Tip
Phase 9 complete — All commerce tenants, PIM, Portal, business services, and tool services are deployed to Coolify alongside N8N, AI Agents, and supporting services. 90+ containers running with HTTPS via Traefik.
Milestone Status Phase 1 — Monorepo + Git setup Done Phase 2 — Coolify + single tenant (Brinxx) Done Phase 2b — Magic Access + Monitoring Done Phase 3 — Feature flag integration Done Phase 4 — N8N, Agents, Redis, Supporting Services Done (2026-03-25) Phase 5a — Internal commerce tenants (dev, demo, default, master) Done (2026-03-25) Phase 5b — Client commerce tenants (bovisales, jodasign, logohorloge, spranz) Done (2026-03-26) Phase 5c — Backend-only tenants (desluis, toolvizion) Done (2026-03-26) Phase 6 — PIM system migration Done (2026-03-26) Phase 7 — Portal + MySQL migration Done (2026-03-26) Phase 8 — Business services (Connector, Contact) Done (2026-03-26) Phase 9 — Tools (Editor, 3D, Logo, Modal, Moodshot, Resize) Done (2026-03-26) Phase 10 — DNS cutover + decommission old server Planned Preview Deployments Done (2026-03-29)
Developer opens PR #42 on midego1/Magic-e-VERSE
GitHub App webhook → Coolify
├── Builds preview container from PR branch
├── Assigns preview domain via Traefik
Backend: pr-42.admin-development.magicomniverse.online
Storefront: pr-42.development.magicomniverse.online
PR closed/merged → Coolify cleans up preview
App Repo Preview URL Pattern development-backend Magic-e-VERSE pr-{id}.admin-development.magicomniverse.onlinedevelopment-storefront Magic-e-VERSE pr-{id}.development.magicomniverse.onlinemaster-backend Magic-e-VERSE pr-{id}.admin-master.magicomniverse.onlinemagic-monitor Magic-Monitor pr-{id}.monitor.magicomniverse.onlineportal Magic-Portal pr-{id}.portal.magicomniverse.onlinepim-backend Magic-PIM pr-{id}.pim.magicomniverse.onlineprice-import Magic-Price-Import pr-{id}.price-import.magicomniverse.online
All preview URLs resolve automatically via the existing *.magicomniverse.online wildcard DNS record pointing to 159.195.68.41.
The Coolify webhook endpoint is routed via /data/coolify/proxy/dynamic/coolify-webhook.yaml. This file also makes the Coolify dashboard accessible at https://coolify.magicomniverse.online.
Detail Value App name magic-everse-coolifyApp ID 3171127Installation ID 118592927Events push, pull_requestPermissions contents:read, pull_requests:write, metadata:read, administration:readManage repos https://github.com/settings/installations/118592927
Detail Value Provider Contabo VPS IP 159.195.68.41OS Debian 13 (Trixie) CPU 12 cores RAM 32 GB Disk 1 TB (965 GB free) SSH root@159.195.68.41
Detail Value URL https://coolify.magicomniverse.onlineEmail admin@magicomniverse.onlinePassword See Vaultwarden API Token See Vaultwarden
Domain Points to *.magicomniverse.online159.195.68.41
Resource UUID Backend App les7duuk6opipbl38vvq35ilStorefront App jkm70m01bv0uf9xqwa6leu8jPostgreSQL ypigwo3w0yteib6qscn4gs3tRedis vh8unk1tbyqxoxncrvjt1ucm
Detail Value Host ypigwo3w0yteib6qscn4gs3t (internal Docker)Port 5432Database magic_b2b_brinxxCredentials See Vaultwarden
Detail Value Host vh8unk1tbyqxoxncrvjt1ucm (internal Docker)Port 6379Credentials See Vaultwarden
Product images and uploads are stored on the host filesystem and mounted into the backend container:
Host Path Container Path Size /data/magic-commerce/brinxx/static-products/app/static/products~28 GB /data/magic-commerce/brinxx/uploads/app/uploads~3.8 GB
Image breakdown by supplier:
Supplier Files Size xdconnect ~93K 11 GB midocean ~53K 9.1 GB pfconcept ~155K 2.6 GB spranz ~4.3K 1.4 GB langenberg ~1.6K 475 MB moxz 54 147 MB
Note
After a Coolify redeploy, the volume mounts in the docker-compose file may be overwritten. The volumes need to be re-added to /data/coolify/applications/les7duuk6opipbl38vvq35il/docker-compose.yaml after each deploy until persistent storage is configured through the Coolify UI. Add the following under restart: unless-stopped:
- /data/magic-commerce/brinxx/static-products:/app/static/products
- /data/magic-commerce/brinxx/uploads:/app/uploads
Then run: docker compose -f /data/coolify/applications/les7duuk6opipbl38vvq35il/docker-compose.yaml up -d --force-recreate
Detail Value Repo github.com/midego1/magic-commerceBranch mainAuth GitHub PAT embedded in Coolify git URL Structure Monorepo: backend/ (Medusa v2) + storefront/ (Next.js 15) + tenants/ (config)
┌─────────────────────────────────────────────────┐
│ Coolify (159.195.68.41) │
│ ┌──────────┐ ┌──────────────────────────┐ │
│ │ Traefik │───▶│ brinxx-backend (:9000) │ │
│ │ :80/:443 │ │ Medusa v2 + Admin Panel │ │
│ │ │ │ + Static Image Serving │ │
│ │ │ └──────────┬───────────────┘ │
│ │ │ ┌──────────▼───────────────┐ │
│ │ │───▶│ brinxx-storefront (:3000)│ │
│ │ │ │ Next.js 15 (standalone) │ │
│ │ │ └──────────────────────────┘ │
│ ┌──────────────┐ ┌─────────────────────┐ │
│ │ PostgreSQL 16│ │ Redis 7 │ │
│ └──────────────┘ └─────────────────────┘ │
│ /data/magic-commerce/brinxx/ │
│ ├── static-products/ (28 GB, bind mount) │
│ └── uploads/ (3.8 GB, bind mount) │
└─────────────────────────────────────────────────┘
All services are protected by Magic Access — a custom Express.js authentication proxy running as a Docker container on the Coolify network. It uses Traefik’s forwardAuth middleware to validate every request before it reaches the backend or storefront.
Detail Value Container magic-accessPort 3334Login URL https://access.magicomniverse.onlineDatabase PostgreSQL magic_access (on same Coolify PostgreSQL instance) Auth methods Email/password + WhatsApp 2FA
How it works:
Browser request → Traefik → forwardAuth → magic-access:3334/api/validate
┌────────────────┴────────────────┐
IP whitelisted? Has valid session?
or device token? (cookie check)
401 → Blocked page 401 → Redirect to login
Features:
IP whitelisting (26 IPs migrated from old server)
Device tokens (30-day cookies, 14 tokens migrated)
WhatsApp 2FA via MessageBird API
Password policy: 28-day expiry, complexity requirements, history check
CAPTCHA protection on login
Session management with PostgreSQL-backed user table (19 users)
Branded “Access Denied” page showing visitor’s IP address
Independence from old server
Magic Access was originally dependent on MySQL on the old server (83.86.98.93). All database queries have been rewritten to use PostgreSQL on the new server. There is zero dependency on the old server.
Traefik integration:
The magic-access container defines a magic-forward-auth middleware via Docker labels. Backend and storefront containers reference this middleware in their custom_labels (stored in Coolify’s DB):
traefik.http.middlewares.magic-forward-auth.forwardauth.address=http://magic-access:3334/api/validate
traefik.http.middlewares.magic-forward-auth.forwardauth.authRequestHeaders=X-Real-IP,X-Forwarded-For,Cookie,Host
Detail Value URL https://monitor.magicomniverse.onlineAuth Traefik basicAuth (Netdata has no built-in login) Credentials See Vaultwarden Container netdata (on coolify network)
What it monitors:
All Docker containers (CPU, memory, network I/O, disk I/O per container)
Host system (CPU, RAM, disk, network interfaces)
PostgreSQL (connections, queries, locks, replication)
Redis (commands, memory, keys, connections)
Traefik config: Netdata routing is handled via a file provider config at /traefik/dynamic/netdata.yaml inside the coolify-proxy container — NOT via Docker labels. This keeps Netdata on basicAuth instead of the Magic Access forwardAuth.
Note
Container names in Netdata show as Docker IDs (e.g., les7duuk6opipbl38vvq35il-022554890518). Consider renaming containers to friendly names (e.g., brinxx-backend) for easier identification in the monitoring dashboard.
Step Old Server (KVM 4, 4 cores) New Server (12 cores) Backend npm ci + build ~25 min ~12 min Storefront build ~10 min ~2 min
All Coolify API calls use the token in the Authorization header:
curl -H ' Authorization: Bearer <API_TOKEN> ' \
http://localhost:8000/api/v1/servers
Action Method Endpoint List servers GET /api/v1/serversList apps GET /api/v1/applicationsDeploy app GET /api/v1/deploy?uuid={app_uuid}App env vars GET /api/v1/applications/{uuid}/envsAdd env var POST /api/v1/applications/{uuid}/envsDeployment status GET /api/v1/deployments/{deploy_uuid}
curl -H ' Authorization: Bearer <API_TOKEN> ' \
' http://localhost:8000/api/v1/deploy?uuid=les7duuk6opipbl38vvq35il '
curl -H ' Authorization: Bearer <API_TOKEN> ' \
' http://localhost:8000/api/v1/deploy?uuid=jkm70m01bv0uf9xqwa6leu8j '
Issue Workaround Fix Volume mounts lost on Coolify redeploy Re-add volumes to docker-compose.yaml manually Configure persistent storage via Coolify UI Some DB image URLs reference brinxx.magiceverse.online Images still load via /static/products/ relative paths Update absolute URLs in image table to use new domain designer.spranz.de CORS errorsNon-critical — logo designer feature Add magicomniverse.online to Spranz CORS allowlist
All services from the old server have been migrated to Coolify as Docker Image apps, each with HTTPS via Traefik and auto-SSL.
All use n8nio/n8n:latest image, persistent data via bind mounts to /data/apps/n8n/.
All agents use the @magic-agent/brinxx package with per-tenant config. Each connects to its own PostgreSQL database (magic_agent_{name}) on the shared magic-postgres container.
Docker images: Built locally using parameterized Dockerfile.fixed with AGENT_NAME build arg, pushed to local registry at localhost:5000/magic-agent-{name}:latest.
Instance Coolify UUID agent-redis ibv29cyx5rg7rw14vjq75gtgspranz-redis ghuodyk9d2gxjp7wlog8rhi0
All agent databases, escalation, and flowbuilder share the magic-postgres container:
Detail Value Container magic-postgresCredentials See Vaultwarden Network coolify (all apps on same network)
A local Docker registry runs at localhost:5000 on the new server. Agent images are tagged as localhost:5000/magic-agent-{name}:latest and pulled by Coolify from there (avoids Docker Hub pulls for custom images).
Project UUID Contents N8N t10zqw5ff2czpvz0xl7akg6r4 N8N instances Agents ly8emm9hcayrv31odbrxy9tr10 agents + 2 Redis + 4 supporting services
All commerce tenants deployed to Coolify. Each tenant has a Medusa v2 backend, optional Next.js storefront, and dedicated Redis instance. All connect to the shared magic-postgres PostgreSQL container.
Project UUID Contents Commerce Tenants ra5w4beuzwbsj39bxjtlp33aPhase 5a internal tenants + toolvizion bovisales u60xain9eru7mq9oepq40jwfbovisales backend + storefront + redis jodasign p124fkya1oj1j16gobrzom7zjodasign backend + storefront + redis logohorloge o46mvqff13ukvhziaotcm1zrlogohorloge backend + storefront + redis spranz mu2gbfvdliyucernkoa34z4ispranz backend + storefront + redis desluis kekoexxuyou8j9w3n9bfywk6desluis backend + redis
All commerce backends are built from the midego1/Magic-e-VERSE monorepo (main branch) with:
Build pack: dockerfile
Base directory: /backend (backends) or /storefront (storefronts)
Ports: 9000 (backends), 9002 (storefronts)
GitHub App UUID: vt1agfhku2dybkk97qpi4yng
Medusa migration prompt
Medusa v2’s db:migrate command shows an interactive “Select tables to DELETE” prompt when stale link references exist in the link_module_migrations table. This hangs Docker containers. Root cause fix: delete stale rows from link_module_migrations (e.g., DELETE FROM link_module_migrations WHERE table_name = 'user_rbac_role'). The start_command field in Coolify does NOT override the Dockerfile CMD for dockerfile build pack apps.
Magic PIM migrated to Coolify as a standalone app with its own GitHub repo, separate from the commerce monorepo.
Detail Value GitHub Repo midego1/Magic-PIM (private)Coolify App UUID a5j3s2r6zqjter8ps2mpqf12Coolify Project pim (vinrsqy0eqf0k38aepzr05vq)URL https://pim.magicomniverse.online Admin Panel https://pim.magicomniverse.online/app Build Pack dockerfile (multi-stage, from /backend/Dockerfile)Port 4002Database magic_pim (189 tables, on shared magic-postgres)Redis Shared instance (vh8unk1tbyqxoxncrvjt1ucm, db index 1)
Separate repo: midego1/Magic-PIM instead of midego1/Magic-e-VERSE
Port: 4002 (commerce tenants use 9000)
No storefront: PIM is backend/admin only
Supplier connectors: Built-in connectors for 8 suppliers (Spranz, XD Connect, PF Concept, Midocean, Toppoint, NewWave, Moxz, Langenberg)
PIM API port: 7992 for internal sync endpoints
First build takes ~20 minutes (no Docker layer cache). Subsequent builds are faster.
Product images (225 GB) are currently on the old server at /mnt/data/pim_data/. These will be migrated to Cloudflare R2 or S3 in a future phase. For now, the PIM serves images from its local filesystem.
Magic Portal migrated to Coolify. MySQL was already present on the new server with all databases imported.
Detail Value GitHub Repo midego1/Magic-Portal (private)Coolify App UUID asobzrb38ogwdasunt4hm2mkCoolify Project portal (guiv6q9ktejyggk9rsbgldmc)URL https://portal.magicomniverse.online Build Pack dockerfile (Node.js + pre-built React frontend)Port 4096Database MySQL magic_doc (60 tables, on mysql container)
The portal is a React 19 + TypeScript frontend (built with Vite) served by an Express.js backend (server.cjs). The frontend is pre-built and included in the Docker image — no build step needed at deploy time.
Stack: React 19 / Vite / Express 4 / MySQL 8 / Nodemailer / WhatsApp 2FA
Detail Value Container mysqlInternal hostname mysql (on coolify network)Databases magic_doc (portal), uren, dartv2dev, magic_promotionalz, portal_dbCredentials See Vaultwarden
Business services migrated to Coolify as standalone apps with dedicated GitHub repos.
Project UUID business-services gwd6yqz3oat1ka9l9l9l9412
All tool services deployed to Coolify with dedicated GitHub repos, Dockerfiles, auto-deploy on push, and preview deployments on PRs.
Database Used By Tables magic_logoMagic Logo (Prisma ORM) 20 moodshot_serviceMagic Moodshot 1
Project UUID tools a11xohldkir9aodr2ek0l6as
NODE_ENV in builder stages
All multi-stage Dockerfiles set ENV NODE_ENV=development in builder stages to ensure devDependencies (TypeScript, Vite, etc.) are installed during npm install. Coolify injects env vars as Docker build ARGs, and NODE_ENV=production would skip devDeps needed for compilation.
Magic Terminal (midego1/Magic-Terminal, sshwifty-based) was not deployed because the repo was not added to the GitHub App installation. It can be deployed later when needed.
Switch production DNS (magiceverse.online) to new server
Verify all services with production domains
Decommission old server (83.86.98.93)
Object storage — Move product images to Cloudflare R2 or S3 instead of local disk
CI/CD pipeline — GitHub Actions for automated testing before deploy
Alerting — Configure Netdata alerts for disk space, memory, and container health
Database backups — Automated daily pg_dump to off-site storage
Meilisearch — Add search service for product catalog
Watch paths refinement — Add more granular watch paths for shared config files
Detail Value IP 185.77.96.209SSH midego@185.77.96.209Credentials See Vaultwarden Domain *.magic.midego.net
Detail Value Hostname magic-serverIP (public) 83.86.98.93IP (local) 192.168.1.26Role Current production — all tenants run here Data path /mnt/data/magic_omniverse/magic_commerce/PIM images /mnt/data/pim_data/