docker.recipes

Saleor + PostgreSQL + Redis + Celery

advanced

GraphQL-first e-commerce platform with async task processing.

Overview

Saleor is a modern GraphQL-first e-commerce platform built with Django and designed for headless commerce implementations. Originally developed by Mirumee Software, Saleor provides a robust API-driven foundation for building custom storefronts while handling complex e-commerce operations like inventory management, payment processing, and multi-channel sales. The platform emphasizes developer experience with comprehensive GraphQL APIs and webhook support for real-time integrations. This stack combines Saleor's API backend with PostgreSQL for transactional data storage, Redis for caching and session management, and Celery for asynchronous task processing. PostgreSQL handles complex e-commerce queries involving products, orders, and customer data with ACID compliance, while Redis provides fast access to frequently accessed data like product catalogs and shopping cart sessions. Celery workers process time-intensive operations like image resizing, email notifications, and inventory synchronization without blocking the main application. Enterprise development teams, growing e-commerce businesses, and agencies building custom commerce solutions will find this stack particularly valuable. The GraphQL-first approach enables frontend teams to work independently while the async processing capabilities ensure the platform can handle high-volume operations. The separation of concerns between the API, dashboard, and background workers creates a scalable architecture suitable for both rapid prototyping and production deployments.

Key Features

  • GraphQL-first API with comprehensive schema for products, orders, customers, and inventory management
  • Headless architecture enabling custom frontend implementations across web, mobile, and IoT platforms
  • Multi-tenant capabilities supporting multiple storefronts and sales channels from single backend
  • Celery-powered async processing for image optimization, email campaigns, and third-party integrations
  • Advanced product catalog with variants, attributes, categories, and digital product support
  • Built-in payment gateway integrations with webhook-driven order fulfillment workflows
  • PostgreSQL-backed inventory tracking with real-time stock level management across warehouses
  • Redis-cached product searches and recommendations for sub-second response times

Common Use Cases

  • 1Building custom B2B e-commerce portals with role-based pricing and bulk ordering capabilities
  • 2Creating headless storefronts for fashion brands with complex product variants and seasonal catalogs
  • 3Developing marketplace platforms connecting multiple vendors with centralized order management
  • 4Implementing omnichannel retail systems integrating online stores with POS and inventory systems
  • 5Building subscription commerce platforms with recurring billing and automated fulfillment
  • 6Creating international e-commerce sites with multi-currency support and localized product catalogs
  • 7Developing mobile-first commerce apps using GraphQL APIs for optimal data fetching

Prerequisites

  • Docker Engine 20.10+ and Docker Compose V2 for container orchestration
  • Minimum 4GB RAM (8GB recommended) due to Saleor API, Celery workers, and PostgreSQL memory requirements
  • Available ports 8000 (API), 9000 (Dashboard), and 5432/6379 for database connections
  • Basic understanding of GraphQL schema and query structure for API interactions
  • Familiarity with Django admin interface for initial store configuration and user management
  • SSL certificate and domain configuration for production deployments with payment processing

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 api:
3 image: ghcr.io/saleor/saleor:latest
4 environment:
5 - DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/saleor
6 - REDIS_URL=redis://redis:6379/0
7 - CELERY_BROKER_URL=redis://redis:6379/1
8 - SECRET_KEY=${SECRET_KEY}
9 - ALLOWED_HOSTS=localhost,api
10 - DEBUG=False
11 - DEFAULT_COUNTRY=US
12 - DEFAULT_CURRENCY=USD
13 ports:
14 - "8000:8000"
15 depends_on:
16 - postgres
17 - redis
18 networks:
19 - saleor-network
20 restart: unless-stopped
21
22 dashboard:
23 image: ghcr.io/saleor/saleor-dashboard:latest
24 environment:
25 - API_URI=http://localhost:8000/graphql/
26 ports:
27 - "9000:80"
28 depends_on:
29 - api
30 networks:
31 - saleor-network
32 restart: unless-stopped
33
34 postgres:
35 image: postgres:15
36 environment:
37 - POSTGRES_USER=${POSTGRES_USER}
38 - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
39 - POSTGRES_DB=saleor
40 volumes:
41 - postgres-data:/var/lib/postgresql/data
42 networks:
43 - saleor-network
44 restart: unless-stopped
45
46 redis:
47 image: redis:alpine
48 volumes:
49 - redis-data:/data
50 networks:
51 - saleor-network
52 restart: unless-stopped
53
54 celery:
55 image: ghcr.io/saleor/saleor:latest
56 command: celery -A saleor worker --loglevel=info
57 environment:
58 - DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/saleor
59 - REDIS_URL=redis://redis:6379/0
60 - CELERY_BROKER_URL=redis://redis:6379/1
61 - SECRET_KEY=${SECRET_KEY}
62 depends_on:
63 - postgres
64 - redis
65 networks:
66 - saleor-network
67 restart: unless-stopped
68
69 celery-beat:
70 image: ghcr.io/saleor/saleor:latest
71 command: celery -A saleor beat --loglevel=info
72 environment:
73 - DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/saleor
74 - REDIS_URL=redis://redis:6379/0
75 - CELERY_BROKER_URL=redis://redis:6379/1
76 - SECRET_KEY=${SECRET_KEY}
77 depends_on:
78 - postgres
79 - redis
80 networks:
81 - saleor-network
82 restart: unless-stopped
83
84volumes:
85 postgres-data:
86 redis-data:
87
88networks:
89 saleor-network:
90 driver: bridge

