Compare commits

...
Sign in to create a new pull request.

15 commits

Author SHA1 Message Date
CTO
c97a2d218e chore(stalwart): bump v0.16.11 -> v0.16.18 (DEV-542)
Transport-only patch bump. No auth/OIDC/config changes.
Snapshots (config.json, DB dump, live YAML) attached to DEV-542.
Rollback: git revert; ArgoCD resyncs; PVCs retained.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-08-23 16:46:31 +00:00
CTO
e69e3d8eb4 chore(restic): bump image 0.17.3 -> 0.19.1 (DEV-541)
Mirrored docker.io/restic/restic:0.19.1 to
harbor.basicstack.de/library/restic:0.19.1 (crane in-cluster Job).
Updated all CronJob pins and the restore-drill/tag-bump docs.

Digest: sha256:136600b6ff6843d61d355f7f71f460a166429f35de6fd11b568fece3c9a4d510

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-08-23 15:52:15 +00:00
CTO Agent
96c3846202 chore(stalwart): bump alpine 3.19 -> 3.24 in backup cronjob (DEV-539)
Only occurrence of plain alpine:3.19 across apps/**. Touches:
- apps/stalwart/stalwart-fresh-deployment.yaml (stalwart-backup CronJob container)

Scope excludes alpine/k8s (see DEV-520 majors phase).

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-08-23 15:42:36 +00:00
CTO Agent
76e250c334 fix(opencloud): use Recreate rollout strategy for RWO PVC (DEV-538)
The 7.2.0 -> 7.4.0 rollout stalled because the default RollingUpdate
tried to start the new pod before terminating the old one, but they
both mount opencloud-data (RWO), causing Multi-Attach errors.

Switch to strategy: Recreate so the old pod is terminated first and
the volume detaches cleanly before the new pod starts. Same fix
pattern as bookstack (DEV-528) and other RWO-backed apps.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-08-23 15:39:17 +00:00
CTO Agent
0887f87c82 chore(opencloud): bump 7.2.0 -> 7.4.0 (DEV-538)
Skimmed 7.3.0 (2026-07-14) and 7.4.0 (2026-08-03) release notes: no
breaking changes, no config or index migrations required.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-08-23 15:35:03 +00:00
CTO
a7e81db4e1 chore(directus): bump 12.1.1 -> 12.3.0 (DEV-537)
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-08-23 15:27:14 +00:00
CTO
777a4d0404 chore(pocket-id): bump v2.11.0 -> v2.14.0 (DEV-536)
Minor version bump of the cluster OIDC provider. No breaking changes;
multi-client-secret support in 2.14 is additive; SameSite=Lax cookie
default in 2.13 is standard. DB snapshot captured pre-rollout.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-08-23 15:18:23 +00:00
CTO
3317401eba chore(headlamp): bump v0.43.0 -> v0.45.0 (DEV-535)
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-08-23 15:14:38 +00:00
CTO Agent
71496fc5ac chore(dozzle): bump v10.6.10 -> v10.7.3 (DEV-534)
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-08-23 15:11:47 +00:00
CTO Agent
6313b85999 chore(pangolin): bump postgres 17.5 -> 17.11 (DEV-533)
Patch bump per DEV-520 plan. Only pangolin uses postgres:17.5*;
other apps (paperclip, directus, forgejo, stalwart) are on
postgres:16-alpine and are out of scope for this ticket.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-08-23 15:07:38 +00:00
CTO Agent
7cbb603ec1 chore(pangolin): bump busybox 1.37 -> 1.38.0 (DEV-532)
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-08-23 15:02:26 +00:00
CTO Agent
a226958b16 chore(paperclip): bump busybox 1.36 -> 1.38.0 (DEV-531)
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-08-23 14:59:34 +00:00
CTO Agent
e6a94ae26a chore(stalwart): remove no-op stalwart-allow-cluster-ips job (DEV-530)
The Job self-deletes after ttlSecondsAfterFinished=3600, causing ArgoCD
to report the app permanently OutOfSync. The job body only hits
/healthz/live and prints a manual TODO; it never modified Stalwart
config. The real IP allowlist is already declared in
apps/stalwart/stalwart-config.yaml under
[server.listener.*.security] allowed-ips.

Also removes the orphan ServiceAccount/Role/RoleBinding
stalwart-config-access bundled in the same file.

Board approval: DEV-529 interaction 9472bc9b-93d7-44e2-b32b-cf5598480f9a.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-08-23 14:18:26 +00:00
e9fcf4cbb4 fix(bookstack): Recreate rollout strategy for RWO PVC (DEV-528) (#8) 2026-08-23 12:01:49 +00:00
cto-agent
e155ab6a17 fix(bookstack): use Recreate rollout strategy (DEV-528)
BookStack is a single-replica Deployment backed by a ReadWriteOnce
PVC (`bookstack-config`). The default RollingUpdate strategy creates
the new pod before terminating the old one, and the two pods cannot
share the RWO volume — so every rollout deadlocks on
`Multi-Attach error for volume`.

Switching to `strategy: Recreate` terminates the old pod first,
releases the PVC, and then starts the new pod. Brief downtime is
expected on rollout, but rollouts actually complete.

Discovered while rolling out the `/status` probe fix (previous commit).

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-08-23 12:01:35 +00:00
18 changed files with 30 additions and 149 deletions

View file

@ -100,6 +100,8 @@ metadata:
namespace: bookstack namespace: bookstack
spec: spec:
replicas: 1 replicas: 1
strategy:
type: Recreate
selector: selector:
matchLabels: matchLabels:
app: bookstack app: bookstack

View file

@ -35,7 +35,7 @@ spec:
fsGroup: 1000 fsGroup: 1000
containers: containers:
- name: directus - name: directus
image: directus/directus:12.1.1 image: directus/directus:12.3.0
ports: ports:
- name: http - name: http
containerPort: 8055 containerPort: 8055

View file

@ -18,7 +18,7 @@ spec:
serviceAccountName: dozzle serviceAccountName: dozzle
containers: containers:
- name: dozzle - name: dozzle
image: amir20/dozzle:v10.6.10 image: amir20/dozzle:v10.7.3
ports: ports:
- containerPort: 8080 - containerPort: 8080
name: dozzle-http name: dozzle-http

View file

@ -96,7 +96,7 @@ spec:
memory: 512Mi memory: 512Mi
containers: containers:
- name: restic - name: restic
image: harbor.basicstack.de/library/restic:0.17.3 image: harbor.basicstack.de/library/restic:0.19.1
env: env:
- name: AWS_ACCESS_KEY_ID - name: AWS_ACCESS_KEY_ID
valueFrom: valueFrom:

View file

@ -16,7 +16,7 @@ spec:
serviceAccountName: headlamp-admin serviceAccountName: headlamp-admin
containers: containers:
- name: headlamp - name: headlamp
image: ghcr.io/headlamp-k8s/headlamp:v0.43.0 image: ghcr.io/headlamp-k8s/headlamp:v0.45.0
imagePullPolicy: IfNotPresent imagePullPolicy: IfNotPresent
args: args:
- "-in-cluster" - "-in-cluster"

View file

@ -2,7 +2,7 @@
Manifests recording the cluster-side monitoring backup CronJobs that were previously applied out-of-band. These files are the authoritative source (`kubectl apply -f apps/monitoring/`). See [DEV-464](/DEV/issues/DEV-464) for the repair context. Manifests recording the cluster-side monitoring backup CronJobs that were previously applied out-of-band. These files are the authoritative source (`kubectl apply -f apps/monitoring/`). See [DEV-464](/DEV/issues/DEV-464) for the repair context.
- `backup-k8s-resources-cronjob.yaml` — daily dump of cluster-scoped and per-namespace Kubernetes resources, streamed through `restic backup --stdin` to `hetzner-s3:${BUCKET}/restic/k8s-resources`. Uses `serviceAccountName: backup-sa` and no PVC mount (init container `alpine/k8s:1.29.4` writes an emptyDir, main container `restic/restic:0.17.3` reads it on stdin). Rewritten from the local-path tarball per the [DEV-482](/DEV/issues/DEV-482) Option 4 rollout ([DEV-487](/DEV/issues/DEV-487)). - `backup-k8s-resources-cronjob.yaml` — daily dump of cluster-scoped and per-namespace Kubernetes resources, streamed through `restic backup --stdin` to `hetzner-s3:${BUCKET}/restic/k8s-resources`. Uses `serviceAccountName: backup-sa` and no PVC mount (init container `alpine/k8s:1.29.4` writes an emptyDir, main container `restic/restic:0.19.1` reads it on stdin). Rewritten from the local-path tarball per the [DEV-482](/DEV/issues/DEV-482) Option 4 rollout ([DEV-487](/DEV/issues/DEV-487)).
- `backup-loki-restic-cronjob.yaml` — daily restic backup of `loki-storage-encrypted` to `hetzner-s3:${BUCKET}/restic/loki`. Co-schedules with the Loki pod via `podAffinity` (RWO permits additional read-only mounts on the same node). Deployed per the [DEV-482](/DEV/issues/DEV-482) Option 4 rollout ([DEV-485](/DEV/issues/DEV-485)). - `backup-loki-restic-cronjob.yaml` — daily restic backup of `loki-storage-encrypted` to `hetzner-s3:${BUCKET}/restic/loki`. Co-schedules with the Loki pod via `podAffinity` (RWO permits additional read-only mounts on the same node). Deployed per the [DEV-482](/DEV/issues/DEV-482) Option 4 rollout ([DEV-485](/DEV/issues/DEV-485)).
- `backup-grafana-restic-cronjob.yaml` — daily restic backup of `grafana-storage` to `hetzner-s3:${BUCKET}/restic/grafana`. Pinned to `k3s-worker-2` via `nodeSelector` (the local-path PV anchors the grafana pod there already, no `podAffinity` needed). Schedule `15 3 * * *` — offset from the loki run at `03:00`. Deployed per the [DEV-482](/DEV/issues/DEV-482) Option 4 rollout ([DEV-486](/DEV/issues/DEV-486)). - `backup-grafana-restic-cronjob.yaml` — daily restic backup of `grafana-storage` to `hetzner-s3:${BUCKET}/restic/grafana`. Pinned to `k3s-worker-2` via `nodeSelector` (the local-path PV anchors the grafana pod there already, no `podAffinity` needed). Schedule `15 3 * * *` — offset from the loki run at `03:00`. Deployed per the [DEV-482](/DEV/issues/DEV-482) Option 4 rollout ([DEV-486](/DEV/issues/DEV-486)).
- `prometheus-backup-cronjob.yaml` + `prometheus-backup-sealed.yaml` — daily restic backup of `prometheus-data-encrypted` to `hetzner-s3:${BUCKET}/restic/prometheus`. Co-schedules with the Prometheus pod via `podAffinity` so the RWO PVC attaches on the same node. Schedule `30 3 * * *` — offset from the loki (03:00) and grafana (03:15) runs. Migrated from the DEV-465 `rclone sync` job to restic client-side encryption per [DEV-492](/DEV/issues/DEV-492) / [DEV-482](/DEV/issues/DEV-482) Option 4. **Compaction-race mitigation:** `--exclude wal/*` + `--exclude chunks_head/*` + accept `restic backup` exit code 3 (source file vanished mid-walk) as a warning, not a failure; restore drill re-runs `promtool tsdb analyze` per block. - `prometheus-backup-cronjob.yaml` + `prometheus-backup-sealed.yaml` — daily restic backup of `prometheus-data-encrypted` to `hetzner-s3:${BUCKET}/restic/prometheus`. Co-schedules with the Prometheus pod via `podAffinity` so the RWO PVC attaches on the same node. Schedule `30 3 * * *` — offset from the loki (03:00) and grafana (03:15) runs. Migrated from the DEV-465 `rclone sync` job to restic client-side encryption per [DEV-492](/DEV/issues/DEV-492) / [DEV-482](/DEV/issues/DEV-482) Option 4. **Compaction-race mitigation:** `--exclude wal/*` + `--exclude chunks_head/*` + accept `restic backup` exit code 3 (source file vanished mid-walk) as a warning, not a failure; restore drill re-runs `promtool tsdb analyze` per block.

View file

@ -44,8 +44,8 @@ spec:
kubernetes.io/hostname: k3s-worker-2 kubernetes.io/hostname: k3s-worker-2
containers: containers:
- name: restic - name: restic
image: harbor.basicstack.de/library/restic:0.17.3 image: harbor.basicstack.de/library/restic:0.19.1
# Mirrored from docker.io/restic/restic:0.17.3 (DEV-493) — # Mirrored from docker.io/restic/restic:0.19.1 (DEV-493) —
# deterministic ingress via Harbor. Retag procedure in # deterministic ingress via Harbor. Retag procedure in
# docs/monitoring/restic-restore.md § "Tag-bump procedure". # docs/monitoring/restic-restore.md § "Tag-bump procedure".
env: env:

View file

@ -11,7 +11,7 @@
# 1. `kubectl-dump` init container (`alpine/k8s:1.29.4`) writes # 1. `kubectl-dump` init container (`alpine/k8s:1.29.4`) writes
# /dump/cluster.yaml into an emptyDir. Uses `serviceAccountName: # /dump/cluster.yaml into an emptyDir. Uses `serviceAccountName:
# backup-sa` (unchanged from the legacy job). # backup-sa` (unchanged from the legacy job).
# 2. `restic` main container (`restic/restic:0.17.3`, matches the # 2. `restic` main container (`restic/restic:0.19.1`, matches the
# loki/grafana siblings) reads that file on stdin and streams it # loki/grafana siblings) reads that file on stdin and streams it
# into the restic repo with `--stdin-filename cluster.yaml`. # into the restic repo with `--stdin-filename cluster.yaml`.
apiVersion: batch/v1 apiVersion: batch/v1
@ -90,8 +90,8 @@ spec:
mountPath: /dump mountPath: /dump
containers: containers:
- name: restic - name: restic
image: harbor.basicstack.de/library/restic:0.17.3 image: harbor.basicstack.de/library/restic:0.19.1
# Mirrored from docker.io/restic/restic:0.17.3 (DEV-493) — # Mirrored from docker.io/restic/restic:0.19.1 (DEV-493) —
# deterministic ingress via Harbor. Retag procedure in # deterministic ingress via Harbor. Retag procedure in
# docs/monitoring/restic-restore.md § "Tag-bump procedure". # docs/monitoring/restic-restore.md § "Tag-bump procedure".
env: env:

View file

@ -53,8 +53,8 @@ spec:
topologyKey: kubernetes.io/hostname topologyKey: kubernetes.io/hostname
containers: containers:
- name: restic - name: restic
image: harbor.basicstack.de/library/restic:0.17.3 image: harbor.basicstack.de/library/restic:0.19.1
# Mirrored from docker.io/restic/restic:0.17.3 (DEV-493) — # Mirrored from docker.io/restic/restic:0.19.1 (DEV-493) —
# deterministic ingress via Harbor. Retag procedure in # deterministic ingress via Harbor. Retag procedure in
# docs/monitoring/restic-restore.md § "Tag-bump procedure". # docs/monitoring/restic-restore.md § "Tag-bump procedure".
env: env:

View file

@ -81,7 +81,7 @@ spec:
topologyKey: kubernetes.io/hostname topologyKey: kubernetes.io/hostname
containers: containers:
- name: restic - name: restic
image: harbor.basicstack.de/library/restic:0.17.3 image: harbor.basicstack.de/library/restic:0.19.1
env: env:
- name: AWS_ACCESS_KEY_ID - name: AWS_ACCESS_KEY_ID
valueFrom: valueFrom:

View file

@ -42,6 +42,8 @@ metadata:
namespace: opencloud namespace: opencloud
spec: spec:
replicas: 1 replicas: 1
strategy:
type: Recreate
selector: selector:
matchLabels: matchLabels:
app: opencloud app: opencloud
@ -56,7 +58,7 @@ spec:
runAsNonRoot: true runAsNonRoot: true
initContainers: initContainers:
- name: init-dirs - name: init-dirs
image: opencloudeu/opencloud-rolling:7.2.0 image: opencloudeu/opencloud-rolling:7.4.0
command: command:
- sh - sh
- -c - -c
@ -71,7 +73,7 @@ spec:
runAsNonRoot: true runAsNonRoot: true
containers: containers:
- name: opencloud - name: opencloud
image: opencloudeu/opencloud-rolling:7.2.0 image: opencloudeu/opencloud-rolling:7.4.0
command: command:
- /bin/sh - /bin/sh
- -c - -c

View file

@ -35,7 +35,7 @@ spec:
spec: spec:
initContainers: initContainers:
- name: wait-for-postgres - name: wait-for-postgres
image: postgres:17.5 image: postgres:17.11
command: command:
- /bin/sh - /bin/sh
- -c - -c
@ -58,7 +58,7 @@ spec:
name: pangolin-postgres-secrets name: pangolin-postgres-secrets
key: postgres-db key: postgres-db
- name: render-config - name: render-config
image: busybox:1.37 image: busybox:1.38.0
command: command:
- /bin/sh - /bin/sh
- -c - -c

View file

@ -57,7 +57,7 @@ spec:
fsGroup: 999 fsGroup: 999
containers: containers:
- name: postgres - name: postgres
image: postgres:17.5 image: postgres:17.11
imagePullPolicy: IfNotPresent imagePullPolicy: IfNotPresent
ports: ports:
- containerPort: 5432 - containerPort: 5432

View file

@ -20,7 +20,7 @@ spec:
fsGroupChangePolicy: Always fsGroupChangePolicy: Always
initContainers: initContainers:
- name: fix-permissions - name: fix-permissions
image: busybox:1.36 image: busybox:1.38.0
command: command:
- sh - sh
- -c - -c

View file

@ -17,7 +17,7 @@ spec:
spec: spec:
containers: containers:
- name: pocket-id - name: pocket-id
image: ghcr.io/pocket-id/pocket-id:v2.11.0 image: ghcr.io/pocket-id/pocket-id:v2.14.0
imagePullPolicy: IfNotPresent imagePullPolicy: IfNotPresent
ports: ports:
- containerPort: 1411 - containerPort: 1411

View file

@ -1,123 +0,0 @@
---
# One-time Job to configure Stalwart HTTP listener to allow internal cluster IPs
#
# Problem: Stalwart blocks the HTTP port from Traefik's pod IP (10.244.2.227),
# causing 502/503 errors when accessing mail.basicstack.de
#
# Solution: Use kubectl exec to access Stalwart's admin API via localhost (which is allowed)
# and disable IP filtering for the HTTP listener, or allow the pod network CIDR
#
# This Job must be manually triggered after Stalwart is running:
# kubectl create job --from=cronjob/stalwart-allow-cluster-ips manual-fix -n stalwart
#
# Or apply directly:
# kubectl apply -f stalwart-allow-cluster-ips-job.yaml
# kubectl wait --for=condition=complete job/stalwart-allow-cluster-ips -n stalwart --timeout=120s
# kubectl logs -n stalwart job/stalwart-allow-cluster-ips
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: stalwart-config-access
namespace: stalwart
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: stalwart-config-access
namespace: stalwart
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]
- apiGroups: [""]
resources: ["pods/exec"]
verbs: ["create"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get"]
resourceNames: ["stalwart-admin-credentials"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: stalwart-config-access
namespace: stalwart
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: stalwart-config-access
subjects:
- kind: ServiceAccount
name: stalwart-config-access
namespace: stalwart
---
apiVersion: batch/v1
kind: Job
metadata:
name: stalwart-allow-cluster-ips
namespace: stalwart
spec:
ttlSecondsAfterFinished: 3600 # Keep logs for 1 hour
backoffLimit: 3
template:
metadata:
labels:
app: stalwart-security-fix
spec:
serviceAccountName: stalwart-config-access
restartPolicy: OnFailure
containers:
- name: fix-security
image: bitnami/kubectl:latest
command:
- /bin/bash
- -c
- |
set -e
echo "=== Stalwart HTTP Listener Security Fix ==="
echo "Configuring Stalwart to allow internal cluster IPs for the HTTP listener"
echo ""
# Wait for Stalwart pod to be ready
echo "Waiting for stalwart-0 pod to be ready..."
kubectl wait --for=condition=ready pod/stalwart-0 -n stalwart --timeout=180s
# Get admin credentials
echo "Retrieving admin credentials..."
ADMIN_EMAIL=$(kubectl get secret stalwart-admin-credentials -n stalwart -o jsonpath='{.data.admin-email}' | base64 -d)
ADMIN_PASSWORD=$(kubectl get secret stalwart-admin-credentials -n stalwart -o jsonpath='{.data.admin-password}' | base64 -d)
echo "Admin email: $ADMIN_EMAIL"
# Use kubectl exec to access Stalwart's admin API from localhost
# The HTTP listener allows localhost connections even when blocking other IPs
echo ""
echo "Accessing Stalwart admin API via kubectl exec..."
# Test API access first
echo "Testing API connectivity..."
kubectl exec -n stalwart stalwart-0 -- curl -s -u "$ADMIN_EMAIL:$ADMIN_PASSWORD" \
http://localhost:8080/healthz/live
# Note: The actual API endpoint structure for v0.16.11 may vary
# The web UI uses a REST API, but the exact endpoints for security config
# need to be determined from the Stalwart documentation or by inspecting
# the web UI's network traffic.
echo ""
echo "✅ Successfully connected to Stalwart API"
echo ""
echo "IMPORTANT: This Job demonstrates API connectivity."
echo "The actual security configuration change requires:"
echo "1. Identifying the correct API endpoint for security settings"
echo "2. Sending the appropriate PUT/POST request to allow cluster IPs"
echo ""
echo "Recommended manual fix:"
echo "1. Temporarily port-forward: kubectl port-forward -n stalwart svc/stalwart-http 8080:8080"
echo "2. Access https://mail.basicstack.de from your browser"
echo "3. Login with admin credentials"
echo "4. Navigate to Settings > Security"
echo "5. Disable IP filtering for the HTTP listener or add 10.244.0.0/16 to allowed IPs"
exit 0

View file

@ -122,7 +122,7 @@ spec:
mountPath: /var/lib/stalwart mountPath: /var/lib/stalwart
containers: containers:
- name: stalwart - name: stalwart
image: stalwartlabs/stalwart:v0.16.11 image: stalwartlabs/stalwart:v0.16.18
ports: ports:
- containerPort: 25 - containerPort: 25
name: smtp name: smtp
@ -316,7 +316,7 @@ spec:
topologyKey: kubernetes.io/hostname topologyKey: kubernetes.io/hostname
containers: containers:
- name: backup - name: backup
image: alpine:3.19 image: alpine:3.24
command: command:
- /bin/sh - /bin/sh
- -c - -c

View file

@ -70,7 +70,7 @@ spec:
restartPolicy: Never restartPolicy: Never
containers: containers:
- name: restic - name: restic
image: harbor.basicstack.de/library/restic:0.17.3 # matches CronJob image (DEV-493) image: harbor.basicstack.de/library/restic:0.19.1 # matches CronJob image (DEV-493, bumped in DEV-541)
command: ["sleep", "3600"] command: ["sleep", "3600"]
env: env:
- { name: AWS_ACCESS_KEY_ID, valueFrom: { secretKeyRef: { name: monitoring-s3-backup, key: access-key } } } - { name: AWS_ACCESS_KEY_ID, valueFrom: { secretKeyRef: { name: monitoring-s3-backup, key: access-key } } }
@ -240,9 +240,9 @@ All three restic CronJobs (`backup-loki-restic`, `backup-grafana-restic`,
keep the backup pipeline off the Docker Hub pull path and immune to keep the backup pipeline off the Docker Hub pull path and immune to
upstream retagging: upstream retagging:
- Manifest reference: `harbor.basicstack.de/library/restic:0.17.3` - Manifest reference: `harbor.basicstack.de/library/restic:0.19.1`
- Upstream: `docker.io/restic/restic:0.17.3` - Upstream: `docker.io/restic/restic:0.19.1`
- Ticket: [DEV-493](/DEV/issues/DEV-493) - Ticket: [DEV-493](/DEV/issues/DEV-493) (bumped to 0.19.1 in [DEV-541](/DEV/issues/DEV-541))
The `library` project is public, so no `imagePullSecret` is required The `library` project is public, so no `imagePullSecret` is required
on the CronJob pods. on the CronJob pods.