Saleor + PostgreSQL + Redis + Celery
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:latest4 environment: 5 - DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/saleor6 - REDIS_URL=redis://redis:6379/07 - CELERY_BROKER_URL=redis://redis:6379/18 - SECRET_KEY=${SECRET_KEY}9 - ALLOWED_HOSTS=localhost,api10 - DEBUG=False11 - DEFAULT_COUNTRY=US12 - DEFAULT_CURRENCY=USD13 ports: 14 - "8000:8000"15 depends_on: 16 - postgres17 - redis18 networks: 19 - saleor-network20 restart: unless-stopped2122 dashboard: 23 image: ghcr.io/saleor/saleor-dashboard:latest24 environment: 25 - API_URI=http://localhost:8000/graphql/26 ports: 27 - "9000:80"28 depends_on: 29 - api30 networks: 31 - saleor-network32 restart: unless-stopped3334 postgres: 35 image: postgres:1536 environment: 37 - POSTGRES_USER=${POSTGRES_USER}38 - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}39 - POSTGRES_DB=saleor40 volumes: 41 - postgres-data:/var/lib/postgresql/data42 networks: 43 - saleor-network44 restart: unless-stopped4546 redis: 47 image: redis:alpine48 volumes: 49 - redis-data:/data50 networks: 51 - saleor-network52 restart: unless-stopped5354 celery: 55 image: ghcr.io/saleor/saleor:latest56 command: celery -A saleor worker --loglevel=info57 environment: 58 - DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/saleor59 - REDIS_URL=redis://redis:6379/060 - CELERY_BROKER_URL=redis://redis:6379/161 - SECRET_KEY=${SECRET_KEY}62 depends_on: 63 - postgres64 - redis65 networks: 66 - saleor-network67 restart: unless-stopped6869 celery-beat: 70 image: ghcr.io/saleor/saleor:latest71 command: celery -A saleor beat --loglevel=info72 environment: 73 - DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/saleor74 - REDIS_URL=redis://redis:6379/075 - CELERY_BROKER_URL=redis://redis:6379/176 - SECRET_KEY=${SECRET_KEY}77 depends_on: 78 - postgres79 - redis80 networks: 81 - saleor-network82 restart: unless-stopped8384volumes: 85 postgres-data: 86 redis-data: 8788networks: 89 saleor-network: 90 driver: bridge.env Template
.env
1# Saleor2POSTGRES_USER=saleor3POSTGRES_PASSWORD=secure_postgres_password4SECRET_KEY=your-very-long-secret-key-here56# Generate secret: python -c "import secrets; print(secrets.token_urlsafe(50))"Usage Notes
- 1API at http://localhost:8000/graphql/
- 2Dashboard at http://localhost:9000
- 3Create superuser: docker exec -it api python manage.py createsuperuser
- 4Celery for async tasks
- 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 file2cat > docker-compose.yml << 'EOF'3services:4 api:5 image: ghcr.io/saleor/saleor:latest6 environment:7 - DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/saleor8 - REDIS_URL=redis://redis:6379/09 - CELERY_BROKER_URL=redis://redis:6379/110 - SECRET_KEY=${SECRET_KEY}11 - ALLOWED_HOSTS=localhost,api12 - DEBUG=False13 - DEFAULT_COUNTRY=US14 - DEFAULT_CURRENCY=USD15 ports:16 - "8000:8000"17 depends_on:18 - postgres19 - redis20 networks:21 - saleor-network22 restart: unless-stopped2324 dashboard:25 image: ghcr.io/saleor/saleor-dashboard:latest26 environment:27 - API_URI=http://localhost:8000/graphql/28 ports:29 - "9000:80"30 depends_on:31 - api32 networks:33 - saleor-network34 restart: unless-stopped3536 postgres:37 image: postgres:1538 environment:39 - POSTGRES_USER=${POSTGRES_USER}40 - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}41 - POSTGRES_DB=saleor42 volumes:43 - postgres-data:/var/lib/postgresql/data44 networks:45 - saleor-network46 restart: unless-stopped4748 redis:49 image: redis:alpine50 volumes:51 - redis-data:/data52 networks:53 - saleor-network54 restart: unless-stopped5556 celery:57 image: ghcr.io/saleor/saleor:latest58 command: celery -A saleor worker --loglevel=info59 environment:60 - DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/saleor61 - REDIS_URL=redis://redis:6379/062 - CELERY_BROKER_URL=redis://redis:6379/163 - SECRET_KEY=${SECRET_KEY}64 depends_on:65 - postgres66 - redis67 networks:68 - saleor-network69 restart: unless-stopped7071 celery-beat:72 image: ghcr.io/saleor/saleor:latest73 command: celery -A saleor beat --loglevel=info74 environment:75 - DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/saleor76 - REDIS_URL=redis://redis:6379/077 - CELERY_BROKER_URL=redis://redis:6379/178 - SECRET_KEY=${SECRET_KEY}79 depends_on:80 - postgres81 - redis82 networks:83 - saleor-network84 restart: unless-stopped8586volumes:87 postgres-data:88 redis-data:8990networks:91 saleor-network:92 driver: bridge93EOF9495# 2. Create the .env file96cat > .env << 'EOF'97# Saleor98POSTGRES_USER=saleor99POSTGRES_PASSWORD=secure_postgres_password100SECRET_KEY=your-very-long-secret-key-here101102# Generate secret: python -c "import secrets; print(secrets.token_urlsafe(50))"103EOF104105# 3. Start the services106docker compose up -d107108# 4. View logs109docker compose logs -fOne-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 | bashTroubleshooting
- 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
Components
saleor-apisaleor-dashboardpostgresqlrediscelery
Tags
#saleor#graphql#ecommerce#celery#async
Category
E-Commerce & BusinessAd Space
Shortcuts: C CopyF FavoriteD Download