services: minecraft: image: itzg/minecraft-server:latest container_name: minecraft expose: - "25565" environment: EULA: "TRUE" ONLINE_MODE: "FALSE" TYPE: "VANILLA" VERSION: "26.1.2" MEMORY: "4G" volumes: - ./data:/data restart: unless-stopped stdin_open: true tty: true autossh: image: jnovack/autossh:2.0.1 container_name: minecraft-autossh restart: unless-stopped depends_on: - minecraft environment: SSH_REMOTE_USER: root SSH_REMOTE_HOST: spotbotdev1.dedicated.co.za SSH_REMOTE_PORT: "22" SSH_BIND_IP: "0.0.0.0" # bind on the *remote* (spotbot) public iface SSH_TUNNEL_PORT: "25565" # spotbot:25565 (public side) … SSH_TARGET_HOST: "minecraft" # → service name on the compose network … SSH_TARGET_PORT: "25565" # → minecraft container's :25565 SSH_MODE: "-R" SSH_KEY_FILE: "/id_rsa" SSH_KNOWN_HOSTS_FILE: "/known_hosts" SSH_SERVER_ALIVE_INTERVAL: "20" SSH_SERVER_ALIVE_COUNT_MAX: "3" AUTOSSH_GATETIME: "0" AUTOSSH_PORT: "0" # disable monitoring port; rely on ServerAlive AUTOSSH_LOGLEVEL: "1" volumes: - ./ssh/spotbot_key:/id_rsa:ro - ./ssh/known_hosts:/known_hosts:ro bot: build: ./bot image: minecraft-telegram-bot:latest container_name: minecraft-bot restart: unless-stopped environment: BOT_TOKEN_FILE: /run/secrets/bot_token GEMINI_API_KEY_FILE: /run/secrets/google_key GEMINI_MODEL: "${GEMINI_MODEL:-gemini-2.5-flash-lite}" # OpenRouter primary; Gemini stays as fallback. `openrouter/free` auto- # selects a free model that supports tool calling for this request. OPENROUTER_API_KEY_FILE: /run/secrets/openrouter_token OPENROUTER_MODEL: "${OPENROUTER_MODEL:-openrouter/free}" MC_DIR: /mc DB_PATH: /data/users.db ADMIN_BOOTSTRAP: "${ADMIN_BOOTSTRAP:-1311866578:Paul}" COMPOSE_HOST_DIR: "${COMPOSE_HOST_DIR:-/home/paul/containers/minecraft}" TZ: Africa/Johannesburg # Gitea release upload from inside the container. The token is mounted # as a docker secret (see `secrets:` below + ./gitea.token, gitignored); # backup.sh reads it via $GITEA_TOKEN_FILE. GITEA_API_BASE / GITEA_REPO # let backup.sh skip its `git config remote.origin.url` parse — needed # because the host's origin URL points at localhost:3000, which the bot # container can't reach. GITEA_TOKEN_FILE: /run/secrets/gitea_token GITEA_API_BASE: "${GITEA_API_BASE:-https://thinkstation-web.spot-bot.co.za/api/v1}" GITEA_REPO: "${GITEA_REPO:-paul/Minecraft-Server}" volumes: - /var/run/docker.sock:/var/run/docker.sock - .:/mc - ./bot/data:/data secrets: - bot_token - google_key - gitea_token - openrouter_token secrets: bot_token: file: ./bot.token google_key: file: ./google_key.txt gitea_token: file: ./gitea.token openrouter_token: file: ./openrouter.token