Chart AppVersion and Image Tag Sync#
In the dify-helm chart, three versioning identifiers coexist and can diverge silently:
| Identifier | Location | Purpose |
|---|---|---|
Chart.version | Chart.yaml | Helm chart release version |
Chart.appVersion | Chart.yaml | Declared "primary" application version |
image.<component>.tag | values.yaml | Actual container image pulled at runtime |
The core risk: appVersion (currently "1.17.0") is the sole source for the app.kubernetes.io/version label applied to all rendered Kubernetes resources via the dify.labels helper. Image tags are configured independently per component in values.yaml and are never read back to update that label β meaning the label and the running container can easily report different versions.
How the app.kubernetes.io/version Label Is Set#
The dify.labels template helper in charts/dify/templates/_helpers.tpl stamps every resource with:
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
This value comes directly from Chart.yaml's appVersion field β not from any component's image.*.tag. There is no per-component version label. Every Deployment, StatefulSet, Service, and related resource gets the same app.kubernetes.io/version regardless of which image tag a given component actually runs.
Per-Component Image Tags#
Each Dify component has its own image.<component>.tag in values.yaml. The defaults in the current chart show that not all components share the same version as appVersion:
| Component | Repository | Default Tag |
|---|---|---|
api | langgenius/dify-api | 1.17.0 |
web | langgenius/dify-web | 1.17.0 |
agentBackend | langgenius/dify-agent-backend | 1.17.0 |
localSandbox | langgenius/dify-agent-local-sandbox | 1.17.0 |
sandbox | langgenius/dify-sandbox | 0.2.15 |
pluginDaemon | langgenius/dify-plugin-daemon | 0.6.10-local |
proxy | nginx | latest |
ssrfProxy | ubuntu/squid | latest |
Even at chart publish time, sandbox (0.2.15) and pluginDaemon (0.6.10-local) already differ from appVersion: "1.17.0" . This is by design β those components follow independent release cadences.
Divergence Scenarios#
Scenario 1 β Pinning an image ahead of the chart release.
An operator sets image.api.tag=1.18.0 in their values.yaml override to track a newer Dify build before a chart update ships. The running container is 1.18.0, but app.kubernetes.io/version still reads 1.17.0 (from Chart.appVersion). Monitoring dashboards and kubectl label selectors that filter by version will report stale data.
Scenario 2 β Upgrading appVersion without touching image tags.
A chart maintainer bumps appVersion in Chart.yaml to document a new release but forgets to update image.api.tag in values.yaml. Resources are labelled with the new version, but containers are still running the old image.
Scenario 3 β Infrastructure components are always diverged.
sandbox and pluginDaemon intentionally ship versions that do not match appVersion . There is no mechanism in the chart to flag this mismatch; it is silently accepted.
Keeping Versions in Sync#
As a chart consumer:
- When overriding image tags, treat
app.kubernetes.io/versionas reflecting the chart's declared baseline, not your running containers. Do not rely on it for per-component version auditing. - For accurate version tracking, inspect actual image digests or tags directly (e.g.,
kubectl get pod -o jsonpath='{.spec.containers[*].image}').
As a chart maintainer:
- Update
image.api.tag,image.web.tag,image.agentBackend.tag, andimage.localSandbox.taginvalues.yamltogether withappVersioninChart.yamlon every Dify core release. sandboxandpluginDaemonfollow independent versioning and should be updated separately on their own release cycles.- The chart does not validate tag/appVersion alignment β this is a manual discipline.