towerops/k8s
Graham McIntire 50324c61ce feat(metrics): expose Prometheus /metrics via PromEx on :9568
Add PromEx with Application/BEAM/Phoenix/LiveView/Ecto/Oban plugins plus
a custom plugin that bridges existing Towerops Oban/Redis telemetry events.
The metrics HTTP server runs isolated on port 9568 so scrape traffic never
traverses the public Traefik IngressRoute.

The pod template carries prometheus.io annotations (scrape, port, path, job)
so the external Prometheus on 10.0.15.31 discovers each pod through the
existing kubernetes-pods scrape job (apiserver-proxy).
2026-05-08 10:25:25 -05:00
..
base-image Dockerfile: align Elixir/OTP/Debian versions with microwaveprop 2026-04-29 12:45:21 -05:00
certificate.yaml Remove www subdomain from certificate and IngressRoute 2026-01-02 15:06:21 -06:00
deployment.yaml feat(metrics): expose Prometheus /metrics via PromEx on :9568 2026-05-08 10:25:25 -05:00
Dockerfile ci: cache slow runtime apt deps in a prebuilt base image 2026-05-05 11:19:49 -05:00
Dockerfile.base ci: cache slow runtime apt deps in a prebuilt base image 2026-05-05 11:19:49 -05:00
ingressroute.yaml Remove www subdomain from certificate and IngressRoute 2026-01-02 15:06:21 -06:00
kustomization.yaml fix: exclude cert-manager and traefik resources from FluxCD kustomization 2026-02-14 11:05:20 -06:00
namespace.yaml Add Kubernetes deployment manifests for towerops.net 2026-01-02 14:38:52 -06:00
poddisruptionbudget.yaml Add zero-downtime deployment configuration 2026-01-17 12:44:22 -06:00
README.md Set DEPLOY_TIMESTAMP from GitLab CI instead of pod metadata 2026-01-17 11:17:07 -06:00
service-headless.yaml cluster 2026-01-02 15:29:02 -06:00
service.yaml Add Kubernetes deployment manifests for towerops.net 2026-01-02 14:38:52 -06:00
traefik-security-headers-middleware.yaml fix prod crash with yaml parsing 2026-01-31 08:25:07 -06:00

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)

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:

# 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:

kubectl set env deployment/towerops DEPLOY_TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ") -n towerops

Deploying

Apply all resources using kustomize:

kubectl apply -k k8s/

Or individually:

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