All checks were successful
CD / Build and push images (push) Successful in 3m51s
CI / Lint, typecheck, test (push) Successful in 4m5s
CD / Deploy to Test (push) Successful in 11s
CI / Build container images (push) Has been skipped
CD / Smoke tests against Test (push) Successful in 1m11s
CD / Promote to Int (push) Successful in 12s
CI / Auth e2e pack (push) Successful in 5m52s
CI / Import/export fidelity gate (push) Successful in 47s
The operator-level extra beside the admin-configured Nextcloud target (#103), unblocked now that the ONE→BASEL tunnel is stable again. - sidecar: optional mirror step (mirror.ts) driven purely by env — BACKUP_MIRROR_TARGET (rsync-over-ssh), BACKUP_MIRROR_SSH_KEY (private key on the secrets volume, never in image or repo), BACKUP_MIRROR_SSH_PORT. Runs after the prune of every successful run, so --delete aligns the remote retention with the local one (the newest-complete-set guarantee carries over). Only set files travel (db-*.dump, files-*.tar.gz); status files and bundles stay local. Host key pinned via accept-new into .mirror_known_hosts on the backups volume; fixed remote modes (dirs 750, files 640, symbolic --chmod — octal needs rsync ≥ 3, macOS dev machines ship 2.6.9). rsync + openssh-client added to the sidecar image. - status: additive `mirror` block in status.json (outcome, transferred count, lastSuccessAt carried across failures) — shown on the admin backup card; failures alert via a new backupMirrorFailed mail (de+en) while the local run still counts as succeeded. - deploy/backup-basel.md: complete BASEL-side walkthrough — dedicated user dorfteich-backup with a /home/ home and a bash login shell, explicitly avoiding the Debian backup-user (UID 34) pitfalls (nologin shell rejects rsync sessions, /var/backups home), key placement through the api container onto the secrets volume, .env values, on-demand verification. - tests: rsync-arg/stats-parsing units plus an integration suite against the real rsync binary (local target; skips where rsync is absent) — transfer, idempotent re-run (0 files), retention alignment, failure path carrying lastSuccessAt. Verified live against the real BASEL host from a native sidecar run: initial transfer, host-key pinning, retention alignment after a local prune, idempotency, and the failure path (surfaced in status.json while the local run stayed green). BASEL side provisioned per the doc. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EwZ4jR4KFAPvpjWevfUGX1
33 lines
1.4 KiB
Docker
33 lines
1.4 KiB
Docker
# Build context is the repository root (workspace build):
|
|
# docker build -f apps/backup/Dockerfile .
|
|
|
|
FROM node:22.15-alpine AS build
|
|
WORKDIR /repo
|
|
RUN npm install -g pnpm@11
|
|
COPY pnpm-workspace.yaml pnpm-lock.yaml package.json tsconfig.base.json ./
|
|
COPY packages/shared ./packages/shared
|
|
COPY apps/backup ./apps/backup
|
|
RUN pnpm install --frozen-lockfile --filter @dorfteich/backup... \
|
|
&& pnpm --filter @dorfteich/shared build \
|
|
&& pnpm --filter @dorfteich/backup build \
|
|
# Self-contained production bundle (prod deps only) at /out.
|
|
&& pnpm --filter @dorfteich/backup deploy --prod --legacy /out \
|
|
&& cp -r apps/backup/dist /out/dist
|
|
|
|
FROM node:22.15-alpine
|
|
ARG APP_VERSION=0.0.0-dev
|
|
ENV NODE_ENV=production APP_VERSION=${APP_VERSION} \
|
|
# Baked-in volume paths (self-sufficient without compose env, like the
|
|
# api image's PLUGINS_DIR — issue #71's lesson).
|
|
BACKUPS_DIR=/backups UPLOADS_DIR=/data/uploads PLUGINS_DIR=/data/plugins \
|
|
SECRETS_FILE=/data/secrets/secrets.env
|
|
# pg_dump/pg_restore matching the stack's postgres:17 server, GNU tar for the
|
|
# volume archives, tzdata so BACKUP_TIME honors a configured TZ, and
|
|
# rsync + ssh for the optional off-host mirror (issue #84).
|
|
RUN apk add --no-cache postgresql17-client tar tzdata rsync openssh-client \
|
|
&& mkdir -p /backups && chown node:node /backups
|
|
WORKDIR /app
|
|
COPY --from=build --chown=node:node /out /app
|
|
USER node
|
|
CMD ["node", "dist/index.js"]
|