Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions api/v1beta1/temporalcluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,17 @@ type TemporalUISpec struct {
// Image defines the temporal ui docker image the instance should run.
// +optional
Image string `json:"image"`
// ImageTag overrides the tag used for the temporal ui image. When set, it
// is used instead of Version as the image tag.
// +optional
ImageTag string `json:"imageTag,omitempty"`
// ImageDigest pins the temporal ui image to an immutable digest
// (e.g. "sha256:abc..."). When set, it is appended to the image reference
// (repository:tag@digest) so the running image cannot change behind a
// mutable tag.
// +kubebuilder:validation:Pattern=`^sha256:[a-fA-F0-9]{64}$`
// +optional
ImageDigest string `json:"imageDigest,omitempty"`
// Number of desired replicas for the ui. Default to 1.
// +kubebuilder:validation:Minimum=1
// +optional
Expand Down Expand Up @@ -589,6 +600,17 @@ type TemporalAdminToolsSpec struct {
// Version defines the temporal admin tools version the instance should run.
// +optional
Version string `json:"version"`
// ImageTag overrides the tag used for the temporal admin tools image. When
// set, it is used instead of Version as the image tag.
// +optional
ImageTag string `json:"imageTag,omitempty"`
// ImageDigest pins the temporal admin tools image to an immutable digest
// (e.g. "sha256:abc..."). When set, it is appended to the image reference
// (repository:tag@digest) so the running image cannot change behind a
// mutable tag.
// +kubebuilder:validation:Pattern=`^sha256:[a-fA-F0-9]{64}$`
// +optional
ImageDigest string `json:"imageDigest,omitempty"`
// Compute Resources required by the ui.
// More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
// +optional
Expand Down Expand Up @@ -1015,6 +1037,18 @@ type TemporalClusterSpec struct {
// This version impacts the underlying persistence schemas versions.
// +optional
Version *version.Version `json:"version"`
// ImageTag overrides the tag used for the temporal server image. When set,
// it is used instead of Version as the image tag. Version still drives the
// persistence schema version regardless of this override.
// +optional
ImageTag string `json:"imageTag,omitempty"`
// ImageDigest pins the temporal server image to an immutable digest
// (e.g. "sha256:abc..."). When set, it is appended to the image reference
// (repository:tag@digest) so the running image cannot change behind a
// mutable tag.
// +kubebuilder:validation:Pattern=`^sha256:[a-fA-F0-9]{64}$`
// +optional
ImageDigest string `json:"imageDigest,omitempty"`
// Log defines temporal cluster's logger configuration.
// +optional
Log *LogSpec `json:"log,omitempty"`
Expand Down
40 changes: 40 additions & 0 deletions config/crd/bases/temporal.io_temporalclusters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,19 @@ spec:
image:
description: Image defines the temporal admin tools docker image the instance should run.
type: string
imageDigest:
description: |-
ImageDigest pins the temporal admin tools image to an immutable digest
(e.g. "sha256:abc..."). When set, it is appended to the image reference
(repository:tag@digest) so the running image cannot change behind a
mutable tag.
pattern: ^sha256:[a-fA-F0-9]{64}$
type: string
imageTag:
description: |-
ImageTag overrides the tag used for the temporal admin tools image. When
set, it is used instead of Version as the image tag.
type: string
overrides:
description: Overrides adds some overrides to the resources deployed for the ui.
properties:
Expand Down Expand Up @@ -450,6 +463,14 @@ spec:
image:
description: Image defines the temporal server docker image the cluster should use for each services.
type: string
imageDigest:
description: |-
ImageDigest pins the temporal server image to an immutable digest
(e.g. "sha256:abc..."). When set, it is appended to the image reference
(repository:tag@digest) so the running image cannot change behind a
mutable tag.
pattern: ^sha256:[a-fA-F0-9]{64}$
type: string
imagePullSecrets:
description: |-
An optional list of references to secrets in the same namespace
Expand All @@ -471,6 +492,12 @@ spec:
type: object
x-kubernetes-map-type: atomic
type: array
imageTag:
description: |-
ImageTag overrides the tag used for the temporal server image. When set,
it is used instead of Version as the image tag. Version still drives the
persistence schema version regardless of this override.
type: string
jobInitContainers:
description: JobInitContainers adds a list of init containers to the setup's jobs.
items:
Expand Down Expand Up @@ -3876,6 +3903,19 @@ spec:
image:
description: Image defines the temporal ui docker image the instance should run.
type: string
imageDigest:
description: |-
ImageDigest pins the temporal ui image to an immutable digest
(e.g. "sha256:abc..."). When set, it is appended to the image reference
(repository:tag@digest) so the running image cannot change behind a
mutable tag.
pattern: ^sha256:[a-fA-F0-9]{64}$
type: string
imageTag:
description: |-
ImageTag overrides the tag used for the temporal ui image. When set, it
is used instead of Version as the image tag.
type: string
ingress:
description: |-
Ingress is an optional ingress configuration for the UI.
Expand Down
166 changes: 166 additions & 0 deletions docs/api/v1beta1.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,35 @@ This version impacts the underlying persistence schemas versions.</p>
</tr>
<tr>
<td>
<code>imageTag</code><br>
<em>
string
</em>
</td>
<td>
<em>(Optional)</em>
<p>ImageTag overrides the tag used for the temporal server image. When set,
it is used instead of Version as the image tag. Version still drives the
persistence schema version regardless of this override.</p>
</td>
</tr>
<tr>
<td>
<code>imageDigest</code><br>
<em>
string
</em>
</td>
<td>
<em>(Optional)</em>
<p>ImageDigest pins the temporal server image to an immutable digest
(e.g. &ldquo;sha256:abc&hellip;&rdquo;). When set, it is appended to the image reference
(repository:tag@digest) so the running image cannot change behind a
mutable tag.</p>
</td>
</tr>
<tr>
<td>
<code>log</code><br>
<em>
<a href="#temporal.io/v1beta1.LogSpec">
Expand Down Expand Up @@ -4612,6 +4641,34 @@ string
</tr>
<tr>
<td>
<code>imageTag</code><br>
<em>
string
</em>
</td>
<td>
<em>(Optional)</em>
<p>ImageTag overrides the tag used for the temporal admin tools image. When
set, it is used instead of Version as the image tag.</p>
</td>
</tr>
<tr>
<td>
<code>imageDigest</code><br>
<em>
string
</em>
</td>
<td>
<em>(Optional)</em>
<p>ImageDigest pins the temporal admin tools image to an immutable digest
(e.g. &ldquo;sha256:abc&hellip;&rdquo;). When set, it is appended to the image reference
(repository:tag@digest) so the running image cannot change behind a
mutable tag.</p>
</td>
</tr>
<tr>
<td>
<code>resources</code><br>
<em>
<a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#resourcerequirements-v1-core">
Expand Down Expand Up @@ -4838,6 +4895,35 @@ This version impacts the underlying persistence schemas versions.</p>
</tr>
<tr>
<td>
<code>imageTag</code><br>
<em>
string
</em>
</td>
<td>
<em>(Optional)</em>
<p>ImageTag overrides the tag used for the temporal server image. When set,
it is used instead of Version as the image tag. Version still drives the
persistence schema version regardless of this override.</p>
</td>
</tr>
<tr>
<td>
<code>imageDigest</code><br>
<em>
string
</em>
</td>
<td>
<em>(Optional)</em>
<p>ImageDigest pins the temporal server image to an immutable digest
(e.g. &ldquo;sha256:abc&hellip;&rdquo;). When set, it is appended to the image reference
(repository:tag@digest) so the running image cannot change behind a
mutable tag.</p>
</td>
</tr>
<tr>
<td>
<code>log</code><br>
<em>
<a href="#temporal.io/v1beta1.LogSpec">
Expand Down Expand Up @@ -5297,6 +5383,32 @@ TemporalNamespaceArchivalSpec
If not set, the default cluster configuration is used.</p>
</td>
</tr>
<tr>
<td>
<code>customSearchAttributes</code><br>
<em>
map[string]string
</em>
</td>
<td>
<em>(Optional)</em>
<p>CustomSearchAttributes is an optional mapping of custom search attribute names to types.
Supported types: Text, Keyword, Int, Double, Bool, DateTime, KeywordList.</p>
</td>
</tr>
<tr>
<td>
<code>allowSearchAttributeDeletion</code><br>
<em>
bool
</em>
</td>
<td>
<em>(Optional)</em>
<p>AllowSearchAttributeDeletion makes the controller remove custom search attributes
from the Temporal server if they are not present in the spec.</p>
</td>
</tr>
</table>
</td>
</tr>
Expand Down Expand Up @@ -5521,6 +5633,32 @@ TemporalNamespaceArchivalSpec
If not set, the default cluster configuration is used.</p>
</td>
</tr>
<tr>
<td>
<code>customSearchAttributes</code><br>
<em>
map[string]string
</em>
</td>
<td>
<em>(Optional)</em>
<p>CustomSearchAttributes is an optional mapping of custom search attribute names to types.
Supported types: Text, Keyword, Int, Double, Bool, DateTime, KeywordList.</p>
</td>
</tr>
<tr>
<td>
<code>allowSearchAttributeDeletion</code><br>
<em>
bool
</em>
</td>
<td>
<em>(Optional)</em>
<p>AllowSearchAttributeDeletion makes the controller remove custom search attributes
from the Temporal server if they are not present in the spec.</p>
</td>
</tr>
</tbody>
</table>
</div>
Expand Down Expand Up @@ -6082,6 +6220,34 @@ string
</tr>
<tr>
<td>
<code>imageTag</code><br>
<em>
string
</em>
</td>
<td>
<em>(Optional)</em>
<p>ImageTag overrides the tag used for the temporal ui image. When set, it
is used instead of Version as the image tag.</p>
</td>
</tr>
<tr>
<td>
<code>imageDigest</code><br>
<em>
string
</em>
</td>
<td>
<em>(Optional)</em>
<p>ImageDigest pins the temporal ui image to an immutable digest
(e.g. &ldquo;sha256:abc&hellip;&rdquo;). When set, it is appended to the image reference
(repository:tag@digest) so the running image cannot change behind a
mutable tag.</p>
</td>
</tr>
<tr>
<td>
<code>replicas</code><br>
<em>
int32
Expand Down
68 changes: 68 additions & 0 deletions docs/features/image-pinning.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Pinning image tags and digests

By default the operator derives every container image tag from the configured
`version`: the server, web UI and admin tools images are all deployed as
`<image>:<version>`. This is convenient, but it means:

- the deployed tag is coupled to `version`, even though `version` also drives
the persistence schema migrations, and
- a mutable tag can be repointed upstream, so the running image can change
without any change to the `TemporalCluster` resource.

Each component (`spec`, `spec.ui`, `spec.admintools`) therefore exposes two
optional fields:

- **`imageTag`** — overrides the tag used for the image. When set, it is used
instead of `version`. For the server, `version` still drives the persistence
schema version regardless of this override — only the deployed image tag
changes. This is useful when an image is published with a tag that differs
from the Temporal version (for example admin-tools images).
- **`imageDigest`** — pins the image to an immutable digest (`sha256:...`). When
set, it is appended to the reference as `<image>:<tag>@<digest>`. The tag is
kept for readability while the digest guarantees the running image cannot
change behind a mutable tag. This is recommended for security-sensitive or
compliance-driven deployments (e.g. supply-chain / image-provenance
requirements).

Both fields are optional and can be combined. The resulting image reference is:

| `imageTag` | `imageDigest` | Resulting reference |
| ---------- | ------------- | ---------------------------- |
| unset | unset | `image:version` |
| set | unset | `image:imageTag` |
| unset | set | `image:version@digest` |
| set | set | `image:imageTag@digest` |

## Example: pin the server and UI to a digest

```yaml
apiVersion: temporal.io/v1beta1
kind: TemporalCluster
metadata:
name: prod
spec:
version: 1.28.2
image: temporalio/server
imageDigest: sha256:459aa877ef82c9a7f0ce688f2451ec8e576142c4efefecb2988d2f5f8b12699e
ui:
enabled: true
version: 2.44.1
image: temporalio/ui
imageDigest: sha256:0000000000000000000000000000000000000000000000000000000000000000
```

## Example: override the admin-tools tag

```yaml
apiVersion: temporal.io/v1beta1
kind: TemporalCluster
metadata:
name: prod
spec:
version: 1.28.2
admintools:
enabled: true
image: temporalio/admin-tools
# the admin-tools image for this version is published under a different tag
imageTag: 1.28.2-tctl-1.18.1-cli-0.13.2
```
Loading