From f9bb7e6124d2c4dee5f02b5a6c8e6b0093ea4ec9 Mon Sep 17 00:00:00 2001 From: Caleb Braaten Date: Thu, 17 Sep 2026 03:13:26 -0700 Subject: [PATCH] Update deployment workflows --- .gitea/workflows/build.yml | 2 ++ blog.nomad.hcl | 19 ++++++++++++++++ blog.nomad.json | 44 ++++++++++++++++++++++++++++++++------ 3 files changed, 59 insertions(+), 6 deletions(-) diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml index b158ff0..a0daebe 100644 --- a/.gitea/workflows/build.yml +++ b/.gitea/workflows/build.yml @@ -58,3 +58,5 @@ jobs: tags: | ${{ env.IMAGE_NAME }}:latest ${{ env.IMAGE_NAME }}:${{ steps.sha.outputs.short_sha }} + provenance: false + sbom: false diff --git a/blog.nomad.hcl b/blog.nomad.hcl index 7501334..d5a430f 100644 --- a/blog.nomad.hcl +++ b/blog.nomad.hcl @@ -16,6 +16,10 @@ job "blog" { group "blog" { count = 1 + # let Consul/Traefik deregister the old allocation before it exits, + # so no requests are routed to it during a rolling switchover + shutdown_delay = "10s" + network { port "http" { to = 3000 @@ -52,6 +56,18 @@ job "blog" { "traefik.http.services.blog-svc.loadbalancer.healthcheck.timeout=2s", "traefik.http.services.blog-svc.loadbalancer.healthcheck.hostname=${local.HOST}", ] + + # canary allocations register with these tags instead, so Traefik + # does not route production traffic to them before promotion + canary_tags = ["canary"] + + check { + name = "blog-health" + type = "http" + path = "/healthz" + interval = "10s" + timeout = "2s" + } } task "blog" { @@ -65,8 +81,11 @@ job "blog" { update { max_parallel = 1 + health_check = "checks" min_healthy_time = "10s" healthy_deadline = "3m" + canary = 1 + auto_promote = true auto_revert = true } } diff --git a/blog.nomad.json b/blog.nomad.json index 455afc3..27830e5 100644 --- a/blog.nomad.json +++ b/blog.nomad.json @@ -65,13 +65,13 @@ "Update": { "Stagger": null, "MaxParallel": 1, - "HealthCheck": null, + "HealthCheck": "checks", "MinHealthyTime": 10000000000, "HealthyDeadline": 180000000000, "ProgressDeadline": null, - "Canary": null, + "Canary": 1, "AutoRevert": true, - "AutoPromote": null + "AutoPromote": true }, "Migrate": null, "Networks": [ @@ -118,12 +118,44 @@ "traefik.http.services.blog-svc.loadbalancer.healthcheck.timeout=2s", "traefik.http.services.blog-svc.loadbalancer.healthcheck.hostname=cbraaten.dev" ], - "CanaryTags": null, + "CanaryTags": [ + "canary" + ], "EnableTagOverride": false, "PortLabel": "http", "AddressMode": "", "Address": "", - "Checks": null, + "Checks": [ + { + "Name": "blog-health", + "Type": "http", + "Command": "", + "Args": null, + "Path": "/healthz", + "Protocol": "", + "PortLabel": "", + "Expose": false, + "AddressMode": "", + "Advertise": "", + "Interval": 10000000000, + "Timeout": 2000000000, + "InitialStatus": "", + "Notes": "", + "TLSServerName": "", + "TLSSkipVerify": false, + "Header": null, + "Method": "", + "CheckRestart": null, + "GRPCService": "", + "GRPCUseTLS": false, + "TaskName": "", + "SuccessBeforePassing": 0, + "FailuresBeforeCritical": 0, + "FailuresBeforeWarning": 0, + "Body": "", + "OnUpdate": "" + } + ], "CheckRestart": null, "Connect": null, "Meta": null, @@ -138,7 +170,7 @@ "Kind": "" } ], - "ShutdownDelay": null, + "ShutdownDelay": 10000000000, "StopAfterClientDisconnect": null, "MaxClientDisconnect": null, "Scaling": null,