|
| 1 | +# Backing up the production database to a Windows network share |
| 2 | + |
| 3 | +This page describes `scripts/oc-backup-db-to-unc.sh`, a variant of the standard |
| 4 | +backup script that streams a `pg_dump` of an instance's PostgreSQL database |
| 5 | +straight to a Windows UNC share — without ever creating a file on the WSL host. |
| 6 | + |
| 7 | +Use it when the backup must not be persisted on the local machine (for example, |
| 8 | +when capturing production into a managed file-share location such as |
| 9 | +`\\widget\SDPRDocuments`). |
| 10 | + |
| 11 | +## When to use this vs. `oc-backup-db.sh` |
| 12 | + |
| 13 | +| Question | Use `oc-backup-db.sh` | Use `oc-backup-db-to-unc.sh` | |
| 14 | +|----------|-----------------------|-------------------------------| |
| 15 | +| Output destination | `./backups/<file>.pgc` on the WSL host | `\\server\share\<file>.pgc` on Windows | |
| 16 | +| Local file allowed? | Yes | No — nothing is written locally | |
| 17 | +| Platform | Any host with `oc` | WSL only (uses `powershell.exe`) | |
| 18 | +| Restore workflow | Pass local file to `oc-restore-db.sh --from` | File must first be copied somewhere local before restore | |
| 19 | + |
| 20 | +## Prerequisites |
| 21 | + |
| 22 | +- WSL with Windows interop enabled (`powershell.exe` reachable at |
| 23 | + `/mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe`). |
| 24 | +- The UNC share is reachable from the Windows side and the current Windows |
| 25 | + user has write access to it. |
| 26 | +- `.oc-deploy/token` exists — created by `scripts/oc-setup-sa.sh` against the |
| 27 | + target namespace (e.g. `fd34fb-prod`). |
| 28 | +- The service account has `pods/exec` permission (granted during setup). |
| 29 | + |
| 30 | +## Usage |
| 31 | + |
| 32 | +```bash |
| 33 | +# Production (instance bcgov-di in namespace fd34fb-prod) |
| 34 | +./scripts/oc-backup-db-to-unc.sh --instance bcgov-di --dest '\\widget\SDPRDocuments' |
| 35 | + |
| 36 | +# Defaulting the instance to the current git branch |
| 37 | +./scripts/oc-backup-db-to-unc.sh --dest '\\widget\SDPRDocuments' |
| 38 | +``` |
| 39 | + |
| 40 | +Output file: `<dest>\<instance>-<YYYYMMDD-HHMMSS>.pgc`, e.g. |
| 41 | +`\\widget\SDPRDocuments\bcgov-di-20260515-082000.pgc`. |
| 42 | + |
| 43 | +The dump uses `pg_dump -Fc --clean --if-exists` (custom format with drop/recreate |
| 44 | +statements). Restore with `pg_restore` or the project's `oc-restore-db.sh`. |
| 45 | + |
| 46 | +## How "no local file" is achieved |
| 47 | + |
| 48 | +The standard `oc-backup-db.sh` writes the dump to `/tmp/...` inside the pod, |
| 49 | +then `oc cp`s it to the local filesystem. This script replaces the second |
| 50 | +step with a direct stream: |
| 51 | + |
| 52 | +1. `oc exec <pod> -c database -- pg_dump -Fc ...` writes the dump to stdout |
| 53 | + (no TTY, so the binary custom-format stream is preserved end-to-end). |
| 54 | +2. Bash pipes that stdout into `powershell.exe -NoProfile -Command '...'`. |
| 55 | +3. The PowerShell side reads raw bytes via `[Console]::OpenStandardInput()` |
| 56 | + and writes them to `[System.IO.File]::Create('<UNC path>')`. Using the |
| 57 | + stream APIs (not `Set-Content`) keeps the byte sequence intact — no |
| 58 | + CRLF translation, no implicit decoding. |
| 59 | +4. PowerShell then queries `Get-Item <dest>` for `.Length` and reports the |
| 60 | + byte count back. The dump itself is never opened for reading. |
| 61 | + |
| 62 | +No file is created on the WSL filesystem or on a local Windows drive — the |
| 63 | +bytes traverse the pipe and land on the network share. |
| 64 | + |
| 65 | +## Before-stream safety check |
| 66 | + |
| 67 | +Before invoking `pg_dump`, the script writes a 2-byte probe file to the |
| 68 | +destination via PowerShell and deletes it again. If the probe fails (share |
| 69 | +unreachable, no write permission, path doesn't exist), the script aborts |
| 70 | +before any database work begins. This avoids running a multi-minute dump only |
| 71 | +to discover the destination is unwritable. |
| 72 | + |
| 73 | +## Restoring a dump that lives on a network share |
| 74 | + |
| 75 | +`scripts/oc-restore-db.sh` expects a local file path, so to restore you must |
| 76 | +first copy the `.pgc` file to a location the restore script can read. |
| 77 | + |
| 78 | +```bash |
| 79 | +# From WSL, copy back via powershell.exe (or any Windows file-copy tool) |
| 80 | +powershell.exe -NoProfile -Command "Copy-Item '\\widget\SDPRDocuments\bcgov-di-20260515-082000.pgc' 'C:\temp\restore.pgc'" |
| 81 | +./scripts/oc-restore-db.sh --instance bcgov-di-test --from /mnt/c/temp/restore.pgc |
| 82 | +``` |
| 83 | + |
| 84 | +The restore script uses `pg_restore` and respects the `--clean --if-exists` |
| 85 | +flags baked into the dump, so existing data in the target instance is |
| 86 | +dropped and replaced. |
| 87 | + |
| 88 | +## What is *not* backed up |
| 89 | + |
| 90 | +The script captures only the PostgreSQL database. Azure Blob Storage content |
| 91 | +(uploaded documents, attachments, etc.) is **not** included; it must be |
| 92 | +backed up separately. This matches the behavior of `oc-backup-db.sh`. |
| 93 | + |
| 94 | +## Troubleshooting |
| 95 | + |
| 96 | +| Symptom | Likely cause | |
| 97 | +|---------|--------------| |
| 98 | +| `powershell.exe not found at /mnt/c/Windows/...` | Not running under WSL, or Windows interop is disabled. | |
| 99 | +| `Destination not writable` | UNC share is unreachable, or the Windows user lacks write permission. Try `powershell.exe -Command "Test-Path '<dest>'"` to verify. | |
| 100 | +| `Backup stream failed` | Either `oc exec` lost its connection, or the PowerShell side errored. A partial file may exist at the destination — delete it before retrying. | |
| 101 | +| `Token may have expired` | Re-run `./scripts/oc-setup-sa.sh --namespace <namespace>` to issue a fresh token. | |
| 102 | +| Backup file is much smaller than expected | The database may genuinely be small, but also check stderr from `pg_dump` (printed inline) for table-level errors. | |
0 commit comments