.env Template

.env
1# Saleor
2POSTGRES_USER=saleor
3POSTGRES_PASSWORD=secure_postgres_password
4SECRET_KEY=your-very-long-secret-key-here
5
6# Generate secret: python -c "import secrets; print(secrets.token_urlsafe(50))"

Usage Notes

  1. 1API at http://localhost:8000/graphql/
  2. 2Dashboard at http://localhost:9000
  3. 3Create superuser: docker exec -it api python manage.py createsuperuser
  4. 4Celery for async tasks
  5. 5GraphQL Playground available

Individual Services(6 services)

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

api
api:
  image: ghcr.io/saleor/saleor:latest
  environment:
    - DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/saleor
    - REDIS_URL=redis://redis:6379/0
    - CELERY_BROKER_URL=redis://redis:6379/1
    - SECRET_KEY=${SECRET_KEY}
    - ALLOWED_HOSTS=localhost,api
    - DEBUG=False
    - DEFAULT_COUNTRY=US
    - DEFAULT_CURRENCY=USD
  ports:
    - "8000:8000"
  depends_on:
    - postgres
    - redis
  networks:
    - saleor-network
  restart: unless-stopped
dashboard
dashboard:
  image: ghcr.io/saleor/saleor-dashboard:latest
  environment:
    - API_URI=http://localhost:8000/graphql/
  ports:
    - "9000:80"
  depends_on:
    - api
  networks:
    - saleor-network
  restart: unless-stopped
postgres
postgres:
  image: postgres:15
  environment:
    - POSTGRES_USER=${POSTGRES_USER}
    - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
    - POSTGRES_DB=saleor
  volumes:
    - postgres-data:/var/lib/postgresql/data
  networks:
    - saleor-network
  restart: unless-stopped
redis
redis:
  image: redis:alpine
  volumes:
    - redis-data:/data
  networks:
    - saleor-network
  restart: unless-stopped
celery
celery:
  image: ghcr.io/saleor/saleor:latest
  command: celery -A saleor worker --loglevel=info
  environment:
    - DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/saleor
    - REDIS_URL=redis://redis:6379/0
    - CELERY_BROKER_URL=redis://redis:6379/1
    - SECRET_KEY=${SECRET_KEY}
  depends_on:
    - postgres
    - redis
  networks:
    - saleor-network
  restart: unless-stopped
