Set DEPLOY_TIMESTAMP from GitLab CI instead of pod metadata

- Update GitLab CI deploy job to set DEPLOY_TIMESTAMP when deploying
- Use 'kubectl set env' to update all pods with same timestamp
- Change deployment.yaml to use static placeholder value
- Update documentation to explain GitLab CI timestamp approach

This ensures all pods show the same deployment time, regardless of:
- Which pod handles the request (with replicas=2)
- When individual pods were created or restarted
- Pod restarts from crashes or rolling updates

The timestamp now represents when the deployment was initiated by GitLab CI,
not when individual pods were created.
This commit is contained in:
Graham McIntire 2026-01-17 11:17:07 -06:00
parent 9fcf19b304
commit 07b0ddb67d
No known key found for this signature in database
4 changed files with 21 additions and 25 deletions

View file

@ -48,8 +48,12 @@ deploy:
script:
- kubectl config get-contexts
- kubectl config use-context towerops/towerops:home-cluster-agent
# Set deployment timestamp (ISO 8601 format in UTC)
- DEPLOY_TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
- echo "Deploying at $DEPLOY_TIMESTAMP"
# Deploy new version (migrations run on app start)
- kubectl set image deployment/towerops towerops=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA -n towerops
- kubectl set env deployment/towerops DEPLOY_TIMESTAMP=$DEPLOY_TIMESTAMP -n towerops
- kubectl rollout status deployment/towerops -n towerops --timeout=5m
environment:
name: production

View file

@ -14,17 +14,19 @@ 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 using the Kubernetes Downward API:
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
env:
- name: DEPLOY_TIMESTAMP
valueFrom:
fieldRef:
fieldPath: metadata.creationTimestamp
# GitLab CI sets this during deploy
- kubectl set env deployment/towerops DEPLOY_TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ") -n towerops
```
The pod's creation timestamp is injected as an environment variable and displayed in the footer as "Last deployed X ago · YYYY-MM-DD HH:MM:SS UTC".
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

View file

@ -56,9 +56,7 @@ spec:
fieldRef:
fieldPath: metadata.namespace
- name: DEPLOY_TIMESTAMP
valueFrom:
fieldRef:
fieldPath: metadata.creationTimestamp
value: "1970-01-01T00:00:00Z" # Placeholder, updated by GitLab CI on deploy
- name: RELEASE_DISTRIBUTION
value: "name"
- name: RELEASE_NODE

View file

@ -52,24 +52,16 @@ defmodule Towerops.Application do
Returns the deployment timestamp.
In production (Kubernetes), this reads from the DEPLOY_TIMESTAMP environment
variable which should be set during deployment. Falls back to compile time
in development.
variable which is automatically set by GitLab CI during deployment. Falls back
to compile time in development.
Set DEPLOY_TIMESTAMP in your Kubernetes deployment:
```yaml
env:
- name: DEPLOY_TIMESTAMP
value: "2026-01-17T12:34:56Z"
The timestamp is set by GitLab CI using:
```bash
kubectl set env deployment/towerops DEPLOY_TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ") -n towerops
```
Or use a downward API to inject the pod creation time:
```yaml
env:
- name: DEPLOY_TIMESTAMP
valueFrom:
fieldRef:
fieldPath: metadata.creationTimestamp
```
This ensures all pods in the deployment show the same deployment time, regardless
of when individual pods were created or restarted.
"""
@spec build_timestamp() :: DateTime.t()
def build_timestamp do