docker.recipes

Complete E-Commerce Stack

intermediate

Medusa e-commerce backend with PostgreSQL, Redis, MinIO storage, and admin dashboard

Overview

Medusa is a modern, open-source headless commerce engine built on Node.js that provides a flexible foundation for e-commerce applications. Unlike traditional monolithic platforms like Magento or Shopify, Medusa separates the backend commerce logic from the frontend presentation layer, allowing developers to build custom storefronts using any technology stack while leveraging powerful commerce APIs for cart management, order processing, inventory tracking, and customer management. This architecture enables faster performance, better developer experience, and unlimited customization possibilities. This complete e-commerce stack combines Medusa's headless backend with essential supporting services: PostgreSQL handles transactional data and complex product catalogs with full ACID compliance, Redis provides high-speed session storage and caching for cart persistence and real-time inventory updates, MinIO offers S3-compatible object storage for product images and digital assets, and the Medusa admin dashboard delivers an intuitive interface for managing products, orders, and customers. Together, these components create a production-ready commerce platform that can handle everything from startup marketplaces to enterprise retail operations. This stack is ideal for developers building custom e-commerce experiences, agencies creating white-label solutions for clients, and businesses requiring flexible commerce functionality without platform lock-in. The headless architecture allows integration with modern frontend frameworks like Next.js, React, or Vue.js, while the robust backend handles complex commerce workflows including multi-region sales, subscription billing, and marketplace functionality. Unlike SaaS platforms, this self-hosted approach provides complete data ownership, unlimited customization, and no transaction fees.

Key Features

  • Headless commerce architecture with RESTful APIs for cart, checkout, product catalog, and order management
  • PostgreSQL-powered product catalog with support for variants, collections, complex pricing rules, and inventory tracking
  • Redis-based session management for persistent shopping carts and real-time inventory caching
  • MinIO S3-compatible storage for product images, digital downloads, and media assets with built-in CDN capabilities
  • Multi-region and multi-currency support with tax calculation and shipping rate management
  • Extensible plugin system for payment processors, fulfillment providers, and third-party integrations
  • Advanced discount engine supporting percentage, fixed amount, and buy-X-get-Y promotions
  • Customer segmentation and analytics with order history and behavioral tracking

Common Use Cases

  • 1Building custom storefronts with modern frameworks while maintaining robust commerce backend functionality
  • 2Creating marketplace platforms with multiple vendors and complex product catalogs
  • 3Developing subscription-based e-commerce sites with recurring billing and customer management
  • 4Launching headless commerce solutions for mobile apps with API-driven shopping experiences
  • 5Building white-label e-commerce platforms for agencies serving multiple retail clients
  • 6Migrating from monolithic platforms like Magento to gain development flexibility and performance
  • 7Creating omnichannel retail experiences connecting online stores with POS and inventory systems

