Drops the /flash and /html5 sections (old URLs redirect to /browse), the GitHub star count endpoint, the unused HOME_RECENT_HOURS setting, upstream's design notes and code review docs, and the issue template's link to upstream discussions.
144 lines
5.9 KiB
YAML
144 lines
5.9 KiB
YAML
# =============================================================================
|
|
# Dotcom Arcade
|
|
# =============================================================================
|
|
# The app serves the UI and API. With the "streaming" profile, a session
|
|
# manager also streams games that can't run in a browser (Java, Shockwave,
|
|
# Flash Player, Windows games), one container per player.
|
|
#
|
|
# Usage:
|
|
# 1. Copy .env.example to .env and set the required variables
|
|
# 2. docker compose up -d --build
|
|
# (or, with IMAGE_PREFIX set to a registry's images:
|
|
# docker compose pull && docker compose up -d)
|
|
# 3. For streaming, set STREAMING_API_TOKEN and COMPOSE_PROFILES=streaming in
|
|
# .env, then run `docker compose up -d --build` again
|
|
#
|
|
# Set PUID/PGID to your host user (`id -u`, `id -g`) so bind-mounted volumes
|
|
# get the right ownership.
|
|
# =============================================================================
|
|
|
|
services:
|
|
app:
|
|
build: .
|
|
image: ${IMAGE_PREFIX:-}dotcom-arcade:${IMAGE_TAG:-latest}
|
|
container_name: dotcom-arcade
|
|
restart: unless-stopped
|
|
ports:
|
|
# Serves both the UI and the API (/api, /game-proxy, /game-zip) on one port
|
|
- "${WEB_PORT:-80}:3100"
|
|
volumes:
|
|
# Read-write: the app records downloaded state in flashpoint.sqlite and
|
|
# writes downloaded game data under Data/Games.
|
|
- ${FLASHPOINT_HOST_PATH:?FLASHPOINT_HOST_PATH is required}:/data/flashpoint
|
|
# Holds user.db and the installed Ruffle. Without this mount an in-app
|
|
# Ruffle update is lost the next time the container is recreated.
|
|
- ${DATA_PATH:-./data}:/app/data
|
|
- ${LOGS_PATH:-./logs}:/app/logs
|
|
environment:
|
|
- PUID=${PUID:-1000}
|
|
- PGID=${PGID:-1000}
|
|
- NODE_ENV=production
|
|
- SERVE_FRONTEND=true
|
|
- TZ=${TZ:-UTC}
|
|
- DOMAIN=${DOMAIN:-http://localhost:${WEB_PORT:-80}}
|
|
- LOG_LEVEL=${LOG_LEVEL:-info}
|
|
# File I/O parallelism: images and ZIP reads run on libuv's threadpool,
|
|
# whose default of 4 throttles every filesystem request in the process.
|
|
- UV_THREADPOOL_SIZE=${UV_THREADPOOL_SIZE:-16}
|
|
- JWT_SECRET=${JWT_SECRET:?JWT_SECRET is required}
|
|
- ENABLE_LOCAL_DB_COPY=${ENABLE_LOCAL_DB_COPY:-false}
|
|
- SQLITE_CACHE_SIZE=${SQLITE_CACHE_SIZE:--64000}
|
|
- SQLITE_MMAP_SIZE=${SQLITE_MMAP_SIZE:-268435456}
|
|
- ENABLE_CACHE_PREWARM=${ENABLE_CACHE_PREWARM:-true}
|
|
# Auth & rate limiting
|
|
- JWT_EXPIRES_IN=${JWT_EXPIRES_IN:-1h}
|
|
- BCRYPT_SALT_ROUNDS=${BCRYPT_SALT_ROUNDS:-10}
|
|
- RATE_LIMIT_WINDOW_MS=${RATE_LIMIT_WINDOW_MS:-60000}
|
|
- RATE_LIMIT_MAX_REQUESTS=${RATE_LIMIT_MAX_REQUESTS:-100}
|
|
# Application
|
|
# "Latest release" API URL (GitHub or Gitea) for update checks; off when unset
|
|
- APP_UPDATE_URL=${APP_UPDATE_URL:-}
|
|
- ENABLE_CGI=${ENABLE_CGI:-false}
|
|
# Streamed play for games that can't run in a browser (off unless the token is set)
|
|
- STREAMING_API_URL=${STREAMING_API_URL:-http://session-manager:8080}
|
|
- STREAMING_STREAM_URL=${STREAMING_STREAM_URL:-http://session-manager:8081}
|
|
- STREAMING_API_TOKEN=${STREAMING_API_TOKEN:-}
|
|
# Sign in users named by an authenticating reverse proxy (off unless both are set)
|
|
- TRUSTED_HEADER_USERNAME=${TRUSTED_HEADER_USERNAME:-}
|
|
- TRUSTED_HEADER_EMAIL=${TRUSTED_HEADER_EMAIL:-}
|
|
- TRUSTED_PROXIES=${TRUSTED_PROXIES:-}
|
|
# OpenTelemetry
|
|
- OTEL_ENABLED=${OTEL_ENABLED:-false}
|
|
- OTEL_EXPORTER_OTLP_ENDPOINT=${OTEL_EXPORTER_OTLP_ENDPOINT:-}
|
|
- OTEL_API_KEY=${OTEL_API_KEY:-}
|
|
- OTEL_SERVICE_NAME=${OTEL_SERVICE_NAME:-dotcom-arcade}
|
|
- OTEL_TRACES_ENABLED=${OTEL_TRACES_ENABLED:-true}
|
|
- OTEL_METRICS_ENABLED=${OTEL_METRICS_ENABLED:-true}
|
|
- OTEL_METRICS_EXPORT_INTERVAL=${OTEL_METRICS_EXPORT_INTERVAL:-60000}
|
|
- OTEL_LOG_LEVEL=${OTEL_LOG_LEVEL:-info}
|
|
healthcheck:
|
|
test: ["CMD", "curl", "--fail", "http://localhost:3100/health"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
# The port opens early and /health reports "starting" until the database
|
|
# copy and cache pre-warm finish, which is minutes on a network share.
|
|
start_period: 300s
|
|
logging:
|
|
driver: json-file
|
|
options:
|
|
max-size: "10m"
|
|
max-file: "3"
|
|
deploy:
|
|
resources:
|
|
limits:
|
|
cpus: "2.0"
|
|
memory: 2G
|
|
reservations:
|
|
cpus: "0.5"
|
|
memory: 512M
|
|
networks:
|
|
- arcade
|
|
|
|
# Starts a streamer container per player. The app proxies /stream/ to it, so
|
|
# it publishes no ports.
|
|
session-manager:
|
|
profiles: [streaming]
|
|
build: streaming/session-manager
|
|
image: ${IMAGE_PREFIX:-}dotcom-arcade-session-manager:${IMAGE_TAG:-latest}
|
|
container_name: dotcom-arcade-session-manager
|
|
restart: unless-stopped
|
|
volumes:
|
|
# Starts and removes streamer containers. Docker socket access is
|
|
# effectively root on the host.
|
|
- /var/run/docker.sock:/var/run/docker.sock
|
|
- ${FLASHPOINT_HOST_PATH:?FLASHPOINT_HOST_PATH is required}:/flashpoint:ro
|
|
environment:
|
|
- FLASHPOINT_HOST_PATH
|
|
# The session manager refuses to start without it
|
|
- API_TOKEN=${STREAMING_API_TOKEN:-}
|
|
- STREAMER_IMAGE=${IMAGE_PREFIX:-}dotcom-arcade-streamer:${IMAGE_TAG:-latest}
|
|
- STREAMER_NETWORK=dotcom-arcade-streams
|
|
- MAX_SESSIONS=${MAX_SESSIONS:-4}
|
|
- STREAM_PLATFORMS=${STREAM_PLATFORMS:-Java,Shockwave,Flash}
|
|
- PUID=${PUID:-1000}
|
|
- PGID=${PGID:-1000}
|
|
networks:
|
|
- arcade
|
|
- streams
|
|
|
|
# The image the session manager runs per player; built here, never started by compose
|
|
streamer:
|
|
profiles: [streaming]
|
|
build: streaming/streamer
|
|
image: ${IMAGE_PREFIX:-}dotcom-arcade-streamer:${IMAGE_TAG:-latest}
|
|
scale: 0
|
|
|
|
networks:
|
|
arcade:
|
|
name: dotcom-arcade
|
|
# Streamer containers: reachable only from the session manager, no internet access
|
|
streams:
|
|
name: dotcom-arcade-streams
|
|
internal: true
|