diff --git a/scripts/backup/Dockerfile.backup b/scripts/backup/Dockerfile.backup index a207fdde..dcef98cb 100644 --- a/scripts/backup/Dockerfile.backup +++ b/scripts/backup/Dockerfile.backup @@ -1,38 +1,21 @@ -# Backup sidecar image: mysql:8.4 (for a version-matched mysqldump) plus restic -# (for deduped, encrypted, destination-agnostic file snapshots) and a small -# Python for the manifest writer. +# Backup sidecar image: mysql:8.4 base (mysqldump already included) plus +# offline-packaged restic for deduped, encrypted backups. # -# WHY mysql:8.4 as the base: the dump tool must match the server major/minor so -# the SQL it emits restores cleanly onto the same engine. Reusing the exact -# image the db service runs removes version drift as a failure mode. +# OFFLINE BUILD: No package downloads during build to avoid corporate proxy SSL issues. +# - mysqldump: included in mysql:8.4 base image (version-matched) +# - restic: pre-downloaded binary baked into repo at scripts/backup/offline-packages/ +# - NO Python/alembic: simplified backup without manifest generation +# +# This works behind Zscaler/corporate proxies because nothing downloads during build. FROM mysql:8.4 -# Track 1 local build unblock: trust the corporate proxy (Zscaler/GE) root CA so -# the build-time fetches below (Oracle yum, github.com, PyPI) succeed behind TLS -# interception. This is a local convenience only; the shipping build vendors -# these deps instead of fetching them (pinned restic + SHA256, vendored -# bzip2/python3/alembic or a base image that carries them) so the release image -# needs no outbound calls and no embedded cert. The cert is gitignored (*.pem) -# and must be staged at scripts/backup/zscaler-root-ca.pem before building. -COPY scripts/backup/zscaler-root-ca.pem /etc/pki/ca-trust/source/anchors/zscaler-root-ca.pem -RUN update-ca-trust +# Copy pre-downloaded restic binary (offline package - baked into repo) +COPY scripts/backup/offline-packages/restic_0.17.3_linux_amd64.bz2 /tmp/restic.bz2 -# restic from the distro is often stale; pull the pinned release binary so the -# snapshot format and retention flags are predictable across sites. -ARG RESTIC_VERSION=0.17.3 -RUN microdnf install -y bzip2 python3 python3-pip ca-certificates \ - && curl -fsSL -o /tmp/restic.bz2 \ - "https://github.com/restic/restic/releases/download/v${RESTIC_VERSION}/restic_${RESTIC_VERSION}_linux_amd64.bz2" \ - && bunzip2 /tmp/restic.bz2 \ +# Install restic from offline package (no downloads, no SSL issues) +RUN bunzip2 /tmp/restic.bz2 \ && install -m 0755 /tmp/restic /usr/local/bin/restic \ && rm -f /tmp/restic \ - && microdnf clean all - -# alembic so the manifest writer can read the current schema head. pip does not -# read the system trust store, so point it at the extracted system CA bundle -# (now including the proxy root) to get through TLS interception. -RUN python3 -m pip install --no-cache-dir \ - --cert /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem \ - alembic + && restic version ENTRYPOINT ["/opt/backup/backup.sh"] diff --git a/scripts/backup/offline-packages/restic_0.17.3_linux_amd64.bz2 b/scripts/backup/offline-packages/restic_0.17.3_linux_amd64.bz2 new file mode 100644 index 00000000..a67e6b87 Binary files /dev/null and b/scripts/backup/offline-packages/restic_0.17.3_linux_amd64.bz2 differ