Wrapper-Frontend vor cryptgeon: der Browser verschluesselt lokal, per Mail geht nur der Link raus. Fuer das Deployment nach den Konventionen aus DEPLOY.md hergerichtet: - docker-compose.yml mit festem Projekt- und Container-Namen, kein ports-Mapping, Healthcheck als Deploy-Gate. cryptgeon und redis liegen im internen Netz, nur app haengt im Web-Netz. - cryptgeon von latest auf 2.9.3 gepinnt. Das ist derselbe Stand, den latest bisher geliefert hat; 2.6.2 existiert nicht. - /healthz in server.js, vor dem Catch-all-Proxy registriert. - Dockerfile auf npm ci mit Lockfile und non-root umgestellt. - .gitea/workflows/deploy.yml: Build und Syntaxpruefung vor dem Deploy, .env aus dem Repo-Secret DOTENV. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
71 lines
2.4 KiB
YAML
71 lines
2.4 KiB
YAML
# Fester Projektname. Ohne das leitet Compose ihn aus dem Verzeichnisnamen
|
|
# ab - und der ist im CI-Job ein anderer als auf dem Host.
|
|
name: sendsecret
|
|
|
|
services:
|
|
# Der Wrapper: eigenes Frontend, Mailversand, Proxy auf cryptgeon.
|
|
# Das ist der einzige Dienst, den der Nginx Proxy Manager sieht.
|
|
app:
|
|
# Versionstag ermoeglicht Rollback ohne Rebuild.
|
|
image: sendsecret:${IMAGE_TAG:-latest}
|
|
build: ./app
|
|
# Fester Name: das ist die Adresse, auf die der Proxy zeigt.
|
|
container_name: sendsecret
|
|
restart: unless-stopped
|
|
# Wird im Workflow aus dem Secret DOTENV erzeugt.
|
|
env_file: .env
|
|
depends_on:
|
|
- cryptgeon
|
|
networks:
|
|
- nginx-proxy-manager_default
|
|
- internal
|
|
# Pflicht: der Deploy-Schritt nutzt --wait und macht das zum Gate.
|
|
# Abweichung von den 60s der Vorlage: bei --wait-timeout 180 reicht ein
|
|
# 60s-Intervall nur fuer drei Versuche - der Deploy wuerde beim ersten
|
|
# Fehlschlag knapp.
|
|
healthcheck:
|
|
test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:3000/healthz').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"]
|
|
interval: 15s
|
|
timeout: 5s
|
|
retries: 3
|
|
start_period: 10s
|
|
|
|
# Cryptgeon haelt die verschluesselten Notizen. Version gepinnt: die
|
|
# Frontend-Bundles verschluesseln mit occulto 2.0.6 gegen dieses API-Format.
|
|
cryptgeon:
|
|
image: cupcakearmy/cryptgeon:2.9.3
|
|
container_name: sendsecret-cryptgeon
|
|
restart: unless-stopped
|
|
depends_on:
|
|
redis:
|
|
condition: service_healthy
|
|
environment:
|
|
REDIS_URL: redis://redis/
|
|
ALLOW_ADVANCED: 'false'
|
|
# Bewusst nicht im Web-Netz: erreichbar nur ueber den Proxy in app.
|
|
networks:
|
|
- internal
|
|
|
|
# Reiner Zwischenspeicher, ohne Persistenz - Notizen sind einmalig
|
|
# abrufbar und sollen einen Neustart nicht ueberleben. Deshalb kein Volume.
|
|
redis:
|
|
image: redis:7-alpine
|
|
command: redis-server --save "" --appendonly no
|
|
container_name: sendsecret-redis
|
|
restart: unless-stopped
|
|
networks:
|
|
- internal
|
|
healthcheck:
|
|
test: ["CMD", "redis-cli", "ping"]
|
|
interval: 10s
|
|
timeout: 3s
|
|
retries: 5
|
|
|
|
# Kein ports-Mapping: Der Proxy erreicht app ueber das gemeinsame Netz unter
|
|
# dem Container-Namen. cryptgeon und redis haengen nur im internen Netz.
|
|
networks:
|
|
nginx-proxy-manager_default:
|
|
external: true
|
|
internal:
|
|
name: sendsecret-internal
|