Files
AirCardIOS/deploy/compose-snippet.yml
T
ClaudeandClaude Sonnet 5.5 f6b9917b07 docs: Scope-Namen der Console (documents.*), sicherer .env-Befehl, X-Real-Ip-Risiko
- Der Key aircard-api braucht in der Console documents.read/documents.write (entspricht rows.* der API) sowie files.read/files.write.
- Der Befehl zum Eintragen des Keys nutzt read -rs, schreibt bei leerer Eingabe nichts und beginnt mit einem Zeilenumbruch
  (klebt nie an einer letzten .env-Zeile ohne Umbruch); Hinweis zum Zeilenumbruch auch bei der Eingabe mit nano.
- deploy/README.md: nginx-503 bei fehlendem Dienst, up -d nach .env-Änderung, X-Real-Ip im Docker-Netz als akzeptiertes Risiko.
- Kommentare in server.js und compose-snippet.yml angepasst.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 16:40:17 +00:00

128 lines
6.0 KiB
YAML

# ==============================================
# AIRCARD-IOS.ORG - Automatisches Deployment aus Gitea
# URL: aircard-ios.org
# Repository: https://git.webklar.com/knso/AirCardIOS
# Einfügen unter `services:` direkt nach dem eship-Block (siehe deploy/README.md).
# Starten NUR mit: docker compose up -d aircard-build aircard aircard-api
# (ein nacktes `up -d` würde andere Dienste wieder anlegen)
# Die Appwrite-Route liegt als Datei in traefik/dynamic/aircard.yml (Router `aircard-api@file`, Pfad /v1).
# Der API-Dienst `aircard-api` hängt per Label am Pfad /api (Router `aircard-gallery-api`, ein anderer Name,
# damit er nicht mit der Datei-Route kollidiert).
# AIRCARD_APPWRITE_PROJECT_ID, AIRCARD_API_KEY und AIRCARD_API_SALT kommen aus /home/webklar/apps/.env.
# ==============================================
aircard-build:
image: node:22-alpine
container_name: webklar-aircard-build
restart: unless-stopped
init: true
mem_limit: 768m
working_dir: /app
environment:
- GITEA_URL=https://git.webklar.com
- GITEA_USER=knso
- GITEA_REPO=AirCardIOS
- GITEA_TOKEN=${GITEA_DEPLOY_TOKEN}
- APP_SUBDIR=web
- DEPLOY_BRANCH=main
- AIRCARD_DEPLOY_BRANCH=main
- AIRCARD_WEBHOOK_TOKEN=${GITEA_DEPLOY_WEBHOOK_SECRET}
- AIRCARD_WEBHOOK_PORT=8087
- AIRCARD_DEPLOY_SCRIPT=/deploy.sh
- POLL_INTERVAL_MINUTES=15
- NODE_OPTIONS=--max-old-space-size=512
- VITE_APPWRITE_ENDPOINT=https://aircard-ios.org/v1
- VITE_APPWRITE_PROJECT_ID=${AIRCARD_APPWRITE_PROJECT_ID}
volumes:
- ./aircard-ios.org/build:/app
- ./aircard-ios.org/out:/out
- ./aircard-ios.org/deploy.sh:/deploy.sh:ro
- ./aircard-ios.org/webhook-server.js:/webhook/server.js:ro
networks:
- webklar-network
command: /bin/sh -c "apk add --no-cache git && node /webhook/server.js"
labels:
- "traefik.enable=true"
- "traefik.http.routers.aircard-webhook.rule=Host(`aircard-ios.org`) && Path(`/webhook/deploy`)"
- "traefik.http.routers.aircard-webhook.entrypoints=websecure"
- "traefik.http.routers.aircard-webhook.tls.certresolver=letsencrypt"
- "traefik.http.routers.aircard-webhook.priority=200"
- "traefik.http.services.aircard-webhook.loadbalancer.server.port=8087"
aircard:
image: nginx:alpine
container_name: webklar-aircard
restart: unless-stopped
mem_limit: 64m
volumes:
- ./aircard-ios.org/out:/usr/share/nginx/html:ro
- ./aircard-ios.org/nginx/aircard-ios.org.conf:/etc/nginx/conf.d/default.conf:ro
networks:
- webklar-network
labels:
- "traefik.enable=true"
- "traefik.http.routers.aircard.rule=Host(`aircard-ios.org`)"
- "traefik.http.routers.aircard.entrypoints=websecure"
- "traefik.http.routers.aircard.tls.certresolver=letsencrypt"
- "traefik.http.services.aircard.loadbalancer.server.port=80"
- "traefik.http.middlewares.aircard-https.redirectscheme.scheme=https"
- "traefik.http.middlewares.aircard-https.redirectscheme.permanent=true"
- "traefik.http.routers.aircard-http.rule=Host(`aircard-ios.org`)"
- "traefik.http.routers.aircard-http.entrypoints=web"
- "traefik.http.routers.aircard-http.middlewares=aircard-https"
# --- www (Step 10): erst einkommentieren, wenn www.aircard-ios.org per DNS auf 91.99.156.85 zeigt.
# Eigene Router, damit ein www-Fehler (Zertifikat) die Hauptdomain nicht blockiert.
# `$$` ist das Escape für ein einzelnes `$` in docker compose; `\\.` ergibt im YAML ein `\.`.
# - "traefik.http.routers.aircard-www.rule=Host(`www.aircard-ios.org`)"
# - "traefik.http.routers.aircard-www.entrypoints=websecure"
# - "traefik.http.routers.aircard-www.tls.certresolver=letsencrypt"
# - "traefik.http.routers.aircard-www.middlewares=aircard-www"
# - "traefik.http.routers.aircard-www-http.rule=Host(`www.aircard-ios.org`)"
# - "traefik.http.routers.aircard-www-http.entrypoints=web"
# - "traefik.http.routers.aircard-www-http.middlewares=aircard-www"
# - "traefik.http.middlewares.aircard-www.redirectregex.regex=^https?://www\\.aircard-ios\\.org(.*)"
# - "traefik.http.middlewares.aircard-www.redirectregex.replacement=https://aircard-ios.org$${1}"
# - "traefik.http.middlewares.aircard-www.redirectregex.permanent=true"
# --- API-Dienst der Community-Galerie (deploy/api/, siehe deploy/api/README.md) ---
# Ohne AIRCARD_API_KEY oder AIRCARD_API_SALT in der .env beendet sich der Dienst mit Exit-Code 1.
# Kein `ports:` (veröffentlicht wird der Dienst nur über Traefik). Im Docker-Netz erreichen ihn andere Container, und er
# vertraut dort dem Header X-Real-Ip: akzeptiertes Risiko, siehe deploy/api/README.md (Client-IP).
aircard-api:
image: node:22-alpine
container_name: webklar-aircard-api
restart: unless-stopped
init: true
mem_limit: 128m
user: node
read_only: true
cap_drop:
- ALL
security_opt:
- no-new-privileges:true
working_dir: /srv
# Log-Größe deckeln: /api/melden ist ohne Anmeldung erreichbar, der Docker-Daemon hat keine eigenen Log-Grenzen.
logging:
driver: json-file
options:
max-size: "5m"
max-file: "2"
environment:
- AIRCARD_API_PORT=8088
- AIRCARD_APPWRITE_ENDPOINT=http://webklar-appwrite/v1
- AIRCARD_APPWRITE_PROJECT_ID=${AIRCARD_APPWRITE_PROJECT_ID}
- AIRCARD_API_KEY=${AIRCARD_API_KEY}
- AIRCARD_API_SALT=${AIRCARD_API_SALT}
- NODE_OPTIONS=--max-old-space-size=64
volumes:
- ./aircard-ios.org/api:/srv:ro
networks:
- webklar-network
command: node /srv/server.js
labels:
- "traefik.enable=true"
- "traefik.http.routers.aircard-gallery-api.rule=Host(`aircard-ios.org`) && PathPrefix(`/api`)"
- "traefik.http.routers.aircard-gallery-api.entrypoints=websecure"
- "traefik.http.routers.aircard-gallery-api.tls.certresolver=letsencrypt"
- "traefik.http.routers.aircard-gallery-api.priority=200"
- "traefik.http.services.aircard-gallery-api.loadbalancer.server.port=8088"