-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathdocker-compose.yml
More file actions
189 lines (175 loc) · 8.79 KB
/
Copy pathdocker-compose.yml
File metadata and controls
189 lines (175 loc) · 8.79 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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# This file is a minimal plug and play working example of a runnable OpenShock stack.
#
# Configuration lives in the .env file next to this compose file. You edit simple
# KEY=value knobs there (host, port, per-service paths, DB password, mail...). This
# file maps those onto the OPENSHOCK__* / PUBLIC_* config the containers read.
#
# Topology: the whole stack runs on ONE host (OPENSHOCK_HOST) and ONE port
# (OPENSHOCK_PORT, default 443), and the services are told apart by path:
# https://host/ -> frontend
# https://host/api/... -> api (OPENSHOCK_API_PATH)
# https://host/gateway/.. -> gateway (OPENSHOCK_GATEWAY_PATH)
# Because everything is one origin, the login cookie is shared with no extra setup.
# Each app owns its path prefix (UsePathBase); Traefik routes by PathPrefix and does
# NOT strip. Shared OPENSHOCK__* config lives in x-openshock-env, merged into each
# service; the `:-default` fallbacks keep the stack booting with almost no config.
# ---------------------------------------------------------------------------
# Shared application config. Every OpenShock service (api, cron, lcg) reads the
# same OPENSHOCK__* schema, so it is defined once here and merged into each
# service with `<<: *openshock-env`. Values come from the knobs in .env; the
# `:-default` fallbacks keep the stack booting with almost no configuration.
# The `${OPENSHOCK_PORT:+:...}` bits append ":port" only when a custom port is set,
# so default (443) deployments keep clean https://host URLs.
# ---------------------------------------------------------------------------
x-openshock-env: &openshock-env
# Core infrastructure
OPENSHOCK__DB__CONN: Host=db;Port=5432;Database=${PG_DB:-openshock};Username=${PG_USER:-openshock};Password=${PG_PASS}
OPENSHOCK__REDIS__HOST: dragonfly
# Frontend URLs — API uses them for cookies/redirects, Cron for e-mail links.
# BASEURL/SHORTURL point at the web UI (host + optional port + frontend path).
# COOKIEDOMAIN is the bare host; since the whole stack is one origin the login
# cookie is shared with every service automatically.
OPENSHOCK__FRONTEND__BASEURL: https://${OPENSHOCK_HOST:-openshock.local}${OPENSHOCK_PORT:+:${OPENSHOCK_PORT}}${OPENSHOCK_FRONTEND_PATH:-}
OPENSHOCK__FRONTEND__SHORTURL: https://${OPENSHOCK_HOST:-openshock.local}${OPENSHOCK_PORT:+:${OPENSHOCK_PORT}}${OPENSHOCK_FRONTEND_PATH:-}
OPENSHOCK__FRONTEND__COOKIEDOMAIN: ${OPENSHOCK_HOST:-openshock.local}
# Feature flags
OPENSHOCK__TURNSTILE__ENABLE: ${OPENSHOCK_TURNSTILE_ENABLE:-false}
OPENSHOCK__ACCOUNT__REGISTRATIONENABLED: ${OPENSHOCK_REGISTRATION_ENABLED:-true}
# E-mail (delivered by the Cron service). TYPE is required by the app; leave it
# as None to run without outbound mail, or set MAIL_TYPE=Smtp / Mailjet in .env
# and fill in the matching block below.
OPENSHOCK__MAIL__TYPE: ${MAIL_TYPE:-None}
OPENSHOCK__MAIL__SENDER__NAME: ${MAIL_SENDER_NAME:-OpenShock}
OPENSHOCK__MAIL__SENDER__EMAIL: ${MAIL_SENDER_EMAIL:-no-reply@openshock.local}
# SMTP (used when MAIL_TYPE=Smtp)
OPENSHOCK__MAIL__SMTP__HOST: ${SMTP_HOST:-}
OPENSHOCK__MAIL__SMTP__PORT: ${SMTP_PORT:-587}
OPENSHOCK__MAIL__SMTP__USERNAME: ${SMTP_USERNAME:-}
OPENSHOCK__MAIL__SMTP__PASSWORD: ${SMTP_PASSWORD:-}
OPENSHOCK__MAIL__SMTP__ENABLESSL: ${SMTP_ENABLESSL:-true}
OPENSHOCK__MAIL__SMTP__VERIFYCERTIFICATE: ${SMTP_VERIFYCERTIFICATE:-true}
# Mailjet (used when MAIL_TYPE=Mailjet)
OPENSHOCK__MAIL__MAILJET__KEY: ${MAILJET_KEY:-}
OPENSHOCK__MAIL__MAILJET__SECRET: ${MAILJET_SECRET:-}
# Common scaffolding shared by the OpenShock app services.
x-openshock-svc: &openshock-svc
restart: unless-stopped
networks:
- openshock
depends_on:
- db
- dragonfly
services:
db: # We need a postgres database, preferably version 18+
image: postgres:18
restart: unless-stopped
container_name: openshock-postgres
healthcheck:
test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"]
start_period: 20s
interval: 30s
retries: 5
timeout: 5s
networks:
- openshock
environment:
POSTGRES_PASSWORD: ${PG_PASS:?database password required}
POSTGRES_USER: ${PG_USER:-openshock}
POSTGRES_DB: ${PG_DB:-openshock}
volumes:
# PG18+ mounts the parent dir (data lives in ./postgres-data/18/docker).
- ./postgres-data:/var/lib/postgresql
dragonfly: # Redis-compatible store. Ex = emit expired-key events (used by the app)
image: ghcr.io/dragonflydb/dragonfly:latest
command: "--notify_keyspace_events=Ex"
restart: unless-stopped
networks:
- openshock
volumes:
- ./dragonfly-data:/data
api:
<<: *openshock-svc
image: ghcr.io/openshock/api:${OPENSHOCK_TAG:-latest}
environment:
<<: *openshock-env
# Path prefix the API is served under. Must match the PathPrefix router below.
OPENSHOCK__API__PATHBASE: ${OPENSHOCK_API_PATH:-/api}
labels:
- "traefik.enable=true"
- "traefik.http.routers.openshock-api.rule=Host(`${OPENSHOCK_HOST:-openshock.local}`) && PathPrefix(`${OPENSHOCK_API_PATH:-/api}`)"
- "traefik.http.routers.openshock-api.entrypoints=https"
- "traefik.http.routers.openshock-api.tls=true"
- "traefik.http.routers.openshock-api.service=openshock-api"
- "traefik.http.services.openshock-api.loadbalancer.server.port=80"
frontend:
image: ghcr.io/openshock/frontend:${OPENSHOCK_FRONTEND_TAG:-latest}
restart: unless-stopped
networks:
- openshock
environment:
PUBLIC_SITE_NAME: OpenShock
PUBLIC_SITE_URL: https://${OPENSHOCK_HOST:-openshock.local}${OPENSHOCK_PORT:+:${OPENSHOCK_PORT}}${OPENSHOCK_FRONTEND_PATH:-}
PUBLIC_SITE_SHORT_URL: https://${OPENSHOCK_HOST:-openshock.local}${OPENSHOCK_PORT:+:${OPENSHOCK_PORT}}${OPENSHOCK_FRONTEND_PATH:-}
PUBLIC_BACKEND_API_URL: https://${OPENSHOCK_HOST:-openshock.local}${OPENSHOCK_PORT:+:${OPENSHOCK_PORT}}${OPENSHOCK_API_PATH:-/api}
# CSP connect-src allow-list for the gateway; the browser opens wss://host[:port].
PUBLIC_GATEWAY_CSP_WILDCARD: https://${OPENSHOCK_HOST:-openshock.local}${OPENSHOCK_PORT:+:${OPENSHOCK_PORT}}
labels:
- "traefik.enable=true"
# Catch-all for the host; the api/gateway/cron PathPrefix routers are more specific and win.
- "traefik.http.routers.openshock-frontend.rule=Host(`${OPENSHOCK_HOST:-openshock.local}`)"
- "traefik.http.routers.openshock-frontend.entrypoints=https"
- "traefik.http.routers.openshock-frontend.tls=true"
- "traefik.http.routers.openshock-frontend.service=openshock-frontend"
- "traefik.http.services.openshock-frontend.loadbalancer.server.port=3000"
lcg:
<<: *openshock-svc
image: ghcr.io/openshock/live-control-gateway:${OPENSHOCK_TAG:-latest}
environment:
<<: *openshock-env
OPENSHOCK__LCG__COUNTRYCODE: ${OPENSHOCK_LCG_COUNTRYCODE:-DE}
# Public address the gateway advertises to firmware & browsers. PUBLICPATH must
# match the PathPrefix router below (the app serves under it via UsePathBase).
OPENSHOCK__LCG__FQDN: ${OPENSHOCK_HOST:-openshock.local}
OPENSHOCK__LCG__PUBLICPORT: ${OPENSHOCK_PORT:-443}
OPENSHOCK__LCG__PUBLICPATH: ${OPENSHOCK_GATEWAY_PATH:-/gateway}
labels:
- "traefik.enable=true"
- "traefik.http.routers.openshock-gateway.rule=Host(`${OPENSHOCK_HOST:-openshock.local}`) && PathPrefix(`${OPENSHOCK_GATEWAY_PATH:-/gateway}`)"
- "traefik.http.routers.openshock-gateway.entrypoints=https"
- "traefik.http.routers.openshock-gateway.tls=true"
- "traefik.http.routers.openshock-gateway.service=openshock-gateway"
- "traefik.http.services.openshock-gateway.loadbalancer.server.port=80"
cron:
<<: *openshock-svc
image: ghcr.io/openshock/cron:${OPENSHOCK_TAG:-latest}
environment:
<<: *openshock-env
labels:
- "traefik.enable=true"
- "traefik.http.routers.openshock-cron.rule=Host(`${OPENSHOCK_HOST:-openshock.local}`) && PathPrefix(`/hangfire`)"
- "traefik.http.routers.openshock-cron.entrypoints=https"
- "traefik.http.routers.openshock-cron.tls=true"
- "traefik.http.routers.openshock-cron.service=openshock-cron"
- "traefik.http.services.openshock-cron.loadbalancer.server.port=780"
traefik:
image: traefik:latest
container_name: traefik
command:
#- "--log.level=DEBUG"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entryPoints.https.address=:443"
#- "--api.insecure=true"
restart: unless-stopped
networks:
- openshock
ports:
- 80:80
# Publish the stack port (default 443) onto Traefik's https entrypoint.
- ${OPENSHOCK_PORT:-443}:443
#- 8080:8080 # Traefik Web UI (enabled by --api.insecure=true)
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
networks:
openshock: