Files
dotcom-arcade/docker-compose.yml
T

98 lines
3.8 KiB
YAML

# =============================================================================
# Flashpoint Web - Production Docker Compose
# =============================================================================
# Single image serving both the API and the web UI.
# Uses a pre-built image from the container registry.
#
# Usage:
# 1. Copy .env.example to .env and configure required variables
# 2. docker compose up -d
#
# For local development with image building, use:
# docker compose -f docker-compose.dev.yml up -d --build
#
# User permissions:
# Set PUID/PGID to match your host user (run 'id -u' and 'id -g' to find)
# This ensures bind-mounted volumes have correct ownership
# =============================================================================
services:
flashpoint-web:
image: darkraise/flashpoint-web:${IMAGE_TAG:-latest}
container_name: flashpoint-web
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
- HOME_RECENT_HOURS=${HOME_RECENT_HOURS:-24}
- ENABLE_CGI=${ENABLE_CGI:-false}
# Streamed play for games that can't run in a browser (off unless both are set)
- STREAMING_API_URL=${STREAMING_API_URL:-}
- STREAMING_API_TOKEN=${STREAMING_API_TOKEN:-}
# 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:-flashpoint-web}
- 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:
- flashpoint-network
networks:
flashpoint-network:
driver: bridge