feat(docker-watcher): phase 12 - hardening

Blue-green zero-downtime deploys, promote flow validation.
Dual auth: local (bcrypt + JWT) and OAuth2/OIDC (any provider).
Auth middleware, login page, auth settings UI.
Structured logging (slog JSON), config export to YAML.
Graceful shutdown with deploy draining.
Multi-stage Dockerfile and production docker-compose.yml.
Swap phase order: Volumes & Env before UI Polish.
This commit is contained in:
2026-03-27 23:20:56 +03:00
parent 5558396bb7
commit 32de5b26a8
30 changed files with 2134 additions and 143 deletions
+30 -9
View File
@@ -325,16 +325,37 @@ stages:
NODE_ENV: production # uses project-level default
```
### Phase 5: Hardening
### Phase 5: Hardening (Phase 12) -- COMPLETED
30. **Blue-green deploys** start new, health check, swap, stop old (zero downtime)
31. **Promote flow** enforce `promote_from` for production deploys
32. **Auth on dashboard** two modes, configurable via settings:
- **Local auth** username/password stored in SQLite (hashed), for simple setups
- **OAuth2 / OpenID Connect** integration with Authentik (or any OIDC provider), configurable client ID/secret/discovery URL
33. **Graceful shutdown** drain in-progress deploys on SIGTERM
34. **Structured logging** JSON logs with deploy context
35. **Config export** download current SQLite state as YAML
30. **Blue-green deploys** -- start new, health check, swap, stop old (zero downtime)
31. **Promote flow** -- enforce `promote_from` for production deploys
32. **Auth on dashboard** -- two modes, configurable via settings:
- **Local auth** -- username/password stored in SQLite (bcrypt hashed), JWT session tokens
- **OAuth2 / OpenID Connect** -- integration with any OIDC provider (configurable client ID/secret/discovery URL)
33. **Graceful shutdown** -- drain in-progress deploys on SIGTERM, close DB, stop poller
34. **Structured logging** -- JSON logs via `log/slog` with deploy context
35. **Config export** -- download current SQLite state as YAML
36. **Dockerfile** -- multi-stage build (Node.js 20 + Go 1.23 build, alpine runtime)
37. **docker-compose.yml** -- production-ready compose with volumes, network, env
38. **Auth middleware** -- protects all /api/* routes except webhook and auth endpoints
39. **Auth settings UI** -- settings page to toggle auth mode, configure OIDC, manage users
40. **Login page** -- username/password form with OIDC SSO option
41. **Final wiring** -- all services properly initialized and shut down in main.go
#### Phase 12 Handoff Notes
- Auth: `auth.LocalAuth` handles JWT generation/validation, `auth.OIDCProvider` handles OIDC flow
- Default admin user created on first launch (ADMIN_PASSWORD env var, default: "admin")
- JWT secret derived from ENCRYPTION_KEY via HMAC-SHA256
- Blue-green: triggered automatically when stage has `max_instances=1`; otherwise standard deploy
- Promote: validated in `TriggerDeploy` before deploy begins
- Graceful shutdown: `deployer.Drain()` waits for in-progress deploys; poller stopped; HTTP server drained; DB closed
- Structured logging: all API, deployer, and main.go use `log/slog` JSON handler
- New dependencies: `github.com/golang-jwt/jwt/v5`, `golang.org/x/crypto/bcrypt`, `github.com/coreos/go-oidc/v3`, `golang.org/x/oauth2`
- New tables: `users` (id, username, password_hash, email, role, timestamps), `auth_settings` (single-row: auth_mode, OIDC config)
- Auth middleware applied to all `/api/*` routes except `/api/auth/login`, `/api/auth/oidc/*`, `/api/webhook/*`, `/api/config/export`
- Frontend: token stored in `localStorage`, sent as `Authorization: Bearer` header
- Run `go mod tidy` after checkout to resolve transitive dependencies
## Key Dependencies (Go)