-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdocker-compose.yml
More file actions
282 lines (266 loc) · 10.6 KB
/
Copy pathdocker-compose.yml
File metadata and controls
282 lines (266 loc) · 10.6 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
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
services:
# Cryptify for filesharing
cryptify-fileshare:
build:
context: cryptify
dockerfile: dev.Dockerfile
healthcheck:
test: ['CMD', 'curl', '-f', 'http://localhost:8000/health']
interval: 1m30s
timeout: 10s
retries: 3
start_interval: 1s
start_period: 30s
ports:
- '8000:8000'
volumes:
- cryptify-data:/app/data
- ./cryptify/conf/config.dev.toml:/app/config.toml:ro
- ./cryptify/src:/app/src
- ./cryptify/templates:/app/templates
# build.rs feeds `PG_CORE_VERSION` (used by the X-PostGuard
# mail header) from Cargo.lock at compile time. Both files
# need to be visible inside the container, or cargo bails
# on `env!("PG_CORE_VERSION")`.
- ./cryptify/build.rs:/app/build.rs:ro
- ./cryptify/Cargo.lock:/app/Cargo.lock:ro
- cryptify-target:/app/target
environment:
- RUST_LOG=info
- ROCKET_CONFIG=/app/config.toml
- RUST_BACKTRACE=1
networks:
- postguard
depends_on:
postguard-pkg:
condition: service_healthy
# PKG service (Private Key Generator)
postguard-pkg:
build:
context: postguard
dockerfile: dev.Dockerfile
healthcheck:
test: ['CMD', 'curl', '-f', 'http://localhost:8087/health']
interval: 1m30s
timeout: 5s
retries: 3
start_interval: 1s
start_period: 30s
ports:
- '8087:8087'
volumes:
- ./postguard:/app
- postguard-pkg-target:/app/target
environment:
- RUST_LOG=debug
- RUST_BACKTRACE=1
- IRMA_SERVER=http://irma-server:8088
networks:
- postguard
depends_on:
- irma-server
# IRMA/Yivi server (unauthenticated, for development only)
irma-server:
image: ghcr.io/privacybydesign/irma:latest
command: server --no-auth -v --url http://localhost:8088 --jwt-privkey-file /etc/irma/jwt_privkey.pem
ports:
- '8088:8088'
volumes:
- ./docker/irma/jwt_privkey.pem:/etc/irma/jwt_privkey.pem:ro
networks:
- postguard
# Email testing tool
mailcrab:
image: marlonb/mailcrab:latest
ports:
- '1080:1080' # Web UI
- '1025:1025' # SMTP
networks:
- postguard
# PostGuard website - Development with hot reload
postguard-website:
build:
context: .
dockerfile: docker/dev.Dockerfile
volumes:
- .:/app
- /app/node_modules
- /app/.svelte-kit
env_file:
- .env.dev
environment:
- NODE_ENV=development
networks:
- postguard
# GlitchTip — open-source, Sentry-compatible error tracker.
# Reports posted by the website's CrashReport button land here.
# UI at http://localhost:8000 (override via GLITCHTIP_PORT if 8000 is taken).
# On first boot, create an account and a project; the DSN goes into
# APP_CONFIG.GLITCHTIP_DSN (see src/lib/env.ts).
glitchtip-postgres:
image: postgres:16-alpine
environment:
- POSTGRES_HOST_AUTH_METHOD=trust
- POSTGRES_DB=glitchtip
volumes:
- glitchtip-pg:/var/lib/postgresql/data
networks:
- postguard
glitchtip-redis:
image: valkey/valkey:8-alpine
networks:
- postguard
glitchtip-web:
image: glitchtip/glitchtip:v5
depends_on:
- glitchtip-postgres
- glitchtip-redis
environment:
- DATABASE_URL=postgres://postgres@glitchtip-postgres:5432/glitchtip
- REDIS_URL=redis://glitchtip-redis:6379/0
- SECRET_KEY=${GLITCHTIP_SECRET_KEY:-dev-only-change-me}
- PORT=8001
- DEFAULT_FROM_EMAIL=noreply@postguard.local
- GLITCHTIP_DOMAIN=http://localhost:8001
- ENABLE_OPEN_USER_REGISTRATION=true
ports:
- '8001:8001'
volumes:
- glitchtip-uploads:/code/uploads
networks:
- postguard
glitchtip-worker:
image: glitchtip/glitchtip:v5
command: ./bin/run-celery-with-beat.sh
# `glitchtip-web` runs Django migrations on startup. Without
# depending on it, the worker's celery-beat starts firing
# scheduled jobs (uptime-dispatch-checks etc.) before the
# tables exist and crashes with `relation "uptime_monitor"
# does not exist`. The web container has no healthcheck, so
# this is a `service_started` ordering rather than a true
# readiness gate — good enough on a single host where the
# web container reaches Postgres in a few seconds.
depends_on:
- glitchtip-postgres
- glitchtip-redis
- glitchtip-web
- glitchtip-init
environment:
- DATABASE_URL=postgres://postgres@glitchtip-postgres:5432/glitchtip
- REDIS_URL=redis://glitchtip-redis:6379/0
- SECRET_KEY=${GLITCHTIP_SECRET_KEY:-dev-only-change-me}
volumes:
- glitchtip-uploads:/code/uploads
networks:
- postguard
# One-shot: applies migrations and creates the dev superuser if it
# doesn't already exist. Runs to completion and exits. Idempotent —
# `createsuperuser --noinput` errors on a duplicate, which we
# swallow so subsequent `up`s remain no-ops. Override credentials
# by exporting GLITCHTIP_ADMIN_EMAIL / GLITCHTIP_ADMIN_PASSWORD.
glitchtip-init:
image: glitchtip/glitchtip:v5
depends_on:
- glitchtip-postgres
environment:
- DATABASE_URL=postgres://postgres@glitchtip-postgres:5432/glitchtip
- REDIS_URL=redis://glitchtip-redis:6379/0
- SECRET_KEY=${GLITCHTIP_SECRET_KEY:-dev-only-change-me}
# python-email-validator (used by GlitchTip's Pydantic response
# schemas) rejects `local`, `localhost`, `test`, `invalid`,
# `arpa`, `onion` TLDs as special-use — so `/api/0/users/me/`
# 500s if the superuser email lands on one of those. `.dev` is
# a real public TLD and not on that list.
- DJANGO_SUPERUSER_EMAIL=${GLITCHTIP_ADMIN_EMAIL:-admin@postguard.dev}
- DJANGO_SUPERUSER_PASSWORD=${GLITCHTIP_ADMIN_PASSWORD:-devpass1}
# Bootstraps: migrations → superuser → PostGuard org → website
# project → prints the DSN. Each step is idempotent so subsequent
# `up`s remain no-ops. Paste the printed DSN into static/config.js
# under `APP_CONFIG.GLITCHTIP_DSN` (or set `GLITCHTIP_DSN=…` in
# .env.dev) — the DSN is stable as long as the postgres volume
# survives, so this is a one-time copy.
command:
- sh
- -c
- |
./manage.py migrate --noinput &&
(./manage.py createsuperuser --noinput 2>/dev/null \
&& echo 'glitchtip-init: superuser created' \
|| echo 'glitchtip-init: superuser already exists') &&
./manage.py shell -c "
from django.apps import apps
from django.contrib.auth import get_user_model
Organization = apps.get_model('organizations_ext', 'Organization')
Project = apps.get_model('projects', 'Project')
ProjectKey = apps.get_model('projects', 'ProjectKey')
user = get_user_model().objects.get(email='$$DJANGO_SUPERUSER_EMAIL')
org, org_created = Organization.objects.get_or_create(
slug='postguard',
defaults={'name': 'PostGuard'},
)
if org_created:
org.add_user(user)
print('glitchtip-init: org PostGuard created')
else:
print('glitchtip-init: org PostGuard already exists')
project, proj_created = Project.objects.get_or_create(
organization=org,
slug='postguard-website',
defaults={'name': 'postguard-website', 'platform': 'javascript'},
)
if proj_created:
print('glitchtip-init: project postguard-website created')
else:
print('glitchtip-init: project postguard-website already exists')
# Pin a deterministic public_key so the DSN survives a
# full volume wipe. Without this, a fresh postgres volume
# regenerates the UUID and any hardcoded DSN in
# static/config.js silently goes stale.
#
# GlitchTip auto-creates a default ProjectKey when a
# Project is saved, so on a fresh volume the get_or_create
# below returns that auto-created key (key_created=False)
# and the defaults= clause is ignored. The `not key_created`
# branch catches that case and rewrites public_key to
# DEV_KEY.
import uuid
DEV_KEY = uuid.UUID('1d8ea2a49c904f079b116550780c0ece')
key, key_created = ProjectKey.objects.get_or_create(
project=project,
defaults={'public_key': DEV_KEY},
)
if not key_created and key.public_key != DEV_KEY:
key.public_key = DEV_KEY
key.save()
dsn = f'http://{key.public_key.hex}@localhost:8001/{project.id}'
print('========================================')
print('glitchtip-init: DSN (already set in static/config.js):')
print(f' {dsn}')
print('========================================')
"
restart: 'no'
networks:
- postguard
# Nginx reverse proxy
nginx:
image: nginx:alpine
ports:
- '8080:80'
volumes:
- ./docker/nginx.dev.conf:/etc/nginx/nginx.conf:ro
networks:
- postguard
depends_on:
- postguard-website
- cryptify-fileshare
- postguard-pkg
- irma-server
networks:
postguard:
driver: bridge
volumes:
cryptify-data:
cryptify-target:
postguard-pkg-target:
glitchtip-pg:
glitchtip-uploads: