name: adventureland # ensure both containers use same version of mongo x-mongo_image: &mongo_image mongo:8.0 # Shared settings for the two game containers. Both use the same image, so # `docker compose build` builds it once. x-app: &app image: git.ao-it.net/gaming/adventureland:latest build: context: . args: NODE_IMAGE: node:22-bookworm-slim AL_REF: main COMMON_REF: main CONFIG_REF: main restart: unless-stopped init: true environment: MONGODB_URI: mongodb://al-mongo:27017/adventureland?replicaSet=rs0 MONGODB_NAME: adventureland # See docker/patch-drm-check.js: without Steam/MAS auth a self-hosted # server would flag every account with "Authorization Failure". # Set to "1" to restore the upstream DRM check. AL_DRM_CHECK: "0" volumes: # Editable keys/options from the host (replaces the cloned template). - ./files/config:/app/secretsandconfig:ro services: # MongoDB runs as a single-node replica set: the game uses transactions, # which MongoDB only allows on replica set members. al-mongo: image: *mongo_image restart: unless-stopped command: ["mongod", "--replSet", "rs0", "--bind_ip_all"] networks: - adventureland volumes: - ./files/db:/data/db healthcheck: test: ["CMD", "mongosh", "--quiet", "--eval", "quit(db.adminCommand({ ping: 1 }).ok ? 0 : 1)"] interval: 5s timeout: 10s retries: 24 start_period: 10s # One-shot: initiates the replset on a fresh database volume. Safe to rerun. al-mongo-init: image: *mongo_image restart: "no" networks: - adventureland depends_on: al-mongo: condition: service_healthy entrypoint: ["/bin/bash", "/scripts/mongo-init.sh"] volumes: - ./docker/mongo-init.sh:/scripts/mongo-init.sh:ro # One-shot: imports the 49 map documents from scripts/seed_mongodb.js. # # The seed script only accepts a direct local connection, so this container # shares MongoDB's network namespace and talks to 127.0.0.1. It skips the # import (exit 0) when the database already has collections. al-seed: <<: *app restart: "no" environment: MONGODB_URI: mongodb://127.0.0.1:27017/adventureland MONGODB_NAME: adventureland network_mode: "service:al-mongo" depends_on: al-mongo-init: condition: service_completed_successfully entrypoint: ["/bin/sh", "/app/docker/seed.sh"] # Web backend: serves the game client on http://localhost:8090 al-backend: <<: *app command: ["node", "main.js"] environment: # See docker/entrypoint.sh: lets the backend reach the game server at # the address it advertises to browsers (localhost:7192). AL_GAME_RELAY: "1" AL_GAME_HOST: al-game AL_GAME_PORT: "7192" networks: - adventureland - backend ports: - 8090:8090 depends_on: al-seed: condition: service_completed_successfully healthcheck: test: ["CMD", "node", "-e", 'fetch("http://127.0.0.1:8090/").then((r) => process.exit(r.status < 500 ? 0 : 1)).catch(() => process.exit(1))'] interval: 10s timeout: 10s retries: 12 start_period: 30s # Game server (Socket.IO) - clients connect to localhost:7192 directly. al-game: <<: *app command: ["node", "server.js", "local"] working_dir: /app/node networks: - adventureland - backend ports: - 7192:7192 depends_on: al-seed: condition: service_completed_successfully al-backend: condition: service_started healthcheck: test: ["CMD", "node", "-e", 'fetch("http://127.0.0.1:7192/").then((r) => process.exit(r.ok ? 0 : 1)).catch(() => process.exit(1))'] interval: 10s timeout: 10s retries: 12 start_period: 30s networks: adventureland: backend: # external: true