Prerequisites

  • Docker and Docker Compose installed with minimum 4GB RAM available for all services
  • Ports 9000, 7001, 9001, and 9002 available for Medusa API, admin dashboard, and MinIO interfaces
  • Basic understanding of REST APIs and headless commerce concepts for integration development
  • Environment variables configured for database credentials, JWT secrets, and MinIO access keys
  • Node.js knowledge helpful for Medusa plugin development and custom business logic
  • PostgreSQL familiarity recommended for database optimization and backup strategies

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 medusa:
3 image: medusajs/medusa:latest
4 container_name: medusa
5 restart: unless-stopped
6 ports:
7 - "${MEDUSA_PORT:-9000}:9000"
8 environment:
9 - DATABASE_URL=postgres://${DB_USER}:${DB_PASSWORD}@medusa-db:5432/medusa
10 - REDIS_URL=redis://medusa-redis:6379
11 - JWT_SECRET=${JWT_SECRET}
12 - COOKIE_SECRET=${COOKIE_SECRET}
13 - STORE_CORS=http://localhost:8000
14 - ADMIN_CORS=http://localhost:7001
15 depends_on:
16 - medusa-db
17 - medusa-redis
18
19 medusa-admin:
20 image: medusajs/admin:latest
21 container_name: medusa-admin
22 restart: unless-stopped
23 ports:
24 - "${ADMIN_PORT:-7001}:7001"
25 environment:
26 - MEDUSA_BACKEND_URL=http://medusa:9000
27 depends_on:
28 - medusa
29
30 medusa-db:
31 image: postgres:15-alpine
32 container_name: medusa-db
33 restart: unless-stopped
34 environment:
35 - POSTGRES_USER=${DB_USER}
36 - POSTGRES_PASSWORD=${DB_PASSWORD}
37 - POSTGRES_DB=medusa
38 volumes:
39 - medusa_db_data:/var/lib/postgresql/data
40
41 medusa-redis:
42 image: redis:7-alpine
43 container_name: medusa-redis
44 restart: unless-stopped
45 volumes:
46 - medusa_redis_data:/data
47
48 minio:
49 image: minio/minio:latest
50 container_name: medusa-minio
51 restart: unless-stopped
52 ports:
53 - "${MINIO_PORT:-9001}:9000"
54 - "${MINIO_CONSOLE:-9002}:9001"
55 environment:
56 - MINIO_ROOT_USER=${MINIO_USER}
57 - MINIO_ROOT_PASSWORD=${MINIO_PASSWORD}
58 volumes:
59 - minio_data:/data
60 command: server /data --console-address ":9001"
61
62volumes:
63 medusa_db_data:
64 medusa_redis_data:
65 minio_data:

.env Template

.env
1# E-Commerce Stack
2MEDUSA_PORT=9000
3ADMIN_PORT=7001
4MINIO_PORT=9001
5MINIO_CONSOLE=9002
6
7# Database
8DB_USER=medusa
9DB_PASSWORD=medusa_password
10
11# Secrets (generate with: openssl rand -hex 32)
12JWT_SECRET=your-jwt-secret
13COOKIE_SECRET=your-cookie-secret
14
15# MinIO
16MINIO_USER=minioadmin
17MINIO_PASSWORD=minioadmin

Usage Notes

  1. 1Medusa API at http://localhost:9000
  2. 2Admin dashboard at http://localhost:7001
  3. 3MinIO for product images at http://localhost:9002
  4. 4Create admin: docker exec medusa medusa user -e admin@test.com -p password
  5. 5Seed data: docker exec medusa medusa seed
  6. 6Headless - connect any frontend (Next.js, Gatsby)

Individual Services(5 services)

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

medusa
medusa:
  image: medusajs/medusa:latest
  container_name: medusa
  restart: unless-stopped
  ports:
    - ${MEDUSA_PORT:-9000}:9000
  environment:
    - DATABASE_URL=postgres://${DB_USER}:${DB_PASSWORD}@medusa-db:5432/medusa
    - REDIS_URL=redis://medusa-redis:6379
    - JWT_SECRET=${JWT_SECRET}
    - COOKIE_SECRET=${COOKIE_SECRET}
    - STORE_CORS=http://localhost:8000
    - ADMIN_CORS=http://localhost:7001
  depends_on:
    - medusa-db
    - medusa-redis
medusa-admin
medusa-admin:
  image: medusajs/admin:latest
  container_name: medusa-admin
  restart: unless-stopped
  ports:
    - ${ADMIN_PORT:-7001}:7001
  environment:
    - MEDUSA_BACKEND_URL=http://medusa:9000
  depends_on:
    - medusa
medusa-db
medusa-db:
  image: postgres:15-alpine
  container_name: medusa-db
  restart: unless-stopped
  environment:
    - POSTGRES_USER=${DB_USER}
    - POSTGRES_PASSWORD=${DB_PASSWORD}
    - POSTGRES_DB=medusa
  volumes:
    - medusa_db_data:/var/lib/postgresql/data
medusa-redis
medusa-redis:
  image: redis:7-alpine
  container_name: medusa-redis
  restart: unless-stopped
  volumes:
    - medusa_redis_data:/data
minio
minio:
  image: minio/minio:latest
  container_name: medusa-minio
  restart: unless-stopped
  ports:
    - ${MINIO_PORT:-9001}:9000
    - ${MINIO_CONSOLE:-9002}:9001
  environment:
    - MINIO_ROOT_USER=${MINIO_USER}
    - MINIO_ROOT_PASSWORD=${MINIO_PASSWORD}
  volumes:
    - minio_data:/data
  command: server /data --console-address ":9001"