celery-beat
celery-beat:
  image: ghcr.io/saleor/saleor:latest
  command: celery -A saleor beat --loglevel=info
  environment:
    - DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/saleor
    - REDIS_URL=redis://redis:6379/0
    - CELERY_BROKER_URL=redis://redis:6379/1
    - SECRET_KEY=${SECRET_KEY}
  depends_on:
    - postgres
    - redis
  networks:
    - saleor-network
  restart: unless-stopped

Quick Start

terminal
1# 1. Create the compose file
2cat > docker-compose.yml << 'EOF'
3services:
4 api:
5 image: ghcr.io/saleor/saleor:latest
6 environment:
7 - DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/saleor
8 - REDIS_URL=redis://redis:6379/0
9 - CELERY_BROKER_URL=redis://redis:6379/1
10 - SECRET_KEY=${SECRET_KEY}
11 - ALLOWED_HOSTS=localhost,api
12 - DEBUG=False
13 - DEFAULT_COUNTRY=US
14 - DEFAULT_CURRENCY=USD
15 ports:
16 - "8000:8000"
17 depends_on:
18 - postgres
19 - redis
20 networks:
21 - saleor-network
22 restart: unless-stopped
23
24 dashboard:
25 image: ghcr.io/saleor/saleor-dashboard:latest
26 environment:
27 - API_URI=http://localhost:8000/graphql/
28 ports:
29 - "9000:80"
30 depends_on:
31 - api
32 networks:
33 - saleor-network
34 restart: unless-stopped
35
36 postgres:
37 image: postgres:15
38 environment:
39 - POSTGRES_USER=${POSTGRES_USER}
40 - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
41 - POSTGRES_DB=saleor
42 volumes:
43 - postgres-data:/var/lib/postgresql/data
44 networks:
45 - saleor-network
46 restart: unless-stopped
47
48 redis:
49 image: redis:alpine
50 volumes:
51 - redis-data:/data
52 networks:
53 - saleor-network
54 restart: unless-stopped
55
56 celery:
57 image: ghcr.io/saleor/saleor:latest
58 command: celery -A saleor worker --loglevel=info
59 environment:
60 - DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/saleor
61 - REDIS_URL=redis://redis:6379/0
62 - CELERY_BROKER_URL=redis://redis:6379/1
63 - SECRET_KEY=${SECRET_KEY}
64 depends_on:
65 - postgres
66 - redis
67 networks:
68 - saleor-network
69 restart: unless-stopped
70
71 celery-beat:
72 image: ghcr.io/saleor/saleor:latest
73 command: celery -A saleor beat --loglevel=info
74 environment:
75 - DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/saleor
76 - REDIS_URL=redis://redis:6379/0
77 - CELERY_BROKER_URL=redis://redis:6379/1
78 - SECRET_KEY=${SECRET_KEY}
79 depends_on:
80 - postgres
81 - redis
82 networks:
83 - saleor-network
84 restart: unless-stopped
85
86volumes:
87 postgres-data:
88 redis-data:
89
90networks:
91 saleor-network:
92 driver: bridge
93EOF
94
95# 2. Create the .env file
96cat > .env << 'EOF'
97# Saleor
98POSTGRES_USER=saleor
99POSTGRES_PASSWORD=secure_postgres_password
100SECRET_KEY=your-very-long-secret-key-here
101
102# Generate secret: python -c "import secrets; print(secrets.token_urlsafe(50))"
103EOF
104
105# 3. Start the services
106docker compose up -d
107
108# 4. View logs
109docker 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-complete/run | bash

Troubleshooting

  • Celery workers not processing tasks: Check Redis connectivity and ensure CELERY_BROKER_URL uses different database than main Redis cache
  • GraphQL mutations failing with authentication errors: Verify SECRET_KEY environment variable matches across all Saleor containers
  • Dashboard showing API connection errors: Confirm API_URI points to accessible GraphQL endpoint and API container is running
  • PostgreSQL connection timeouts during high load: Increase PostgreSQL max_connections and configure connection pooling in Saleor settings
  • Product images not displaying: Check Celery worker logs for image processing errors and verify file upload permissions
  • Slow product catalog queries: Enable PostgreSQL query logging and add database indexes for frequently searched product attributes

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