# Services Reference Per-service details: what each one does, where its config lives, and how to debug it. ## Traefik **Image:** `traefik:v3.2` **Container:** `dezky-traefik` **URL:** https://traefik.dezky.local (dashboard) **Purpose:** Reverse proxy, TLS termination, service discovery via Docker labels **Config:** - Static: `configs/traefik/traefik.yml` - Dynamic: `configs/traefik/dynamic.yml` (TLS certs) - Certs: `certs/dezky.local.pem` + `certs/dezky.local-key.pem` **Debug:** ```bash docker compose logs -f traefik # Open https://traefik.dezky.local for dashboard ``` --- ## PostgreSQL **Image:** `postgres:16-alpine` **Container:** `dezky-postgres` **Internal hostname:** `postgres` **Purpose:** Shared RDBMS for Authentik and OCIS (future) **Databases:** - `authentik` (owner: `authentik`) - `ocis` (owner: `ocis`, reserved for future use) **Debug:** ```bash # Shell access docker compose exec postgres psql -U postgres # Check users \du # Check databases \l # Connect to specific DB \c authentik ``` --- ## MongoDB **Image:** `mongo:7` **Container:** `dezky-mongo` **Internal hostname:** `mongo` **Purpose:** Portal application data **Connection:** ``` mongodb://root:${MONGO_ROOT_PASSWORD}@mongo:27017/dezky?authSource=admin ``` **Debug:** ```bash docker compose exec mongo mongosh -u root -p $(grep MONGO_ROOT_PASSWORD .env | cut -d= -f2) ``` --- ## Redis **Image:** `redis:7-alpine` **Container:** `dezky-redis` **Internal hostname:** `redis` **Purpose:** Cache and session store (used by Authentik) **Debug:** ```bash docker compose exec redis redis-cli -a $(grep REDIS_PASSWORD .env | cut -d= -f2) > KEYS * > INFO ``` --- ## Authentik **Image:** `ghcr.io/goauthentik/server:2025.10` **Containers:** `dezky-authentik` (server) + `dezky-authentik-worker` **URL:** https://auth.dezky.local **Purpose:** Identity provider, SSO, MFA **First-time setup:** - URL: https://auth.dezky.local/if/flow/initial-setup/ - Email: `admin@dezky.local` - Password: `AUTHENTIK_BOOTSTRAP_PASSWORD` from `.env` **API:** - Base: https://auth.dezky.local/api/v3 - Auth: `Authorization: Bearer ` - Docs: https://auth.dezky.local/api/v3/ **Debug:** ```bash docker compose logs -f authentik-server authentik-worker # Check API health curl https://auth.dezky.local/-/health/ready/ ``` See `docs/AUTHENTIK-SETUP.md` for OIDC configuration steps. --- ## Stalwart Mail **Image:** `stalwartlabs/mail-server:latest` **Container:** `dezky-stalwart` **URL:** https://mail.dezky.local **Purpose:** Mail server (SMTP/IMAP/JMAP/CalDAV/CardDAV/ActiveSync) **Ports exposed:** - 25 (SMTP) - 465 (SMTPS) - 587 (Submission) - 143 (IMAP) - 993 (IMAPS) - 4190 (ManageSieve) **Config:** `configs/stalwart/config.toml` **Data:** Docker volume `dezky_stalwart_data` **Admin login:** - User: `admin` - Password: `STALWART_ADMIN_PASSWORD` from `.env` **Debug:** ```bash docker compose logs -f stalwart # Test SMTP swaks --to test@dezky.local --from sender@example.com --server mail.dezky.local:25 # Check ports docker compose port stalwart 25 ``` --- ## OCIS **Image:** `owncloud/ocis:7.0` **Container:** `dezky-ocis` **URL:** https://files.dezky.local **Purpose:** File storage, sharing, sync **OIDC config:** - Issuer: `https://auth.dezky.local/application/o/ocis/` - Client ID: `ocis-web` (configured in Authentik) - Auto-provision: enabled (creates OCIS user on first SSO login) **Admin login:** - User: `admin` - Password: `OCIS_ADMIN_PASSWORD` from `.env` **Storage backend:** - Dev: local filesystem inside volume `dezky_ocis_data` - Prod: will switch to S3 (Hetzner Object Storage) **Debug:** ```bash docker compose logs -f ocis # Health check curl -k https://files.dezky.local/ ``` --- ## Collabora **Image:** `collabora/code:latest` **Container:** `dezky-collabora` **URL:** https://office.dezky.local **Purpose:** Office document editing inside OCIS **Integration with OCIS:** - OCIS must be configured to use Collabora as its office editor - See: OCIS app config → "wopiserver" **Debug:** ```bash docker compose logs -f collabora # Discovery endpoint (used by OCIS) curl -k https://office.dezky.local/hosting/discovery ``` --- ## Portal (Nuxt 3) **Container:** `dezky-portal` **URL:** https://app.dezky.local **Source:** `apps/portal/` **Purpose:** Customer-facing portal, launcher, custom webmail **Stack:** - Nuxt 3 - Vue 3 + TypeScript - Vite dev server - pnpm for dependencies **Hot reload:** - File changes in `apps/portal/` trigger HMR automatically - Vite watches via polling (configured in `nuxt.config.ts`) **Environment:** - `NUXT_PUBLIC_AUTH_URL`: Authentik URL (client-side) - `NUXT_API_BASE`: provisioning service URL (server-side) - `MONGODB_URI`: MongoDB connection string **Debug:** ```bash docker compose logs -f portal # Shell into container docker compose exec portal sh > pnpm dev ``` --- ## Provisioning Service (NestJS) **Container:** `dezky-provisioning` **Port:** 3001 (internal only) **Source:** `services/provisioning/` **Purpose:** Tenant lifecycle, billing webhooks, service orchestration **Endpoints to implement:** - `POST /tenants` — Create tenant - `GET /tenants/:id` — Get tenant - `PATCH /tenants/:id` — Update tenant - `POST /tenants/:id/users` — Add user to tenant - `POST /webhooks/stripe` — Billing events **Environment:** - `MONGODB_URI`: Portal data store - `AUTHENTIK_API_URL` + `AUTHENTIK_API_TOKEN` - `STALWART_API_URL` + `STALWART_ADMIN_USER/PASSWORD` - `OCIS_API_URL` **Debug:** ```bash docker compose logs -f provisioning # Test health endpoint docker compose exec provisioning wget -qO- http://localhost:3001/health ```