Skip to content

Docker Setup

The system runs 42 Docker containers:

ContainerImagePortPurpose
magic_pim_postgres_devpostgres:16-alpine5432Shared PostgreSQL (all 43 DBs)
mysqlmysql3306Portal docs, workflow data

Standard tenants have 3 containers each (backend, storefront, redis). Two tenants run without a storefront.

Container PatternPort PatternPurpose
magic_{tenant}_redis_dev63XXRedis cache
magic_{tenant}_backend_dev40XX (API), 70XX (PIM)Medusa backend
magic_{tenant}_storefront_dev100XXNext.js storefront

Tenants with full stack (8): development, demo, default, brinxx, bovisales, desluis, jodasign, logohorloge

Tenants without storefront (2):

TenantBackendRedisNote
magic_spranz40916391Storefront port configured but no container running
master_magic40596390Backend + Redis only, no storefront
ContainerPortPurpose
magic_pim_backend_dev4002, 7992PIM backend + API
magic_pim_redis_dev6380PIM cache
ContainerPortPurpose
magic_n8n8090N8N workflow automation (primary)
magic_n8n_28091N8N instance 2
magic_n8n_38092N8N instance 3
ContainerPortPurpose
nextcloud_app8580NextCloud document storage
nextcloud_db3306 (internal)NextCloud dedicated database
onlyoffice_docs8581OnlyOffice document editor
ContainerPortPurpose
rembg-service5050Background removal AI
preflight-service5051Image preflight validation
omada-controller— (no external ports)TP-Link Omada network controller

Each service has its own docker-compose.yml:

/mnt/data/magic_pim/docker-compose.yml
/mnt/data/magic_omniverse/magic_commerce/magic_development/docker-compose.yml
/mnt/data/magic_omniverse/magic_commerce/magic_brinxx/docker-compose.yml
/mnt/data/magic_omniverse/magic_commerce/magic_default/docker-compose.yml
/mnt/data/magic_omniverse/magic_commerce/magic_spranz/docker-compose.yml
/mnt/data/magic_omniverse/magic_commerce/master_magic/docker-compose.yml
... (one per tenant)
/mnt/data/magic_omniverse/magic_n8n/docker-compose.yml
/mnt/data/magic_omniverse/magic_docs/docker-compose.yml
# Stage 1: Dependencies
FROM node:22-alpine AS deps
RUN npm install --legacy-peer-deps
# Stage 2: Build
FROM node:22-alpine AS builder
RUN npm run build # Builds admin panel
# Stage 3: Production
FROM node:22-alpine AS runner
RUN apk add --no-cache git # For dev projects
USER medusa:nodejs
ENTRYPOINT ["sh", "-c", "npx medusa db:migrate && npx medusa start"]

Build argument MEDUSA_BACKEND_URL is set per-tenant.

Each tenant has an isolated Docker bridge network:

magic_{tenant}_network_dev
├── redis
├── backend
└── storefront (not present for spranz, master_magic)

Networks are isolated — no cross-tenant communication at the Docker level. All inter-service communication happens through:

  • Nginx reverse proxy (external traffic)
  • host.docker.internal (database access)
- /mnt/data/pim_data:/mnt/data/pim_data:ro # Product images
- /mnt/data/magic_pim/backend/uploads:/app/uploads:ro # PIM uploads
- /mnt/data/magic_omniverse:/mnt/data/magic_omniverse # Code access
- postgres_data:/var/lib/postgresql/data # DB data on NVMe
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s, timeout: 5s, retries: 5
test: ["CMD", "redis-cli", "ping"]
interval: 10s, timeout: 5s, retries: 5
Terminal window
# Check all containers
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | grep magic_
# View logs
docker logs magic_brinxx_backend_dev --tail=50 -f
# Rebuild a tenant
cd /mnt/data/magic_omniverse/magic_commerce/magic_brinxx
docker compose build backend --no-cache
docker compose up -d backend
# Inspect network
docker network ls | grep magic
docker network inspect magic_brinxx_network_dev
# Check disk usage
df -h /mnt/data
docker system df