Retired workload (2026-10-23). The
rankstackDeployment, Services, Ingress, and replica-set Job no longer exist. The namespace, Secret, andrankstack-mongo-pvcremain. The PVC holds a static WiredTiger tree.kubectl scale deploy/rankstack-mongodoes not work. Recover the data with a temporarymongodpod that mounts a copy of the tree. Do not startmongodon the retained PVC. Do not recreate the old Deployment or route unless you intend to serve the app again.
Class C runs daily and includes the raw PVC:
rankstack/rankstack-mongo
/var/lib/rancher/k3s/storage/pvc-fb2fad5e-3e23-46cb-af88-659ecee047f6_rankstack_rankstack-mongo-pvc
The registry uses engine: file, so restic reads the tree directly. There is no mongodump target
in the current registry. A snapshot may still contain old archives under
var/backups/staging/class-C/mongo/rankstack-rankstack-mongo.archive.gz. Those archives are
historical. Use the raw WiredTiger tree for current recovery.
Measured 2026-10-23: the PVC holds 509 MB. The tree contains WiredTiger and journal/. The
2026-09-28 measurement of 369 MB allocated with 0 documents and 5 collections described the old
running database. It does not describe the current raw tree.
Run these commands on the node as root.
set -a; . /etc/vps-backup/env; set +a
export RESTIC_REPOSITORY=/var/backups/restic
restic snapshots --tag class-C
restic restore latest --tag class-C --target /var/tmp/recover-c
The tree is at:
/var/tmp/recover-c/var/lib/rancher/k3s/storage/pvc-fb2fad5e-3e23-46cb-af88-659ecee047f6_rankstack_rankstack-mongo-pvc
Restic password: ansible/group_vars/vps/secrets.sops.yaml, key restic_password. The owner’s
password manager also holds it. Without it, the snapshot is unreadable.
Copy the tree. Mongo writes to the data directory during startup and recovery. Never point it at the retained PVC.
SRC=/var/tmp/recover-c/var/lib/rancher/k3s/storage/pvc-fb2fad5e-3e23-46cb-af88-659ecee047f6_rankstack_rankstack-mongo-pvc
DST=/var/tmp/mongo-recover
install -d -m 700 "$DST"
cp -a "$SRC"/. "$DST"/
chown -R 999:999 "$DST"
Create a temporary pod in the rankstack namespace. It uses a hostPath volume for the copy. It
has no Service and no Ingress.
NS=rankstack
kubectl apply -n "$NS" -f - <<'EOF'
apiVersion: v1
kind: Pod
metadata:
name: mongo-recover
spec:
restartPolicy: Never
containers:
- name: mongod
image: mongo:7
command: ["mongod", "--dbpath", "/scratch", "--bind_ip", "127.0.0.1"]
volumeMounts:
- {name: data, mountPath: /scratch}
resources:
requests: {memory: 256Mi}
limits: {memory: 1Gi}
volumes:
- name: data
hostPath: {path: /var/tmp/mongo-recover, type: Directory}
EOF
Use the image the old Deployment used if mongo:7 cannot read the tree. The image version must
support the WiredTiger format. Do not run mongod --repair on the retained PVC.
Wait for the server:
until kubectl -n "$NS" exec mongo-recover -- mongosh --quiet --eval 'db.runCommand({ping:1}).ok' >/dev/null 2>&1; do
sleep 3
done
The database name is rankstack in the old deployment. Confirm it before you dump.
kubectl -n "$NS" exec mongo-recover -- mongosh --quiet --eval \
'db.adminCommand({listDatabases:1}).databases.map(d => d.name)'
kubectl -n "$NS" exec mongo-recover -- sh -c \
'mongodump --db rankstack --archive=/tmp/recovered.archive.gz --gzip'
kubectl cp "$NS"/mongo-recover:/tmp/recovered.archive.gz /var/tmp/recovered.archive.gz
Validate the archive before you delete anything:
kubectl -n "$NS" exec mongo-recover -- sh -c \
'mongorestore --archive=/tmp/recovered.archive.gz --gzip --dryRun'
--dryRun lists what would restore and does not write. If the archive is valid, keep it. Do not
import it into a live database until the app owner confirms the target.
Use this only for an old rankstack-rankstack-mongo.archive.gz from a snapshot. Start a scratch
mongo:7 instance on an empty directory. The old registry set oplog: true, so those archives
were taken with mongodump --oplog. Restore them with --oplogReplay. Without that flag the restore
stops at the dump start and discards the captured oplog. --oplogReplay works against a standalone
scratch instance. It does not require a replica set.
kubectl -n "$NS" cp /var/tmp/old.archive.gz mongo-recover:/tmp/old.archive.gz
kubectl -n "$NS" exec mongo-recover -- sh -c \
'mongorestore --archive=/tmp/old.archive.gz --gzip --oplogReplay --drop'
Do not add --oplogReplay to the current raw-tree path or to a dump that was not taken with
--oplog. The current registry has no mongo target.
The old S0 bundle has no usable Mongo copy. Restic is the only source.
kubectl -n "$NS" delete pod mongo-recover
rm -rf /var/tmp/mongo-recover /var/tmp/recover-c
Delete the temporary pod. Do not delete the PVC, the PV, or the Secret. Do not leave a mongod
process on the retained tree.
The raw-tree check is part of the class-C restore drill on the 15th at 06:00 UTC. The drill finds
WiredTiger at depth 4 and requires a non-empty file plus a sibling journal/ directory. It does
not run mongod and does not compare document counts. The last known document count (0 on
2026-09-28) was measured against the old running database and is historical.