A modified version of Wafrn used on https://wf.jbc.lol (mirror of https://git.jbc.lol/jbcrn/wf.jbc.lol which is a mirror of https://codeberg.org/jbcarreon123/wf.jbc.lol)
1services:
2 backend: &default_backend
3 build: &default_backend_build
4 context: .
5 dockerfile: packages/backend/Dockerfile
6 # these args configure private env vars for the backend and public env vars for the frontend
7 depends_on:
8 db:
9 condition: service_healthy
10 redis:
11 condition: service_started
12 frontend:
13 condition: service_started
14 migration:
15 condition: service_completed_successfully
16 restart: unless-stopped
17 environment: &default_backend_env_vars
18 NODE_ENV: production
19 ADMIN_USER: ${ADMIN_USER}
20 ADMIN_EMAIL: ${ADMIN_EMAIL}
21 ADMIN_PASSWORD: ${ADMIN_PASSWORD}
22 JWT_SECRET: ${JWT_SECRET}
23 DOMAIN_NAME: ${DOMAIN_NAME}
24
25 CACHE_DOMAIN: ${CACHE_DOMAIN}
26 MEDIA_DOMAIN: ${MEDIA_DOMAIN}
27
28 SMTP_HOST: ${SMTP_HOST}
29 SMTP_USER: ${SMTP_USER}
30 SMTP_PORT: ${SMTP_PORT}
31 SMTP_PASSWORD: ${SMTP_PASSWORD}
32 SMTP_FROM: ${SMTP_FROM}
33
34 POSTGRES_USER: ${POSTGRES_USER}
35 POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
36 POSTGRES_DBNAME: ${POSTGRES_DBNAME}
37
38 WEBPUSH_EMAIL: ${WEBPUSH_EMAIL}
39 WEBPUSH_PRIVATE: ${WEBPUSH_PRIVATE}
40 WEBPUSH_PUBLIC: ${WEBPUSH_PUBLIC}
41
42 ENABLE_BSKY: ${ENABLE_BSKY}
43 PDS_DOMAIN_NAME: ${PDS_DOMAIN_NAME}
44 PDS_JWT_SECRET: ${PDS_JWT_SECRET}
45 PDS_ADMIN_PASSWORD: ${PDS_ADMIN_PASSWORD}
46
47 USE_WORKERS: false
48 LOG_SQL_QUERIES: ${LOG_SQL_QUERIES:-}
49 UPLOAD_LIMIT: ${UPLOAD_LIMIT:-}
50 POSTS_PER_PAGE: ${POSTS_PER_PAGE:-}
51 LOG_LEVEL: ${LOG_LEVEL:-}
52 BLOCKLIST_URI: ${BLOCKLIST_URI:-}
53 FRONTEND_PATH: ${FRONTEND_PATH:-}
54 DISABLE_REQUIRE_SEND_EMAIL: ${DISABLE_REQUIRE_SEND_EMAIL:-}
55 BLOCKED_IPS: ${BLOCKED_IPS:-}
56 REVIEW_REGISTRATIONS: ${REVIEW_REGISTRATIONS:-}
57 IGNORE_BLOCK_HOSTS: ${IGNORE_BLOCK_HOSTS:-}
58
59 FRONTEND_LOGO: ${FRONTEND_LOGO:-}
60 FRONTEND_API_URL: ${FRONTEND_API_URL:-}
61 FRONTEND_MEDIA_URL: ${FRONTEND_MEDIA_URL:-}
62 FRONTEND_CACHE_URL: ${FRONTEND_CACHE_URL:-}
63 FRONTEND_CACHE_BACKUP_URLS: ${FRONTEND_CACHE_BACKUP_URLS:-}
64 FRONTEND_SHORTEN_POSTS: ${FRONTEND_SHORTEN_POSTS:-}
65 FRONTEND_DISABLE_PWA: ${FRONTEND_DISABLE_PWA:-}
66 FRONTEND_MAINTENANCE: ${FRONTEND_MAINTENANCE:-}
67 FRONTEND_SHORT_TITLE: ${FRONTEND_SHORT_TITLE:-}
68 FRONTEND_LONG_TITLE: ${FRONTEND_LONG_TITLE:-}
69 FRONTEND_DESCRIPTION: ${FRONTEND_DESCRIPTION:-}
70
71 FRONTEND_FQDN_URL: https://${DOMAIN_NAME}
72
73 ENABLE_RAW_OUTPUT: ${ENABLE_RAW_OUTPUT:-}
74 deploy:
75 mode: replicated
76 replicas: 3
77 volumes:
78 - ./packages/backend/uploads:/app/packages/backend/uploads
79 - ./packages/backend/cache:/app/packages/backend/cache
80 - frontend:/app/packages/frontend:ro
81
82 migration:
83 <<: *default_backend
84 depends_on:
85 db:
86 condition: service_healthy
87 redis:
88 condition: service_started
89 frontend:
90 condition: service_started
91 restart: no
92 deploy:
93 mode: replicated
94 replicas: 1
95 command: "npm exec tsx migrate.ts init-container"
96
97 frontend:
98 restart: unless-stopped
99 build:
100 context: .
101 dockerfile: packages/frontend/Dockerfile
102 ports:
103 - 80:80
104 - 443:443
105 environment:
106 DOMAIN_NAME: ${DOMAIN_NAME}
107 PDS_DOMAIN_NAME: ${PDS_DOMAIN_NAME}
108 CACHE_DOMAIN: ${CACHE_DOMAIN}
109 MEDIA_DOMAIN: ${MEDIA_DOMAIN}
110 ACME_EMAIL: ${ACME_EMAIL}
111 FRONTEND_SHORT_TITLE: ${FRONTEND_SHORT_TITLE:-}
112 FRONTEND_LONG_TITLE: ${FRONTEND_LONG_TITLE:-}
113 FRONTEND_DESCRIPTION: ${FRONTEND_DESCRIPTION:-}
114 CACHE_HOST: "cache:9000"
115 BACKEND_HOST: "wafrn-backend-1:9000 wafrn-backend-2:9000 wafrn-backend-3:9000"
116 WEBSOCKET_HOST: "wafrn-websocket-1:9000"
117
118 volumes:
119 - "caddy:/data"
120 - "frontend:/var/www/html/frontend"
121 - ./packages/backend/uploads:/var/www/html/uploads
122 - ./packages/caddy:/etc/caddy/config
123
124 db:
125 build:
126 context: monitoring/database
127 dockerfile: Dockerfile
128 restart: unless-stopped
129 shm_size: '2gb'
130 environment:
131 POSTGRES_USER: ${POSTGRES_USER}
132 POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
133 POSTGRES_DB: ${POSTGRES_DBNAME}
134 POSTGRES_METRICS_USER: ${POSTGRES_METRICS_USER}
135 POSTGRES_METRICS_PASSWORD: ${POSTGRES_METRICS_PASSWORD}
136 POSTGRES_METRICS_DBNAME: ${POSTGRES_METRICS_DBNAME}
137 volumes:
138 - dbpg:/var/lib/postgresql/data
139
140 adminer:
141 image: adminer
142 restart: unless-stopped
143
144 redis:
145 image: redis:7.2.4
146 restart: unless-stopped
147 volumes:
148 - redis:/data
149
150 pds:
151 image: ghcr.io/bluesky-social/pds:0.4
152 restart: unless-stopped
153 profiles:
154 - bluesky
155 environment:
156 PDS_HOSTNAME: ${PDS_DOMAIN_NAME}
157 PDS_JWT_SECRET: ${PDS_JWT_SECRET}
158 PDS_ADMIN_PASSWORD: ${PDS_ADMIN_PASSWORD}
159 PDS_PLC_ROTATION_KEY_K256_PRIVATE_KEY_HEX: ${PDS_PLC_ROTATION_KEY_K256_PRIVATE_KEY_HEX}
160 PDS_DATA_DIRECTORY: /pds
161 PDS_BLOBSTORE_DISK_LOCATION: /pds/blocks
162 PDS_BLOB_UPLOAD_LIMIT: 52428800
163 PDS_DID_PLC_URL: "https://plc.directory"
164 PDS_BSKY_APP_VIEW_URL: "https://api.bsky.app"
165 PDS_BSKY_APP_VIEW_DID: "did:web:api.bsky.app"
166 PDS_REPORT_SERVICE_URL: "https://mod.bsky.app"
167 PDS_REPORT_SERVICE_DID: "did:plc:ar7c4by46qjdydhdevvrndac"
168 PDS_CRAWLERS: "https://bsky.network, https://atproto.africa"
169 PDS_EMAIL_SMTP_URL: "smtp://${SMTP_USER}:${SMTP_PASSWORD}@${SMTP_HOST}:${SMTP_PORT}"
170 PDS_EMAIL_FROM_ADDRESS: "${SMTP_FROM}"
171 LOG_ENABLED: true
172 volumes:
173 - pds:/pds
174
175 pds_worker:
176 <<: *default_backend
177 deploy:
178 mode: replicated
179 replicas: 1
180 profiles:
181 - bluesky
182 command: "npm exec tsx atproto.ts"
183
184 cache:
185 <<: *default_backend
186 deploy:
187 mode: replicated
188 replicas: 1
189 websocket:
190 <<: *default_backend
191 deploy:
192 mode: replicated
193 replicas: 1
194 command: "npm exec tsx websocket.ts"
195
196 workers:
197 <<: *default_backend
198 build:
199 <<: *default_backend_build
200 environment:
201 <<: *default_backend_env_vars
202 USE_WORKERS: true
203 deploy:
204 mode: replicated
205 replicas: 3
206
207 prometheus:
208 restart: unless-stopped
209 image: prom/prometheus:latest
210 volumes:
211 - ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml
212 - prometheus_data:/prometheus
213 command:
214 - '--config.file=/etc/prometheus/prometheus.yml'
215 - '--storage.tsdb.path=/prometheus'
216 - '--web.console.libraries=/usr/share/prometheus/console_libraries'
217 - '--web.console.templates=/usr/share/prometheus/consoles'
218
219 cadvisor:
220 restart: unless-stopped
221 image: gcr.io/cadvisor/cadvisor:latest
222 command:
223 - '-port=8081'
224 environment:
225 CADVISOR_HEALTHCHECK_URL: http://localhost:8081/healthz
226 volumes:
227 - /:/rootfs:ro
228 - /var/run:/var/run:rw
229 - /sys:/sys:ro
230 - /var/lib/docker/:/var/lib/docker:ro
231
232 node-exporter:
233 restart: unless-stopped
234 image: prom/node-exporter:latest
235 volumes:
236 - /proc:/host/proc:ro
237 - /sys:/host/sys:ro
238 - /:/rootfs:ro
239 command:
240 - '--path.procfs=/host/proc'
241 - '--path.sysfs=/host/sys'
242 - '--collector.filesystem.ignored-mount-points="^/(sys|proc|dev|host|etc)($$|/)"'
243
244 grafana:
245 build:
246 context: monitoring/grafana
247 dockerfile: Dockerfile
248 volumes:
249 - grafana_data:/var/lib/grafana
250 restart: unless-stopped
251 environment:
252 GF_SERVER_HTTP_PORT: 2345
253 GF_SECURITY_ADMIN_PASSWORD: ${GF_SECURITY_ADMIN_PASSWORD}
254 GF_USERS_ALLOW_SIGN_UP: false
255
256 GF_SMTP_ENABLED: true
257 GF_SMTP_HOST: ${SMTP_HOST}:${SMTP_PORT}
258 GF_SMTP_FROM_ADDRESS: ${SMTP_FROM}
259 GF_SERVER_DOMAIN: ${DOMAIN_NAME}
260 GF_SMTP_FROM_NAME: ${SMTP_FROM}
261 GF_SMTP_USER: "${SMTP_USER}"
262 GF_SMTP_PASSWORD: "${SMTP_PASSWORD}"
263
264 POSTGRES_METRICS_USER: ${POSTGRES_METRICS_USER}
265 POSTGRES_METRICS_PASSWORD: ${POSTGRES_METRICS_PASSWORD}
266 POSTGRES_METRICS_DBNAME: ${POSTGRES_METRICS_DBNAME}
267
268 pgwatch:
269 build:
270 context: monitoring/pgwatch
271 dockerfile: Dockerfile
272 args:
273 POSTGRES_USER: ${POSTGRES_USER}
274 POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
275 POSTGRES_DB: ${POSTGRES_DBNAME}
276 restart: unless-stopped
277 environment:
278 POSTGRES_METRICS_USER: ${POSTGRES_METRICS_USER}
279 POSTGRES_METRICS_PASSWORD: ${POSTGRES_METRICS_PASSWORD}
280 POSTGRES_METRICS_DBNAME: ${POSTGRES_METRICS_DBNAME}
281 command:
282 - "--web-disable=all"
283 - "--sources=/sources.yaml"
284 - "--sink=postgresql://${POSTGRES_METRICS_USER}:${POSTGRES_METRICS_PASSWORD}@db:5432/${POSTGRES_METRICS_DBNAME}"
285 depends_on:
286 db:
287 condition: service_healthy
288
289volumes:
290 dbpg:
291 caddy:
292 pds:
293 frontend:
294 redis:
295 prometheus_data:
296 grafana_data: