Deployment Overview¶
KanjiIQ uses a fully automated CI/CD pipeline that builds Docker images, pushes them to the Forgejo Container Registry, and deploys to the k3s cluster on every push to main.
Pipeline Flow¶
graph LR
A[git push main] --> B[Forgejo Actions<br/>Triggered]
B --> C[Docker Build<br/>Multi-stage]
C --> D[Push to Registry<br/><registry>]
D --> E[kubectl set image<br/>Rolling update]
E --> F[Rollout Status<br/>Health check]
Path-Based Triggering¶
Each component has its own workflow, triggered only when relevant files change:
| Workflow | Trigger Paths | Image |
|---|---|---|
deploy-frontend.yml |
frontend/**, Dockerfile.frontend, nginx.frontend.conf |
jlpt-kanji-frontend |
deploy-backend.yml |
backend/**, Dockerfile.backend |
jlpt-kanji-backend |
deploy-docs.yml |
docs/**, mkdocs.yml, Dockerfile.docs |
jlpt-kanji-docs |
This means changing a documentation page does not trigger a frontend or backend rebuild.
Deployment Strategy¶
KanjiIQ uses Kubernetes rolling updates:
- New pods are created with the updated image
- Readiness probes must pass before old pods are terminated
- If the new version fails health checks, the rollout is automatically stopped
- Zero-downtime deployments with 2 replicas
Environments¶
| Environment | Purpose | URL |
|---|---|---|
| Production | Live application | kanjiiq.com |
| Staging | Pre-release testing | Local k8s namespace |
| Development | Local development | localhost:8080 / localhost:3000 |
The staging environment mirrors production manifests in a separate Kubernetes namespace (jlpt-kanji-staging) with its own PostgreSQL instance.
Image Tagging¶
Every build produces two tags:
:latest— Always points to the most recent build:COMMIT_SHA— Immutable tag for traceability
Deployments use the commit SHA tag to ensure deterministic rollouts: