Set Up Automated Enterprise Tag-Based Deployments

Roll out a new image automatically whenever a version tag is published.

Overview

Confident AI ships each release as a semver-tagged container image (vX.Y.Z), and a self-hosted deployment pins that tag in its Helm values (image.tag). Tag-based deployment automates the step in between: when a new tag is published, your tooling bumps image.tag and rolls the release, so you are never hand-editing a values file to ship a version.

This guide is for Enterprise customers already running the self-hosted Helm chart. It covers three ways to wire this up, from a single CI job to full GitOps, and the guardrails that keep an automated rollout safe.

Every install and upgrade runs a database migration job, so a tag bump is a real release, not a hot image swap. Roll it out in staging first, and read Disaster Recovery before you let production update on its own.

How Versioning Works

The first-party images are addressed as <registry>/confidentai/confident-<service>:<tag>, and every service in a release shares the same tag. The chart resolves them from a single knob:

1image:
2 tag: "v2.0.18" # pin explicitly; defaults to the chart's appVersion when empty

All you automate is that one value. Pin it explicitly rather than floating on a mutable tag, so a rollout is always a deliberate, reviewable change.

Choose an Approach

These three approaches are illustrative starting points, not prescriptions. The best setup is the delivery pipeline your team already runs and trusts. If you have a battle-tested CI or GitOps workflow, fold image.tag into it rather than adopting new tooling from this guide.

ApproachWhat triggers the updateBest for
CI pipeline on tag pushYou push a vX.Y.Z git tag in your ops repo, and CI runs helm upgradeTeams with existing CI and no GitOps
GitOps image automationA controller watches the registry and commits the new tag to gitTeams already running Argo CD or Flux
In-cluster poller (Keel)Keel watches the registry and patches the workloads directlyThe quickest path, when git-backed history is not required

For an auditable, declarative setup, GitOps is the strongest fit for enterprise. A CI pipeline is the simplest path that still gives you review and rollback through git.

Option A: CI Pipeline on Tag Push

Keep your Helm values in an ops repo. Cutting a release is then pushing a git tag whose name is the image tag you want live. The example below uses GitHub Actions:

1name: deploy-confident-ai
2on:
3 push:
4 tags: ["v*.*.*"]
5
6jobs:
7 deploy:
8 runs-on: ubuntu-latest
9 permissions:
10 id-token: write # federate into your cloud, no long-lived keys
11 contents: read
12 steps:
13 - uses: actions/checkout@v4
14
15 - name: Get cluster credentials
16 run: |
17 # AWS: aws eks update-kubeconfig --name <cluster> --region <region>
18 # GCP: gcloud container clusters get-credentials <cluster> --region <region>
19 # Azure: az aks get-credentials --resource-group <rg> --name <cluster>
20
21 - name: Deploy the tag
22 run: |
23 helm upgrade confident-ai \
24 oci://ghcr.io/confident-ai/charts/confident-ai --version 0.1.0 \
25 -n confident-ai -f values.yaml \
26 --set image.tag=${GITHUB_REF_NAME} \
27 --wait --timeout 15m

The image tag comes from the git tag (GITHUB_REF_NAME), and --wait holds the job open until the rollout is healthy so a bad release fails the pipeline. Give the runner cluster access through your cloud’s OIDC federation rather than a stored kubeconfig, and keep application secrets in the cloud secret store the deployment already uses, never in the repo.

To promote safely, point the tag push at staging first, then gate production behind a manual approval (a GitHub Environment) that deploys the same tag.

Option B: GitOps Image Automation

If you run GitOps, declare the release in git and let a controller bump the tag for you.

Argo CD Image Updater watches the registry and writes the new tag back to your git manifests, and Argo CD syncs the change. Annotate the Application:

1metadata:
2 annotations:
3 argocd-image-updater.argoproj.io/image-list: confident=<registry>/confidentai/confident-backend
4 argocd-image-updater.argoproj.io/confident.update-strategy: semver
5 argocd-image-updater.argoproj.io/confident.allow-tags: regexp:^v\d+\.\d+\.\d+$
6 argocd-image-updater.argoproj.io/confident.helm.image-tag: image.tag
7 argocd-image-updater.argoproj.io/write-back-method: git

confident-backend is the version reference for the whole release, since every service shares the tag. Image Updater needs pull and list access to the registry, so give it the same credentials your deployment uses.

Because the tag lands in git, every rollout is a commit you can review, and a rollback is a git revert.

Option C: In-Cluster Poller

Keel watches the registry and updates the workloads directly, with no git in the loop. Set a policy on the release so it only tracks the tags you want:

1# in your Helm values, applied to the app workloads
2podAnnotations:
3 keel.sh/policy: patch # patch | minor | major, or a semver range
4 keel.sh/trigger: poll
5 keel.sh/pollSchedule: "@every 5m"

This is the fastest to stand up, and a good fit for a staging cluster that should always run the newest release. For production, prefer Option A or B, where the change is recorded and reversible.

Guardrails

The mechanics are easy. These are the practices that keep an automated rollout from becoming an automated outage:

  • Pin, and constrain the policy. Never float on a mutable tag. Let patch releases (~> 2.0.x) update automatically for low risk, and hold minor and major bumps behind manual approval.
  • Migrations run on every upgrade. A tag bump runs the database migration job. Take a database snapshot beforehand in production, and always let staging update first.
  • Promote, do not double-deploy. Deploy a tag to staging, then promote the exact same tag to production. Never let two environments resolve a floating tag independently.
  • Let health gate the rollout. The chart’s readiness probes hold a rolling update until the new pods are healthy. Keep --wait (CI) or sync health checks (GitOps) on, so a failed release stops rather than replaces a working one.
  • Know your rollback. helm rollback confident-ai returns to the previous release; under GitOps, revert the commit. Rehearse it once so it is muscle memory.
  • Give the automation registry access. Whatever watches for new tags needs list and pull access to the registry, so reuse the credentials your deployment already holds.

Verify

Publish a tag to your staging path and watch it land:

$kubectl rollout status deployment/confident-backend -n confident-ai
$kubectl get pods -n confident-ai -o jsonpath='{.items[*].spec.containers[*].image}' | tr ' ' '\n' | sort -u

The image line should show your new tag, and the rollout should report success. Under Argo CD or Flux, confirm the tag was committed to git and the application is Synced and Healthy.

Next Steps