docker.recipes

Saleor Enterprise Commerce

advanced

High-performance GraphQL e-commerce platform with dashboard.

Overview

Saleor is an open-source, headless commerce platform built on Django and GraphQL that emerged as a modern alternative to traditional monolithic e-commerce solutions. Originally developed by Mirumee Software, Saleor provides a complete backend for e-commerce operations while maintaining API-first architecture that separates content management from presentation layers. The platform emphasizes developer experience with its comprehensive GraphQL API, extensive webhook system, and plugin architecture that enables custom business logic without core modifications. This enterprise stack combines Saleor's API server with its React-based dashboard, supported by PostgreSQL for complex relational data management and Redis for high-performance caching and task queuing. The architecture leverages Celery workers for background processing of orders, inventory updates, and email notifications, while the dashboard provides administrators with real-time insights into sales performance, inventory levels, and customer analytics. Organizations choose this stack when they need enterprise-grade e-commerce capabilities with the flexibility to build custom storefronts, integrate with existing systems, and scale across multiple sales channels while maintaining full control over the customer experience and business logic.

Key Features

  • GraphQL API with real-time subscriptions for inventory updates and order status changes
  • Multi-channel sales support with separate pricing, inventory, and tax configurations per channel
  • Advanced product catalog with variant management, digital products, and gift card functionality
  • Comprehensive order management with split fulfillment, refunds, and automated tax calculations
  • Plugin architecture supporting payment gateways, shipping providers, and custom business logic
  • Celery-powered background processing for email campaigns, inventory synchronization, and analytics
  • Redis-backed session management and caching for sub-second API response times
  • PostgreSQL full-text search with product filtering and faceted navigation support

Common Use Cases

  • 1Multi-brand retailers requiring separate storefronts with shared inventory management
  • 2B2B marketplaces with complex pricing tiers and customer-specific catalogs
  • 3Digital product platforms selling software licenses, courses, and subscription services
  • 4International e-commerce with multi-currency support and localized tax calculations
  • 5Headless commerce implementations using React, Vue, or mobile applications as frontends
  • 6Enterprise migrations from Magento or Shopify requiring API-first architecture
  • 7Omnichannel retail operations integrating online stores with POS and marketplace systems

Prerequisites

  • Minimum 4GB RAM for all services (PostgreSQL requires 1GB+, Saleor API needs 2GB+ for production workloads)
  • Docker Engine 20.10+ and Docker Compose 2.0+ with BuildKit support enabled
  • Ports 8000, 9000, and 5432 available on the host system
  • Basic understanding of GraphQL queries and Django admin interface
  • SSL certificates and reverse proxy configuration for production deployment
  • SMTP server credentials for transactional emails and order notifications

For development & testing. Review security settings, change default credentials, and test thoroughly before production use. See Terms

docker-compose.yml

docker-compose.yml
1services:
2 saleor-api:
3 image: ghcr.io/saleor/saleor:latest
4 ports:
5 - "8000:8000"
6 environment:
7 DATABASE_URL: postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}
8 REDIS_URL: redis://redis:6379/0
9 SECRET_KEY: ${SECRET_KEY}
10 ALLOWED_HOSTS: localhost,api
11 DEBUG: "False"
12 DEFAULT_FROM_EMAIL: noreply@example.com
13 depends_on:
14 postgres:
15 condition: service_healthy
16 redis:
17 condition: service_started
18 networks:
19 - saleor-net
20 restart: unless-stopped
21
22 saleor-worker:
23 image: ghcr.io/saleor/saleor:latest
24 command: celery -A saleor --app=saleor.celeryconf:app worker --loglevel=info -B
25 environment:
26 DATABASE_URL: postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}
27 REDIS_URL: redis://redis:6379/0
28 SECRET_KEY: ${SECRET_KEY}
29 depends_on:
30 - saleor-api
31 networks:
32 - saleor-net
33 restart: unless-stopped
34
35 saleor-dashboard:
36 image: ghcr.io/saleor/saleor-dashboard:latest
37 ports:
38 - "9000:80"
39 environment:
40 API_URI: http://localhost:8000/graphql/
41 networks:
42 - saleor-net
43 restart: unless-stopped
44
45 postgres:
46 image: postgres:16-alpine
47 environment:
48 POSTGRES_USER: ${POSTGRES_USER}
49 POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
50 POSTGRES_DB: ${POSTGRES_DB}
51 volumes:
52 - postgres_data:/var/lib/postgresql/data
53 healthcheck:
54 test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
55 interval: 10s
56 timeout: 5s
57 retries: 5
58 networks:
59 - saleor-net
60 restart: unless-stopped
61
62 redis:
63 image: redis:7-alpine
64 volumes:
65 - redis_data:/data
66 networks:
67 - saleor-net
68 restart: unless-stopped
69
70volumes:
71 postgres_data:
72 redis_data:
73
74networks:
75 saleor-net:
76 driver: bridge

.env Template

.env
1# Saleor Configuration
2SECRET_KEY=$(openssl rand -hex 50)
3
4# PostgreSQL
5POSTGRES_USER=saleor
6POSTGRES_PASSWORD=secure_postgres_password
7POSTGRES_DB=saleor

Usage Notes

  1. 1Saleor API at http://localhost:8000/graphql/
  2. 2Dashboard at http://localhost:9000
  3. 3Create superuser: docker compose exec saleor-api python manage.py createsuperuser
  4. 4Populate demo data: docker compose exec saleor-api python manage.py populatedb

Individual Services(5 services)

Copy individual services to mix and match with your existing compose files.

