5558396bb7
Embed SvelteKit static build in Go binary via go:embed. Event bus for pub/sub with deploy log, instance status, and deploy status events. SSE endpoints for real-time streaming. Frontend SSE client with exponential backoff reconnection. Makefile for build pipeline. Update Phase 12 auth plan with OAuth2/OIDC support.
4.2 KiB
4.2 KiB
Phase 12: Hardening
Status: ⬜ Not Started Parent plan: PLAN.md Domain: backend
Objective
Production hardening — blue-green deploys, promote flow, dashboard auth, graceful shutdown, structured logging, and config export.
Tasks
- Task 1: Blue-green deploys — start new container, health check, swap NPM proxy, then stop old container (zero downtime)
- Task 2: Promote flow — enforce
promote_fromfor production deploys (only tags running in source stage are eligible) - Task 3: Local auth — username/password stored in SQLite (bcrypt hashed), login endpoint, session token (JWT or cookie)
- Task 4: OAuth2/OIDC auth — integration with Authentik or any OIDC provider (configurable client ID, client secret, discovery URL)
- Task 5: Auth settings UI — settings page to choose auth mode (local/OIDC), configure OIDC provider, manage local users
- Task 6: Auth middleware — protect all /api/* routes except webhook; check session/JWT/OIDC token
- Task 7: Graceful shutdown — handle SIGTERM/SIGINT, drain in-progress deploys, close DB, stop poller
- Task 8: Structured logging — JSON logs with deploy context (project, stage, tag, instance ID)
- Task 9: Config export — download current SQLite state as YAML (reverse of seed import)
- Task 10: Dockerfile — multi-stage build (build frontend + Go, copy to minimal image)
- Task 11: docker-compose.yml — production-ready compose file with volumes, network, env
- Task 12: Final wiring review — ensure all services are properly initialized and shut down
Files to Modify/Create
internal/deployer/bluegreen.go— blue-green deploy strategyinternal/deployer/promote.go— promote flow logicinternal/auth/local.go— local auth (bcrypt password hashing, session tokens)internal/auth/oidc.go— OAuth2/OIDC provider integrationinternal/auth/middleware.go— auth middleware (session/JWT/OIDC token validation)internal/auth/models.go— user model, auth settings, session storeinternal/api/auth.go— auth API endpoints (login, logout, OIDC callback, user management)internal/config/export.go— config export to YAMLinternal/logging/logger.go— structured JSON loggerinternal/store/users.go— user CRUD, auth settings persistenceweb/src/routes/login/+page.svelte— login pageweb/src/routes/settings/auth/+page.svelte— auth settings UIcmd/server/main.go— graceful shutdown, structured logging, auth initDockerfile— multi-stage builddocker-compose.yml— production compose file
Acceptance Criteria
- Blue-green: zero downtime during deploy (old container serves until new one is healthy)
- Promote: production deploy only accepts tags from the specified source stage
- Auth: unauthenticated requests to /api/* (except webhook) return 401
- Graceful shutdown: in-progress deploys complete before exit
- Logs are JSON-formatted with contextual fields
- Config export produces valid YAML that could be re-imported
- Docker image builds and runs correctly
Notes
- Blue-green: keep old container running until new one passes health check, then swap NPM proxy and stop old
- Auth has two modes configurable via settings:
- Local auth: username/password in SQLite (bcrypt hashed), JWT session tokens
- OAuth2/OIDC: integration with Authentik or any OIDC provider (client ID, secret, discovery URL)
- First launch: create default admin user with configurable password via ADMIN_PASSWORD env var
- OIDC flow: redirect to provider → callback → create/link local user → issue session
- SIGTERM handling: use Go's
os/signal+context.WithCancel - Structured logging: use
log/slog(Go stdlib since 1.21) - Dockerfile: build stage with Node.js + Go, runtime stage with scratch/alpine
- Phase 13 (UI Polish) and Phase 14 (Volumes & Env) follow this phase
Review Checklist
- All tasks completed
- Blue-green deploy handles rollback if new container fails
- Auth doesn't block webhook endpoint
- Graceful shutdown tested with concurrent deploys
- Dockerfile produces a minimal image
- docker-compose.yml matches the example in PLAN.md