-
Notifications
You must be signed in to change notification settings - Fork 15
Expand file tree
/
Copy pathdocker-compose.prod.yaml
More file actions
91 lines (85 loc) · 3.38 KB
/
Copy pathdocker-compose.prod.yaml
File metadata and controls
91 lines (85 loc) · 3.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# Production compose file — web container plus Valkey; Postgres and
# Elasticsearch are expected to be provided externally.
#
# IMAGE_TAG=sha-abc12345 docker compose -f docker-compose.prod.yaml up -d
#
# IMAGE_TAG selects the app + SSR images (CI publishes both per commit with
# matching tags) and is required — compose refuses to start without it rather
# than silently running :latest.
#
# Configuration comes from .env via `env_file`, which injects the values as
# container environment variables — it does NOT mount a .env file into the
# container. That distinction matters: the entrypoint only re-runs
# `php artisan optimize` (rebuilding the config cache from the environment)
# when no .env file exists in /app. A mounted .env would be ignored in favour
# of the config cache baked into the image at build time.
#
# The datastore lives on the host at /mnt/ponyfm-production-datastore, bound
# to /mnt/datastore inside the container — the same layout the legacy stack
# uses, so both stacks can share one .env. PONYFM_DATASTORE=/mnt/datastore
# MUST be set in .env: the app derives file paths from it and sends them as
# X-Accel-Redirect, and Caddy (docker/frankenphp/Caddyfile) reads the same
# variable to decide which paths it will serve — if they disagree, downloads
# and images come back empty under USE_SENDFILE=true.
# While the legacy stack runs alongside this one, the shared Postgres database
# is fine but cache and queues must not collide: the legacy stack uses Redis
# DBs 0 (queues) and 1 (cache), so this stack is pinned to 2 and 3. Set here
# rather than in .env so the isolation can't be lost by a stale .env edit.
services:
web2:
image: ghcr.io/poniverse/pony.fm:${IMAGE_TAG:?IMAGE_TAG is required}
command:
- web
restart: unless-stopped
ports:
# Octane/FrankenPHP listens on 8080 inside the container (see
# docker/entrypoint.sh), not 80 like the old nginx image. Named
# WEB2_PORT so it can't collide with the legacy stack's WEB_PORT
# while both run from one compose project.
- "${WEB2_PORT:-8080}:8080"
env_file:
- .env
environment:
REDIS_DB: "2"
REDIS_CACHE_DB: "3"
volumes:
- /mnt/ponyfm-production-datastore:/mnt/datastore
depends_on:
- valkey
- ssr
# Queue worker: track encoding, notifications, and search indexing jobs.
worker2:
image: ghcr.io/poniverse/pony.fm:${IMAGE_TAG:?IMAGE_TAG is required}
command:
- worker
restart: unless-stopped
env_file:
- .env
environment:
REDIS_DB: "2"
REDIS_CACHE_DB: "3"
volumes:
- /mnt/ponyfm-production-datastore:/mnt/datastore
depends_on:
- valkey
# Inertia SSR server, published by CI from the Dockerfile's `ssr` target.
# Set INERTIA_SSR_ENABLED=true and INERTIA_SSR_URL=http://ssr:13714 in .env
# to turn server rendering on; the app degrades to client-side rendering
# whenever this is unreachable.
ssr:
image: ghcr.io/poniverse/pony.fm-ssr:${IMAGE_TAG:?IMAGE_TAG is required}
restart: unless-stopped
# Redis-compatible store for cache/sessions/queues. Reachable from the web
# container as "valkey" — set REDIS_HOST=valkey in .env. Not exposed on the
# host.
valkey:
image: valkey/valkey:9-alpine
restart: unless-stopped
command:
- valkey-server
- --appendonly
- "yes"
volumes:
- valkey-data:/data
volumes:
valkey-data: