Medusa Commerce
Open-source Shopify alternative.
Overview
Medusa is an open-source, headless commerce platform built with Node.js that provides a modern alternative to Shopify and other traditional e-commerce solutions. Developed as a composable commerce engine, Medusa separates the backend commerce logic from the frontend presentation layer, enabling developers to build custom storefronts using any technology stack while maintaining powerful commerce functionality including inventory management, order processing, customer management, and payment handling. The platform emphasizes developer experience with a plugin-based architecture and comprehensive REST APIs.
This Docker stack combines Medusa with PostgreSQL and Redis to create a production-ready headless commerce backend. PostgreSQL serves as the primary database storing product catalogs, customer data, orders, and inventory information, leveraging its ACID compliance and JSON support for complex e-commerce data structures. Redis handles session management, caching frequently accessed product data, and managing background job queues for order processing and email notifications. This combination provides the data persistence, performance, and reliability needed for modern e-commerce operations.
This configuration is ideal for developers building custom e-commerce solutions, agencies creating unique shopping experiences for clients, and businesses requiring commerce functionality that traditional platforms cannot provide. The headless architecture allows frontend teams to use React, Vue.js, or mobile frameworks while the backend handles all commerce operations, making it perfect for omnichannel retail strategies, B2B marketplaces, and businesses with complex product catalogs or unique checkout flows.
Key Features
- Headless commerce API with complete product, order, and customer management endpoints
- Built-in multi-region and multi-currency support for global e-commerce operations
- Extensible plugin system supporting Stripe, PayPal, and custom payment processors
- Advanced inventory management with variant tracking and stock location handling
- PostgreSQL JSON columns for flexible product attributes and custom metadata storage
- Redis-powered session management and background job processing for order fulfillment
- Discount engine supporting percentage, fixed-amount, and free shipping promotions
- Tax calculation system with region-based tax rates and exemption handling
Common Use Cases
- 1Building custom storefronts with React, Next.js, or Gatsby for unique brand experiences
- 2Creating B2B marketplaces with complex pricing structures and buyer approval workflows
- 3Developing mobile commerce apps with native iOS/Android frontends consuming Medusa APIs
- 4Launching subscription box services with recurring billing and inventory automation
- 5Building omnichannel retail solutions connecting online stores with POS systems
- 6Creating marketplace platforms where multiple vendors can manage their own products
- 7Developing international e-commerce sites requiring multi-currency and tax compliance
Prerequisites
- Docker and Docker Compose installed with at least 2GB available RAM for all services
- Port 9000 available for the Medusa API and admin panel access
- Basic understanding of REST APIs and headless commerce concepts
- Node.js knowledge for customizing Medusa plugins and configurations
- Frontend framework experience (React, Vue.js, or mobile) for building storefronts
- Environment variables configured for JWT_SECRET, COOKIE_SECRET, and database credentials
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 environment: 7 DATABASE_URL: postgres://${DB_USER}:${DB_PASSWORD}@postgres:5432/${DB_NAME}8 REDIS_URL: redis://redis:63799 JWT_SECRET: ${JWT_SECRET}10 COOKIE_SECRET: ${COOKIE_SECRET}11 ports: 12 - "9000:9000"13 depends_on: 14 - postgres15 - redis16 networks: 17 - medusa1819 postgres: 20 image: postgres:16-alpine21 container_name: medusa-postgres22 environment: 23 POSTGRES_DB: ${DB_NAME}24 POSTGRES_USER: ${DB_USER}25 POSTGRES_PASSWORD: ${DB_PASSWORD}26 volumes: 27 - postgres_data:/var/lib/postgresql/data28 networks: 29 - medusa3031 redis: 32 image: redis:alpine33 container_name: medusa-redis34 networks: 35 - medusa3637volumes: 38 postgres_data: 3940networks: 41 medusa: 42 driver: bridge.env Template
.env
1DB_NAME=medusa2DB_USER=medusa3DB_PASSWORD=changeme4JWT_SECRET=your-jwt-secret5COOKIE_SECRET=your-cookie-secretUsage Notes
- 1Docs: https://docs.medusajs.com/
- 2API at http://localhost:9000, admin at http://localhost:9000/app
- 3Seed data: docker exec medusa medusa seed --seed-file=data/seed.json
- 4Headless commerce: use Next.js or Gatsby storefront templates
- 5Built-in support for Stripe, PayPal, manual payments
- 6Extensible plugin system for custom functionality
Individual Services(3 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
environment:
DATABASE_URL: postgres://${DB_USER}:${DB_PASSWORD}@postgres:5432/${DB_NAME}
REDIS_URL: redis://redis:6379
JWT_SECRET: ${JWT_SECRET}
COOKIE_SECRET: ${COOKIE_SECRET}
ports:
- "9000:9000"
depends_on:
- postgres
- redis
networks:
- medusa
postgres
postgres:
image: postgres:16-alpine
container_name: medusa-postgres
environment:
POSTGRES_DB: ${DB_NAME}
POSTGRES_USER: ${DB_USER}
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- medusa
redis
redis:
image: redis:alpine
container_name: medusa-redis
networks:
- medusa
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 environment:9 DATABASE_URL: postgres://${DB_USER}:${DB_PASSWORD}@postgres:5432/${DB_NAME}10 REDIS_URL: redis://redis:637911 JWT_SECRET: ${JWT_SECRET}12 COOKIE_SECRET: ${COOKIE_SECRET}13 ports:14 - "9000:9000"15 depends_on:16 - postgres17 - redis18 networks:19 - medusa2021 postgres:22 image: postgres:16-alpine23 container_name: medusa-postgres24 environment:25 POSTGRES_DB: ${DB_NAME}26 POSTGRES_USER: ${DB_USER}27 POSTGRES_PASSWORD: ${DB_PASSWORD}28 volumes:29 - postgres_data:/var/lib/postgresql/data30 networks:31 - medusa3233 redis:34 image: redis:alpine35 container_name: medusa-redis36 networks:37 - medusa3839volumes:40 postgres_data:4142networks:43 medusa:44 driver: bridge45EOF4647# 2. Create the .env file48cat > .env << 'EOF'49DB_NAME=medusa50DB_USER=medusa51DB_PASSWORD=changeme52JWT_SECRET=your-jwt-secret53COOKIE_SECRET=your-cookie-secret54EOF5556# 3. Start the services57docker compose up -d5859# 4. View logs60docker 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/medusa/run | bashTroubleshooting
- Medusa container exits with 'Cannot connect to database': Ensure PostgreSQL container is fully initialized before Medusa starts, add healthcheck or delay
- Admin panel shows 'Unauthorized' errors: Verify JWT_SECRET and COOKIE_SECRET environment variables are set and consistent across restarts
- Product images not loading: Configure S3 or local file service plugin, check file upload permissions and storage volume mounts
- Redis connection errors during checkout: Confirm Redis container is running and REDIS_URL environment variable matches the service name
- Database migration failures on startup: Clear postgres_data volume and restart with fresh database, or run migrations manually with docker exec
- API requests timing out: Increase container memory allocation, PostgreSQL may need more RAM for complex product queries and indexing
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
Shortcuts: C CopyF FavoriteD Download