Complete E-Commerce Stack
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:latest4 container_name: medusa5 restart: unless-stopped6 ports: 7 - "${MEDUSA_PORT:-9000}:9000"8 environment: 9 - DATABASE_URL=postgres://${DB_USER}:${DB_PASSWORD}@medusa-db:5432/medusa10 - REDIS_URL=redis://medusa-redis:637911 - JWT_SECRET=${JWT_SECRET}12 - COOKIE_SECRET=${COOKIE_SECRET}13 - STORE_CORS=http://localhost:800014 - ADMIN_CORS=http://localhost:700115 depends_on: 16 - medusa-db17 - medusa-redis1819 medusa-admin: 20 image: medusajs/admin:latest21 container_name: medusa-admin22 restart: unless-stopped23 ports: 24 - "${ADMIN_PORT:-7001}:7001"25 environment: 26 - MEDUSA_BACKEND_URL=http://medusa:900027 depends_on: 28 - medusa2930 medusa-db: 31 image: postgres:15-alpine32 container_name: medusa-db33 restart: unless-stopped34 environment: 35 - POSTGRES_USER=${DB_USER}36 - POSTGRES_PASSWORD=${DB_PASSWORD}37 - POSTGRES_DB=medusa38 volumes: 39 - medusa_db_data:/var/lib/postgresql/data4041 medusa-redis: 42 image: redis:7-alpine43 container_name: medusa-redis44 restart: unless-stopped45 volumes: 46 - medusa_redis_data:/data4748 minio: 49 image: minio/minio:latest50 container_name: medusa-minio51 restart: unless-stopped52 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:/data60 command: server /data --console-address ":9001"6162volumes: 63 medusa_db_data: 64 medusa_redis_data: 65 minio_data: .env Template
.env
1# E-Commerce Stack2MEDUSA_PORT=90003ADMIN_PORT=70014MINIO_PORT=90015MINIO_CONSOLE=900267# Database8DB_USER=medusa9DB_PASSWORD=medusa_password1011# Secrets (generate with: openssl rand -hex 32)12JWT_SECRET=your-jwt-secret13COOKIE_SECRET=your-cookie-secret1415# MinIO16MINIO_USER=minioadmin17MINIO_PASSWORD=minioadminUsage Notes
- 1Medusa API at http://localhost:9000
- 2Admin dashboard at http://localhost:7001
- 3MinIO for product images at http://localhost:9002
- 4Create admin: docker exec medusa medusa user -e admin@test.com -p password
- 5Seed data: docker exec medusa medusa seed
- 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 file2cat > docker-compose.yml << 'EOF'3services:4 medusa:5 image: medusajs/medusa:latest6 container_name: medusa7 restart: unless-stopped8 ports:9 - "${MEDUSA_PORT:-9000}:9000"10 environment:11 - DATABASE_URL=postgres://${DB_USER}:${DB_PASSWORD}@medusa-db:5432/medusa12 - REDIS_URL=redis://medusa-redis:637913 - JWT_SECRET=${JWT_SECRET}14 - COOKIE_SECRET=${COOKIE_SECRET}15 - STORE_CORS=http://localhost:800016 - ADMIN_CORS=http://localhost:700117 depends_on:18 - medusa-db19 - medusa-redis2021 medusa-admin:22 image: medusajs/admin:latest23 container_name: medusa-admin24 restart: unless-stopped25 ports:26 - "${ADMIN_PORT:-7001}:7001"27 environment:28 - MEDUSA_BACKEND_URL=http://medusa:900029 depends_on:30 - medusa3132 medusa-db:33 image: postgres:15-alpine34 container_name: medusa-db35 restart: unless-stopped36 environment:37 - POSTGRES_USER=${DB_USER}38 - POSTGRES_PASSWORD=${DB_PASSWORD}39 - POSTGRES_DB=medusa40 volumes:41 - medusa_db_data:/var/lib/postgresql/data4243 medusa-redis:44 image: redis:7-alpine45 container_name: medusa-redis46 restart: unless-stopped47 volumes:48 - medusa_redis_data:/data4950 minio:51 image: minio/minio:latest52 container_name: medusa-minio53 restart: unless-stopped54 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:/data62 command: server /data --console-address ":9001"6364volumes:65 medusa_db_data:66 medusa_redis_data:67 minio_data:68EOF6970# 2. Create the .env file71cat > .env << 'EOF'72# E-Commerce Stack73MEDUSA_PORT=900074ADMIN_PORT=700175MINIO_PORT=900176MINIO_CONSOLE=90027778# Database79DB_USER=medusa80DB_PASSWORD=medusa_password8182# Secrets (generate with: openssl rand -hex 32)83JWT_SECRET=your-jwt-secret84COOKIE_SECRET=your-cookie-secret8586# MinIO87MINIO_USER=minioadmin88MINIO_PASSWORD=minioadmin89EOF9091# 3. Start the services92docker compose up -d9394# 4. View logs95docker 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/complete-ecommerce-stack/run | bashTroubleshooting
- 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
Components
medusapostgresredisminiomedusa-admin
Tags
#medusa#ecommerce#shop#postgres#redis#headless
Category
E-Commerce & BusinessAd Space
Shortcuts: C CopyF FavoriteD Download