Matches cache.handler=redis in .env.docker.example; lets the file-based rate limiter and page cache work consistently across web/api/worker replicas.
102 lines
2.8 KiB
YAML
102 lines
2.8 KiB
YAML
# ---------------------------------------------------------------------------
|
|
# Toolvana production topology.
|
|
#
|
|
# browser -> nginx -> php-fpm (web) stateless, page-cached
|
|
# -> api (php-fpm) /api/v1 traffic isolation
|
|
#
|
|
# queue: postgres/mysql durable jobs; workers scale horizontally:
|
|
# worker-1 .. worker-N (spark queue:work --loop)
|
|
# scheduler (media:cleanup every 5 min + stale reaper)
|
|
#
|
|
# Replace the DB image or add Redis freely — the app only needs a
|
|
# PDO-compatible database and the file cache driver works everywhere.
|
|
# ---------------------------------------------------------------------------
|
|
|
|
x-app-common: &app-common
|
|
build:
|
|
context: .
|
|
dockerfile: docker/Dockerfile
|
|
restart: unless-stopped
|
|
env_file: .env.docker
|
|
volumes:
|
|
- media-storage:/app/writable/media
|
|
- incoming-storage:/app/writable/incoming
|
|
- session-storage:/app/writable/session
|
|
- og-cache:/app/writable/og
|
|
|
|
services:
|
|
nginx:
|
|
image: nginx:1.27-alpine
|
|
restart: unless-stopped
|
|
ports:
|
|
- "80:80"
|
|
- "443:443" # mount certs + full server block for TLS in production
|
|
volumes:
|
|
- ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
|
|
- ./public:/app/public:ro
|
|
- ./writable/og:/app/writable/og:ro
|
|
depends_on:
|
|
- web
|
|
- api
|
|
|
|
web:
|
|
<<: *app-common
|
|
environment:
|
|
TV_ROLE: web
|
|
|
|
# Dedicated pool for developer API + processing endpoints so large
|
|
# conversions never starve page rendering.
|
|
api:
|
|
<<: *app-common
|
|
environment:
|
|
TV_ROLE: api
|
|
|
|
worker-1:
|
|
<<: *app-common
|
|
command: ["php", "spark", "queue:work", "--loop", "--sleep", "2"]
|
|
deploy:
|
|
replicas: 3 # worker-1..worker-N: scale to taste
|
|
|
|
scheduler:
|
|
<<: *app-common
|
|
command: >
|
|
bash -c "while true; do
|
|
php spark media:cleanup >> writable/logs/scheduler.log 2>&1;
|
|
sleep 300;
|
|
done"
|
|
|
|
db:
|
|
image: mariadb:11
|
|
restart: unless-stopped
|
|
environment:
|
|
MARIADB_DATABASE: toolvana
|
|
MARIADB_USER: toolvana
|
|
MARIADB_PASSWORD: ${DB_PASSWORD:-toolvana}
|
|
MARIADB_ROOT_PASSWORD: ${DB_ROOT_PASSWORD:-root-secret}
|
|
volumes:
|
|
- db-data:/var/lib/mysql
|
|
healthcheck:
|
|
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
|
|
interval: 10s
|
|
retries: 5
|
|
|
|
# Shared cache + rate-limit buckets across web/api/worker replicas.
|
|
redis:
|
|
image: redis:7-alpine
|
|
restart: unless-stopped
|
|
command: ["redis-server", "--maxmemory", "256mb", "--maxmemory-policy", "allkeys-lru"]
|
|
volumes:
|
|
- redis-data:/data
|
|
healthcheck:
|
|
test: ["CMD", "redis-cli", "ping"]
|
|
interval: 10s
|
|
retries: 5
|
|
|
|
volumes:
|
|
db-data:
|
|
redis-data:
|
|
media-storage:
|
|
incoming-storage:
|
|
session-storage:
|
|
og-cache:
|