saleor-api
saleor-api:
  image: ghcr.io/saleor/saleor:latest
  ports:
    - "8000:8000"
  environment:
    DATABASE_URL: postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}
    REDIS_URL: redis://redis:6379/0
    SECRET_KEY: ${SECRET_KEY}
    ALLOWED_HOSTS: localhost,api
    DEBUG: "False"
    DEFAULT_FROM_EMAIL: noreply@example.com
  depends_on:
    postgres:
      condition: service_healthy
    redis:
      condition: service_started
  networks:
    - saleor-net
  restart: unless-stopped
saleor-worker
saleor-worker:
  image: ghcr.io/saleor/saleor:latest
  command: celery -A saleor --app=saleor.celeryconf:app worker --loglevel=info -B
  environment:
    DATABASE_URL: postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}
    REDIS_URL: redis://redis:6379/0
    SECRET_KEY: ${SECRET_KEY}
  depends_on:
    - saleor-api
  networks:
    - saleor-net
  restart: unless-stopped
saleor-dashboard
saleor-dashboard:
  image: ghcr.io/saleor/saleor-dashboard:latest
  ports:
    - "9000:80"
  environment:
    API_URI: http://localhost:8000/graphql/
  networks:
    - saleor-net
  restart: unless-stopped
postgres
postgres:
  image: postgres:16-alpine
  environment:
    POSTGRES_USER: ${POSTGRES_USER}
    POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    POSTGRES_DB: ${POSTGRES_DB}
  volumes:
    - postgres_data:/var/lib/postgresql/data
  healthcheck:
    test:
      - CMD-SHELL
      - pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}
    interval: 10s
    timeout: 5s
    retries: 5
  networks:
    - saleor-net
  restart: unless-stopped
redis
redis:
  image: redis:7-alpine
  volumes:
    - redis_data:/data
  networks:
    - saleor-net
  restart: unless-stopped

Quick Start

terminal
1# 1. Create the compose file
2cat > docker-compose.yml << 'EOF'
3services:
4 saleor-api:
5 image: ghcr.io/saleor/saleor:latest
6 ports:
7 - "8000:8000"
8 environment:
9 DATABASE_URL: postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}
10 REDIS_URL: redis://redis:6379/0
11 SECRET_KEY: ${SECRET_KEY}
12 ALLOWED_HOSTS: localhost,api
13 DEBUG: "False"
14 DEFAULT_FROM_EMAIL: noreply@example.com
15 depends_on:
16 postgres:
17 condition: service_healthy
18 redis:
19 condition: service_started
20 networks:
21 - saleor-net
22 restart: unless-stopped
23
24 saleor-worker:
25 image: ghcr.io/saleor/saleor:latest
26 command: celery -A saleor --app=saleor.celeryconf:app worker --loglevel=info -B
27 environment:
28 DATABASE_URL: postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}
29 REDIS_URL: redis://redis:6379/0
30 SECRET_KEY: ${SECRET_KEY}
31 depends_on:
32 - saleor-api
33 networks:
34 - saleor-net
35 restart: unless-stopped
36
37 saleor-dashboard:
38 image: ghcr.io/saleor/saleor-dashboard:latest
39 ports:
40 - "9000:80"
41 environment:
42 API_URI: http://localhost:8000/graphql/
43 networks:
44 - saleor-net
45 restart: unless-stopped
46
47 postgres:
48 image: postgres:16-alpine
49 environment:
50 POSTGRES_USER: ${POSTGRES_USER}
51 POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
52 POSTGRES_DB: ${POSTGRES_DB}
53 volumes:
54 - postgres_data:/var/lib/postgresql/data
55 healthcheck:
56 test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
57 interval: 10s
58 timeout: 5s
59 retries: 5
60 networks:
61 - saleor-net
62 restart: unless-stopped
63
64 redis:
65 image: redis:7-alpine
66 volumes:
67 - redis_data:/data
68 networks:
69 - saleor-net
70 restart: unless-stopped
71
72volumes:
73 postgres_data:
74 redis_data:
75
76networks:
77 saleor-net:
78 driver: bridge
79EOF
80
81# 2. Create the .env file
82cat > .env << 'EOF'
83# Saleor Configuration
84SECRET_KEY=$(openssl rand -hex 50)
85
86# PostgreSQL
87POSTGRES_USER=saleor
88POSTGRES_PASSWORD=secure_postgres_password
89POSTGRES_DB=saleor
90EOF
91
92# 3. Start the services
93docker compose up -d
94
95# 4. View logs
96docker compose logs -f

One-Liner

Run this command to download and set up the recipe in one step:

terminal
1curl -fsSL https://docker.recipes/api/recipes/saleor-commerce/run | bash

Troubleshooting

  • saleor-api exits with 'relation does not exist' errors: Run `docker compose exec saleor-api python manage.py migrate` to apply database migrations
  • Dashboard shows 'Network Error' when connecting to API: Verify API_URI environment variable matches the accessible URL from browser, not internal Docker network
  • Celery workers fail with Redis connection errors: Ensure Redis container is healthy before starting workers, add health checks or init containers
  • GraphQL queries timeout or return incomplete data: Increase PostgreSQL shared_buffers and effective_cache_size in custom postgresql.conf volume mount
  • Image upload failures or missing media files: Add persistent volume mount for `/app/media` directory in saleor-api service
  • Webhook delivery failures to external services: Configure ALLOWED_HOSTS to include webhook recipient domains and verify firewall rules

Community Notes

Loading...
Loading notes...

Download Recipe Kit

Get all files in a ready-to-deploy package

Includes docker-compose.yml, .env template, README, and license

Ad Space