From dfa92ed6658fa05916b9d6ec47096f99b2eb483d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=BChn?= Date: Tue, 25 Aug 2026 10:58:11 +0200 Subject: [PATCH] Add docker-compose.stack.yml for Dockhand/Portainer deployment --- docker-compose.stack.yml | 93 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 docker-compose.stack.yml diff --git a/docker-compose.stack.yml b/docker-compose.stack.yml new file mode 100644 index 0000000..86f68e2 --- /dev/null +++ b/docker-compose.stack.yml @@ -0,0 +1,93 @@ +# ============================================================ +# Dockhand / Portainer Stack File +# Verwendet das vorgebaute Image aus der Gitea-Registry. +# Vor dem Deploy: .env Datei im Stack-Verzeichnis ablegen! +# ============================================================ + +services: + app: + image: gitea.leonkn.de/lxe/workflow-app:DEV1.0 + ports: + - "5000:5000" + volumes: + - app-data:/app/data + environment: + - LDAP_SERVER=${LDAP_SERVER:-} + - LDAP_PORT=${LDAP_PORT:-389} + - LDAP_SEARCH_BASE=${LDAP_SEARCH_BASE:-} + - LDAP_DOMAIN=${LDAP_DOMAIN:-} + - LDAP_IGNORE_CERT_ERRORS=${LDAP_IGNORE_CERT_ERRORS:-false} + - LDAP_BIND_USER=${LDAP_BIND_USER:-} + - LDAP_BIND_PASSWORD=${LDAP_BIND_PASSWORD:-} + - LDAP_SYNC_INTERVAL=${LDAP_SYNC_INTERVAL:-300000} + - LDAP_FILTER=${LDAP_FILTER:-} + - LDAP_ATTRIBUTES=${LDAP_ATTRIBUTES:-mail,displayName,memberOf,distinguishedName,sAMAccountName} + - LDAP_CREATE_OU=${LDAP_CREATE_OU:-} + - LDAP_UPN_SUFFIX=${LDAP_UPN_SUFFIX:-} + - ADMIN_EMAIL=${ADMIN_EMAIL:-admin@workflow.local} + - ADMIN_INIT_PASSWORD=${ADMIN_INIT_PASSWORD:-} + - CORS_ORIGIN=${CORS_ORIGIN:-http://localhost:5000} + - NODE_ENV=${NODE_ENV:-production} + - DATABASE_URL=postgresql://${POSTGRES_USER:-workflow}:${POSTGRES_PASSWORD:-workflow}@db:5432/${POSTGRES_DB:-workflow} + - SESSION_MAX_PER_USER=${SESSION_MAX_PER_USER:-5} + - SESSION_TTL_HOURS=${SESSION_TTL_HOURS:-168} + - LOGIN_MAX_ATTEMPTS=${LOGIN_MAX_ATTEMPTS:-5} + - LOGIN_LOCKOUT_MINUTES=${LOGIN_LOCKOUT_MINUTES:-15} + - BODY_LIMIT=${BODY_LIMIT:-1mb} + depends_on: + db: + condition: service_healthy + restart: unless-stopped + + db: + image: postgres:16-alpine + environment: + - POSTGRES_DB=${POSTGRES_DB:-workflow} + - POSTGRES_USER=${POSTGRES_USER:-workflow} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-workflow} + volumes: + - pgdata:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-workflow} -d ${POSTGRES_DB:-workflow}"] + interval: 10s + timeout: 5s + retries: 5 + restart: unless-stopped + + db-backup: + image: postgres:16-alpine + environment: + - POSTGRES_USER=${POSTGRES_USER:-workflow} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-workflow} + - POSTGRES_DB=${POSTGRES_DB:-workflow} + - BACKUP_INTERVAL_HOURS=${BACKUP_INTERVAL_HOURS:-6} + - BACKUP_RETENTION_DAYS=${BACKUP_RETENTION_DAYS:-30} + - PGHOST=db + - PGUSER=${POSTGRES_USER:-workflow} + - PGPASSWORD=${POSTGRES_PASSWORD:-workflow} + volumes: + - backups:/backups + entrypoint: | + /bin/sh -c " + echo '[Backup] Starting backup service (interval: '$$BACKUP_INTERVAL_HOURS'h, retention: '$$BACKUP_RETENTION_DAYS'd)'; + while true; do + TIMESTAMP=$$(date +%Y%m%d_%H%M%S); + FILENAME=/backups/workflow_$$TIMESTAMP.sql.gz; + echo '[Backup] Creating backup: '$$FILENAME; + pg_dump -h db -U $$PGUSER $$POSTGRES_DB | gzip > $$FILENAME; + echo '[Backup] Done: '$$FILENAME; + find /backups -name 'workflow_*.sql.gz' -mtime +$$BACKUP_RETENTION_DAYS -delete; + echo '[Backup] Cleaned old backups (older than '$$BACKUP_RETENTION_DAYS' days)'; + SLEEP_SECONDS=$$((BACKUP_INTERVAL_HOURS * 3600)); + sleep $$SLEEP_SECONDS; + done + " + depends_on: + db: + condition: service_healthy + restart: unless-stopped + +volumes: + pgdata: + app-data: + backups: \ No newline at end of file