# ───────────────────────────────────────────────────────────────────────────── # Next.js CMS — blue/green # # De app draait met `network_mode: host`, dus een replica neemt een host-poort in # plaats van een gedeelde docker-poort. Daarom twee expliciete services in plaats # van `docker compose up --scale cms=2`: die zou op poort 3002 botsen. # # `deploy.sh` start een release op de vrije poort, wacht op /api/health, schrijft # daarna /etc/nginx/snippets/cms_upstream_servers.conf en herlaadt nginx. Pas dan # wordt de oude replica gestopt. De hele release is dus zero-downtime: faalt de # nieuwe replica, dan blijft de oude gewoon draaien. # # De YAML-anchor houdt beide replicas identiek. Wil je ze bewust uit elkaar # halen (bv. één release canary-en), verwijder dan `<<: *cms` en vul de # afwijkende velden opnieuw in. # ───────────────────────────────────────────────────────────────────────────── x-cms: &cms image: epicnext-cms:${CMS_RELEASE:-local} build: context: . dockerfile: Dockerfile args: NEXT_DEPLOYMENT_ID: ${CMS_RELEASE:-unknown} network: host network_mode: host # 15s: Next moet een lopend request nog netjes kunnen afronden voordat SIGKILL # volgt. Met 10s werden streams en imports afgekapt. stop_grace_period: 15s restart: unless-stopped env_file: - .env volumes: - ./public/nitro-assets:/app/public/nitro-assets - ./public/swf:/app/public/swf - ./storage:/app/storage - /var/www/Gamedata:/var/www/Gamedata # ── Resource limits ── # De limieten waren eerder weggehaald ("Next mag onbeperkt presteren"). Op een # gedeelde host is juist dat gevaarlijk: één geheugenlek vult dan de hele # machine en MariaDB + nginx + Traefik gaan er allemaal onderuit. 4 GiB met # 1 GiB swap geeft de V8-heap ruimte om zich te organiseren voor hij hard wordt # afgesneden, maar houdt de schade begrensd. 2 CPU laat drie keer zoveel # achtergrondwerk toe als de cores, zodat de 6 cores van deze host niet # volledig door twee replicas worden opgeëist. mem_limit: 4g memswap_limit: 5g cpus: 2.0 pids_limit: 512 # Leest de poort uit de eigen omgeving, dus dezelfde healthcheck werkt voor # 3002 én 3003 zonder dat deze tweemaal in de compose hoeft te staan. healthcheck: test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:'+(process.env.PORT||'3002')+'/api/health').then(r=>{process.exit(r.ok?0:1)}).catch(()=>process.exit(1))"] interval: 15s timeout: 5s retries: 3 start_period: 40s services: # Blauwe replica: host-poort 3002. cms: <<: *cms container_name: epicnext-cms environment: - HOSTNAME=0.0.0.0 - PORT=3002 # Groene replica: host-poort 3003. Meestal uitgeschakeld; alleen tijdens een # release gestart, totdat nginx hem in de upstream-lijst heeft overgenomen. cms-green: <<: *cms container_name: epicnext-cms-green profiles: ["green"] environment: - HOSTNAME=0.0.0.0 - PORT=3003 # ── Byparr (Cloudflare bypass for clone sources) ── byparr: image: ghcr.io/thephaseless/byparr:latest container_name: byparr network_mode: host restart: unless-stopped environment: - LOG_LEVEL=INFO # Resource limits verwijderd: Headless Chrome heeft bij zware pagina-scrapes # soms tijdelijk meer dan 1 GB RAM nodig. Nu krijgt hij alle ruimte. pids_limit: 256 healthcheck: test: ["CMD", "curl", "http://localhost:8191/health"] interval: 30s timeout: 10s retries: 3 start_period: 30s # De database draait niet meer in Docker. `mariadb-turbo` is verwijderd: de # service is nooit gestart, de volume bestond niet, en de echte MariaDB draait # al als host-proces op 127.0.0.1:3306. De optimalisatie-vlaggen daar stonden # dus al langer niets meer in beheer.