Quick Start

terminal
1# 1. Create the compose file
2cat > docker-compose.yml << 'EOF'
3services:
4 medusa:
5 image: medusajs/medusa:latest
6 container_name: medusa
7 restart: unless-stopped
8 ports:
9 - "${MEDUSA_PORT:-9000}:9000"
10 environment:
11 - DATABASE_URL=postgres://${DB_USER}:${DB_PASSWORD}@medusa-db:5432/medusa
12 - REDIS_URL=redis://medusa-redis:6379
13 - JWT_SECRET=${JWT_SECRET}
14 - COOKIE_SECRET=${COOKIE_SECRET}
15 - STORE_CORS=http://localhost:8000
16 - ADMIN_CORS=http://localhost:7001
17 depends_on:
18 - medusa-db
19 - medusa-redis
20
21 medusa-admin:
22 image: medusajs/admin:latest
23 container_name: medusa-admin
24 restart: unless-stopped
25 ports:
26 - "${ADMIN_PORT:-7001}:7001"
27 environment:
28 - MEDUSA_BACKEND_URL=http://medusa:9000
29 depends_on:
30 - medusa
31
32 medusa-db:
33 image: postgres:15-alpine
34 container_name: medusa-db
35 restart: unless-stopped
36 environment:
37 - POSTGRES_USER=${DB_USER}
38 - POSTGRES_PASSWORD=${DB_PASSWORD}
39 - POSTGRES_DB=medusa
40 volumes:
41 - medusa_db_data:/var/lib/postgresql/data
42
43 medusa-redis:
44 image: redis:7-alpine
45 container_name: medusa-redis
46 restart: unless-stopped
47 volumes:
48 - medusa_redis_data:/data
49
50 minio:
51 image: minio/minio:latest
52 container_name: medusa-minio
53 restart: unless-stopped
54 ports:
55 - "${MINIO_PORT:-9001}:9000"
56 - "${MINIO_CONSOLE:-9002}:9001"
57 environment:
58 - MINIO_ROOT_USER=${MINIO_USER}
59 - MINIO_ROOT_PASSWORD=${MINIO_PASSWORD}
60 volumes:
61 - minio_data:/data
62 command: server /data --console-address ":9001"
63
64volumes:
65 medusa_db_data:
66 medusa_redis_data:
67 minio_data:
68EOF
69
70# 2. Create the .env file
71cat > .env << 'EOF'
72# E-Commerce Stack
73MEDUSA_PORT=9000
74ADMIN_PORT=7001
75MINIO_PORT=9001
76MINIO_CONSOLE=9002
77
78# Database
79DB_USER=medusa
80DB_PASSWORD=medusa_password
81
82# Secrets (generate with: openssl rand -hex 32)
83JWT_SECRET=your-jwt-secret
84COOKIE_SECRET=your-cookie-secret
85
86# MinIO
87MINIO_USER=minioadmin
88MINIO_PASSWORD=minioadmin
89EOF
90
91# 3. Start the services
92docker compose up -d
93
94# 4. View logs
95docker 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/complete-ecommerce-stack/run | bash

Troubleshooting

  • Medusa API returns 500 errors on startup: Check DATABASE_URL connection string and ensure PostgreSQL container is fully initialized before Medusa starts
  • Admin dashboard shows 'Cannot connect to Medusa backend': Verify MEDUSA_BACKEND_URL environment variable points to http://medusa:9000 and containers are on same network
  • Redis connection timeouts during checkout: Increase Redis memory limits and check REDIS_URL format matches redis://medusa-redis:6379 exactly
  • MinIO image uploads fail with access denied: Create bucket through MinIO console and configure proper IAM policies for Medusa file plugin
  • JWT authentication errors: Ensure JWT_SECRET and COOKIE_SECRET environment variables are set and consistent between container restarts
  • Database migration failures: Run 'docker exec medusa medusa migrations run' manually and check PostgreSQL logs for constraint violations

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