pvm/docker/docker-compose.dev.yml
Mikkel Georgsen 28a827efa1 Add custom login UI replacing Zitadel built-in login pages
Replace Zitadel's built-in login v1 with a fully custom SvelteKit-based
login experience using Zitadel Session API v2. Keeps the existing OIDC
authorization code flow (Auth.js handles token exchange) while providing
branded login, signup, password reset, and TOTP pages.

- Enable Login V2 in docker-compose, assign IAM_LOGIN_CLIENT role in setup script
- Add server-only Zitadel API client ($lib/server/zitadel.ts) with session,
  user, and auth-request management functions
- Create reusable auth UI components (AuthCard, FormField, FormError, LoadingButton)
- Rewrite login page with email/password form and TOTP second factor support
- Add signup page with auto-login after registration
- Add password reset flow (request + verify pages)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 13:54:01 +01:00

97 lines
3.4 KiB
YAML

services:
zitadel:
image: ghcr.io/zitadel/zitadel:latest
command: start-from-init --masterkey "${ZITADEL_MASTERKEY}" --tlsMode disabled
user: "0"
environment:
ZITADEL_DATABASE_POSTGRES_HOST: zitadel-db
ZITADEL_DATABASE_POSTGRES_PORT: 5432
ZITADEL_DATABASE_POSTGRES_DATABASE: zitadel
ZITADEL_DATABASE_POSTGRES_USER_USERNAME: zitadel
ZITADEL_DATABASE_POSTGRES_USER_PASSWORD: "${ZITADEL_DB_PASSWORD}"
ZITADEL_DATABASE_POSTGRES_USER_SSL_MODE: disable
ZITADEL_DATABASE_POSTGRES_ADMIN_USERNAME: zitadel
ZITADEL_DATABASE_POSTGRES_ADMIN_PASSWORD: "${ZITADEL_DB_PASSWORD}"
ZITADEL_DATABASE_POSTGRES_ADMIN_SSL_MODE: disable
ZITADEL_EXTERNALDOMAIN: localhost
ZITADEL_EXTERNALPORT: 8080
ZITADEL_EXTERNALSECURE: "false"
ZITADEL_TLS_MODE: disabled
ZITADEL_FIRSTINSTANCE_ORG_HUMAN_USERNAME: admin
ZITADEL_FIRSTINSTANCE_ORG_HUMAN_PASSWORD: "${ZITADEL_ADMIN_PASSWORD}"
ZITADEL_DEFAULTINSTANCE_FEATURES_LOGINV2_REQUIRED: "true"
ZITADEL_DEFAULTINSTANCE_LOGINV2_BASEURI: "http://localhost:5173"
# Machine user for automated setup (PAT written to bind mount)
ZITADEL_FIRSTINSTANCE_ORG_MACHINE_MACHINE_USERNAME: pvm-setup
ZITADEL_FIRSTINSTANCE_ORG_MACHINE_MACHINE_NAME: PVM Setup Service User
ZITADEL_FIRSTINSTANCE_ORG_MACHINE_PAT_EXPIRATIONDATE: "2030-01-01T00:00:00Z"
ZITADEL_FIRSTINSTANCE_PATPATH: /machinekey/admin.pat
# SMTP for email sending (verification, password reset)
ZITADEL_DEFAULTINSTANCE_SMTPCONFIGURATION_SMTP_HOST: "${ZITADEL_SMTP_HOST}:465"
ZITADEL_DEFAULTINSTANCE_SMTPCONFIGURATION_SMTP_USER: "${ZITADEL_SMTP_USER}"
ZITADEL_DEFAULTINSTANCE_SMTPCONFIGURATION_SMTP_PASSWORD: "${ZITADEL_SMTP_PASSWORD}"
ZITADEL_DEFAULTINSTANCE_SMTPCONFIGURATION_TLS: "true"
ZITADEL_DEFAULTINSTANCE_SMTPCONFIGURATION_FROM: "${ZITADEL_SMTP_USER}"
ZITADEL_DEFAULTINSTANCE_SMTPCONFIGURATION_FROMNAME: "PVM"
ports:
- "8080:8080"
depends_on:
zitadel-db:
condition: service_healthy
volumes:
- ./machinekey:/machinekey
- ./zitadel-healthcheck.yaml:/zitadel-healthcheck.yaml:ro
healthcheck:
test: ["CMD", "/app/zitadel", "ready", "--config", "/zitadel-healthcheck.yaml"]
interval: 10s
timeout: 5s
retries: 15
start_period: 30s
restart: unless-stopped
zitadel-db:
image: postgres:16-alpine
environment:
POSTGRES_DB: zitadel
POSTGRES_USER: zitadel
POSTGRES_PASSWORD: "${ZITADEL_DB_PASSWORD}"
volumes:
- zitadel-pg-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U zitadel -d zitadel"]
interval: 5s
timeout: 5s
retries: 10
restart: unless-stopped
pvm-db:
image: postgres:16-alpine
environment:
POSTGRES_DB: pvm
POSTGRES_USER: pvm
POSTGRES_PASSWORD: "${PVM_DB_PASSWORD}"
ports:
- "5432:5432"
volumes:
- pvm-pg-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U pvm -d pvm"]
interval: 5s
timeout: 5s
retries: 10
restart: unless-stopped
dragonfly:
image: docker.dragonflydb.io/dragonflydb/dragonfly:latest
ports:
- "6379:6379"
volumes:
- dragonfly-data:/data
ulimits:
memlock: -1
restart: unless-stopped
volumes:
zitadel-pg-data:
pvm-pg-data:
dragonfly-data: