---
title: "Keel auto-redeploy"
description: "Keel cluster deployment and how to wire a Deployment for polling-based auto-redeploy."
image: "https://docs.virdx.dev/img/virdx-social-card.png"
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.virdx.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Keel auto-redeploy

## How Keel is deployed

Keel runs in the `keel` namespace, installed via Argo CD from the official Helm chart (`charts.keel.sh`, chart version `1.2.0`).

**Argo CD Application:** `infra_k8s/current/argo-cd/keel.yaml`

Key config from the Helm `valuesObject`:

- **Polling enabled**, `@every 5m` default schedule
- Webhooks, webhookRelay, and Helm provider are **disabled**
- No Service or Ingress exposed (pure in-cluster controller)
- Pulls image digests using the `zot-registry-credentials` secret (`kubernetes.io/dockerconfigjson` in the `keel` namespace)
- The IPA CA cert is mounted and set as `SSL_CERT_FILE` so Keel can talk to the internal Zot registry over TLS

**Supporting resources:** `infra_k8s/current/keel/` (applied by the `keel-support` Argo CD Application)

- `ipa-ca-cert.yaml` — ConfigMap with the IPA CA certificate, mounted into Keel

**Namespace:** `infra_k8s/current/namespaces/keel.yaml`

## How to wire a Deployment for auto-redeploy

Add these annotations to the `Deployment` metadata (not the pod template):

```yaml
metadata:
  annotations:
keel.sh/policy: force
keel.sh/trigger: poll
keel.sh/pollSchedule: "@every 5m"
keel.sh/match-tag: "true"
```

The image in the container spec should use a **mutable tag** (e.g. `latest` or a branch tag):

```yaml
image: zot.fra.virdx.dev:5000/<your-image>:latest
imagePullPolicy: Always
```

### The `force` policy

`force` means: ignore semver — whenever the digest behind the tag changes, redeploy. This is what you want for `latest`-style tags. Alternatives (`patch`, `minor`, `major`) only make sense for semver tags.

### `match-tag: "true"`

Prevents Keel from switching to a different tag if multiple tags point to the same digest. Safe default.

## Working examples

`infra_k8s/current/dashboard/api.yaml` and `frontend.yaml` — both use:

```yaml
image: zot.fra.virdx.dev:5000/dashboard-api:latest # or dashboard-frontend:latest
# Deployment metadata annotations:
keel.sh/policy: force
keel.sh/trigger: poll
keel.sh/pollSchedule: "@every 5m"
keel.sh/match-tag: "true"
```

## What does NOT need to be configured

- No `imagePullSecrets` on the Deployment — Keel reads `zot-registry-credentials` from its own namespace for polling. The pod itself still needs pull access; K3s is configured with a registry mirror so nodes can pull from `zot.fra.virdx.dev:5000` directly.
- No webhook endpoints.
- No Keel UI/API credentials — the UI/API Service is disabled.

Source: https://docs.virdx.dev/knowledge/wiki/workstreams/infrastructure/sops/keel-auto-redeploy/index.mdx
