From 07b0ddb67d8ea20712caac8f86d2e093a1410e63 Mon Sep 17 00:00:00 2001 From: Graham McIntire Date: Sat, 17 Jan 2026 11:17:07 -0600 Subject: [PATCH] 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. --- .gitlab-ci.yml | 4 ++++ k8s/README.md | 16 +++++++++------- k8s/deployment.yaml | 4 +--- lib/towerops/application.ex | 22 +++++++--------------- 4 files changed, 21 insertions(+), 25 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b3df4dfe..6d8a4120 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -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 diff --git a/k8s/README.md b/k8s/README.md index dd42794d..399315aa 100644 --- a/k8s/README.md +++ b/k8s/README.md @@ -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 diff --git a/k8s/deployment.yaml b/k8s/deployment.yaml index b21861ae..6effd4cb 100644 --- a/k8s/deployment.yaml +++ b/k8s/deployment.yaml @@ -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 diff --git a/lib/towerops/application.ex b/lib/towerops/application.ex index ed9ceec8..e57934c9 100644 --- a/lib/towerops/application.ex +++ b/lib/towerops/application.ex @@ -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