towerops/k8s/README.md
Graham McIntire 32c9575952 chore(k8s): unify secrets template into one k8s/secrets.example.yaml
Replace the single-secret towerops-llm template with one
multi-document YAML covering every Secret the Deployment references:
towerops-secrets, towerops-db, towerops-aws, towerops-redis,
towerops-billing, towerops-llm.

Workflow: copy k8s/secrets.example.yaml to k8s/secrets.yaml (which is
gitignored), fill in real values, kubectl apply. Real values never land
in git.
2026-05-09 18:01:09 -05:00

74 lines
2.7 KiB
Markdown

# Kubernetes Deployment
## Secrets Management
Secrets are managed directly in the cluster and must be created before deploying the application.
Required secrets in the `towerops` namespace:
- `gitlab-registry` - Docker registry credentials for pulling images
- `towerops-secrets` - Application secrets (RELEASE_COOKIE, SECRET_KEY_BASE)
- `towerops-db` - Database connection credentials
- `towerops-aws` - AWS credentials (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION)
Optional secrets:
- `towerops-llm` - DeepSeek API credentials for LLM-powered insight enrichment.
Optional — when missing, insights still display without an AI summary.
- `towerops-billing` - Stripe credentials. Every key is optional in the deployment.
### Local secrets workflow
`k8s/secrets.yaml` is gitignored. Use it to keep every `Secret` manifest
the deployment needs in one place for hand-application against the
cluster. Bootstrap from the unified template:
```bash
cp k8s/secrets.example.yaml k8s/secrets.yaml
# edit k8s/secrets.yaml — fill in DATABASE_URL, AWS keys, RELEASE_COOKIE,
# SECRET_KEY_BASE, CLOAK_KEY, and any optional ones (DEEPSEEK_API_KEY,
# Stripe keys, etc.)
kubectl apply -f k8s/secrets.yaml
kubectl rollout restart deployment/towerops -n towerops
```
`k8s/secrets.yaml` is one multi-document YAML covering every Secret the
deployment references (towerops-secrets, towerops-db, towerops-aws,
towerops-redis, towerops-billing, towerops-llm). It is excluded from git
via `.gitignore` so real values never accidentally land in source.
For local development, the project root `.envrc` is used by direnv.
## Deployment Timestamp
The application footer displays the deployment timestamp to track when the current version was deployed. This is automatically set by GitLab CI during deployment:
```yaml
# GitLab CI sets this during deploy
- kubectl set env deployment/towerops DEPLOY_TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ") -n towerops
```
All pods in the deployment share the same timestamp (when the deployment was initiated), regardless of when individual pods were created. This is displayed in the footer as "Last deployed X ago · YYYY-MM-DD HH:MM:SS UTC".
For manual deployments without GitLab CI, set the timestamp:
```bash
kubectl set env deployment/towerops DEPLOY_TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ") -n towerops
```
## Deploying
Apply all resources using kustomize:
```bash
kubectl apply -k k8s/
```
Or individually:
```bash
kubectl apply -f k8s/namespace.yaml
kubectl apply -f k8s/secret.yaml
kubectl apply -f k8s/deployment.yaml
kubectl apply -f k8s/service.yaml
kubectl apply -f k8s/service-headless.yaml
kubectl apply -f k8s/certificate.yaml
kubectl apply -f k8s/ingressroute.yaml
```