95 lines
3.8 KiB
YAML
95 lines
3.8 KiB
YAML
# =============================================================================
|
|
# Flashpoint Web - Development Docker Compose
|
|
# =============================================================================
|
|
# Builds the single API + UI image locally from source.
|
|
#
|
|
# Usage:
|
|
# docker compose -f docker-compose.dev.yml up -d --build
|
|
#
|
|
# View logs:
|
|
# docker compose -f docker-compose.dev.yml logs -f
|
|
#
|
|
# 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:
|
|
build:
|
|
context: .
|
|
dockerfile: ./Dockerfile
|
|
image: flashpoint-web:dev
|
|
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.
|
|
- backend-db:/app/data
|
|
- ${LOGS_PATH:-./logs}:/app/logs
|
|
environment:
|
|
- PUID=${PUID:-1000}
|
|
- PGID=${PGID:-1000}
|
|
- NODE_ENV=${NODE_ENV:-development}
|
|
- SERVE_FRONTEND=true
|
|
# Matches the read-only mount above. Set explicitly because the backend's
|
|
# fallback only points here when NODE_ENV=production.
|
|
- FLASHPOINT_PATH=/data/flashpoint
|
|
# Same reason as FLASHPOINT_PATH above: this container runs
|
|
# NODE_ENV=development, so the production default would put Ruffle outside
|
|
# the data volume and lose every update on recreate.
|
|
- RUFFLE_DATA_PATH=/app/data/ruffle
|
|
- 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
|
|
start_period: 40s
|
|
networks:
|
|
- flashpoint-network
|
|
|
|
networks:
|
|
flashpoint-network:
|
|
driver: bridge
|
|
|
|
volumes:
|
|
backend-db:
|
|
driver: local
|