services: cms: build: context: . dockerfile: Dockerfile # The host disables Docker iptables (daemon.json: "iptables": false), so # build containers on the bridge network have no outbound NAT/DNS. Build on # the host network instead so pnpm/npm/yarn can reach the registry. network: host args: # Run as the host owner (www-data = UID/GID 33, already present in the # node base image) of /var/www/Gamedata so the container can read + write # the shared gamedata directory. RUN_USER: "www-data" container_name: epicnext-cms # Runs on the host network so existing 127.0.0.1 refs in .env keep working: # MariaDB (3306), DragonflyDB/Redis (6379), emulator RCON (3003) + API (3001), # and the imaging renderer (8082). The container then listens directly on the # host's 3002 (the same port the current host-side CMS uses). # NOTE: stop the host CMS (next-server on 3002) first, otherwise the port is taken. network_mode: host restart: unless-stopped env_file: - .env volumes: # ── Write targets (runtime imports/uploads, persistent on the host) ── # The CMS writes imported furni/figures/pets/effects here (see # src/lib/services/furni-asset-dirs.ts). These must be RW, and owned by # UID/GID 33 (www-data) on the host so the container user can write to them: # sudo chown -R 33:33 ./public/nitro-assets ./public/swf ./storage - ./public/nitro-assets:/app/public/nitro-assets - ./public/swf:/app/public/swf # Runtime uploaded media (persistent on the host). - ./storage:/app/storage # ── Shared gamedata (absolute path the CMS hardcodes & writes to) ── # src/lib/services/furni-asset-dirs.ts: `DEFAULT_GAMEDATA_ROOT = # /var/www/Gamedata`. nginx on the host also serves /gamedata/ from this # same directory, so mount it into the container at the same absolute path. # Must be RW so furniture/badge imports can write mirrors to it. - /var/www/Gamedata:/var/www/Gamedata healthcheck: test: ["CMD", "node", "-e", "fetch('http://localhost:3002/api/health').then(r=>{if(!r.ok)process.exit(1)}).catch(()=>process.exit(1))"] interval: 30s timeout: 10s retries: 3 start_period: 40s mem_limit: 2g # ── Opt-in: Octane-Renderer (Habbo avatar imager) ── # Serves /imaging on port 3030 (the CMS proxies /imaging to it). Renders # avatars into /var/www/Gamedata/habbo-imaging, so it needs RW access. # Disabled by default — uncomment to run the renderer as a container. # imager: # build: # context: /var/www/Octane-Renderer # container_name: epicnext-octane-renderer # ports: # - "3030:3030" # restart: unless-stopped # volumes: # - /var/www/Gamedata:/var/www/Gamedata