From 76e3239d5455cc98d76dc5b5db1277b3de178633 Mon Sep 17 00:00:00 2001 From: Roman Priesol Date: Wed, 9 Sep 2026 14:13:42 +0200 Subject: [PATCH] Tidy the deploy checkout into build/, symlink docker-compose.yaml up MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sources now sync into /srv/podman/maptool/build/ (wiped and fully replaced every deploy, nothing in it needs preserving) instead of directly into /srv/podman/maptool/ itself, where data/ and .env also live — the old sync step had to specifically skip data/ by name to avoid wiping it; this way there's nothing to skip. docker-compose.yaml is symlinked (ln -sf, relative target) from /srv/podman/maptool/ up to build/ — both for a human to still find it at the top, and because that symlink's own location, not build/, is what compose resolves ./data and .env's directory against. No changes to docker-compose.yaml or the podman-compose@.service systemd unit's WorkingDirectory needed. Verified against a full local dry run of the new sync step (copy into a fake build/, symlink up, confirm pre-existing data/ survives) and `docker-compose config` against the real docker-compose.yaml through that symlink — both volume mounts (./data, the kiwix ZIM path) resolved to the sibling data/ directory as intended, not build/data. --- .gitea/workflows/ci.yml | 33 ++++++++++++++++++-------------- docs/deployment.adoc | 42 +++++++++++++++++++++++++++++------------ 2 files changed, 49 insertions(+), 26 deletions(-) diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 9bf5c71..51071f8 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -62,21 +62,26 @@ jobs: - name: Write REVISION run: git rev-parse --short HEAD > REVISION - # Clears out everything in the target except data/ (uploaded GPX - # files, offline.pmtiles) and copies the fresh checkout over, dropping - # .git afterwards. Dotfiles like .env (deployment secrets) are left - # alone too — the glob below doesn't match them — and neither is ever - # part of the git checkout in the first place, since both are - # gitignored. - - name: Sync to /srv/podman/maptool + # The checkout lives in build/, wiped and fully replaced every + # deploy — data/ and .env live one level up, in /srv/podman/maptool/ + # itself, so they're never inside the directory this nukes and never + # need special-casing here (an earlier version of this step had to + # skip data/ by name for exactly that reason). docker-compose.yaml + # itself is symlinked up to /srv/podman/maptool/ (relative target, so + # it survives /srv/podman itself ever being renamed) purely for + # discoverability — a human poking around expects to find it at the + # top, not a level down — and because that's what makes `./data` in + # it resolve to the sibling directory: compose resolves a relative + # volume path against the *symlink's* location, not build/ (verified + # against plain `docker-compose config`), so podman-compose@.service's + # own WorkingDirectory=/srv/podman/maptool needs no change either. + - name: Sync to /srv/podman/maptool/build run: | - mkdir -p /srv/podman/maptool - for f in /srv/podman/maptool/*; do - [ "$(basename "$f")" = "data" ] && continue - rm -rf "$f" - done - cp -a . /srv/podman/maptool/ - rm -rf /srv/podman/maptool/.git + rm -rf /srv/podman/maptool/build + mkdir -p /srv/podman/maptool/build + cp -a . /srv/podman/maptool/build/ + rm -rf /srv/podman/maptool/build/.git + ln -sf build/docker-compose.yaml /srv/podman/maptool/docker-compose.yaml # Regenerated on every deploy from repo secrets (Settings -> Actions # -> Secrets) rather than created once by hand on the server — see diff --git a/docs/deployment.adoc b/docs/deployment.adoc index 5ca49d1..95f6f30 100644 --- a/docs/deployment.adoc +++ b/docs/deployment.adoc @@ -31,15 +31,30 @@ existing paths/tooling that still assume `/srv/docker` keep working; expect this to flip the other way, `/srv/docker` symlinked to `/srv/podman`, once nothing depends on the old name anymore) holds: -* A checkout of this repository (kept in sync by the deploy job, see - below) — `Dockerfile`, `docker-compose.yaml`, application code. - `podman compose` reads the same `docker-compose.yaml` — no - Podman-specific compose file needed. -* `data/`, *not* part of that sync — uploaded GPX files, - `offline.pmtiles`, `terrain.pmtiles`, and `kiwix/wikipedia.zim` (see - `docs/development.adoc` for each). Persisted via a bind mount - (`./data:/app/data` in `docker-compose.yaml`), so a redeploy never - touches it. +* `build/` — a checkout of this repository (kept in sync by the + deploy job, see below), wiped and fully replaced every deploy — + `Dockerfile`, `docker-compose.yaml`, application code. +* `docker-compose.yaml` — a relative symlink to `build/docker-compose.yaml`, + purely so it's where a human poking around expects to find it, at + the top rather than a level down. Also what makes the layout work at + all: `podman compose`/`docker compose` resolve a relative volume + path (`./data` below) against the *symlink's own* directory, not + where it points — confirmed against plain `docker-compose config`, + not assumed — so `./data:/app/data` in the compose file keeps + meaning `/srv/podman/maptool/data`, and + `podman-compose@.service`'s `WorkingDirectory=/srv/podman/maptool` + needs no change either. +* `data/`, *not* part of the checkout sync (nothing in `build/` + references it, and the sync step doesn't need to special-case it + the way an earlier version of this layout did) — uploaded GPX + files, `offline.pmtiles`, `terrain.pmtiles`, and + `kiwix/wikipedia.zim` (see `docs/development.adoc` for each). + Persisted via that bind mount, so a redeploy never touches it. +* `.env` — regenerated every deploy (see below), lives here rather + than in `build/` for the same reason as the symlink: `docker + compose`/`podman compose` auto-load `.env` from the compose file's + own directory (as invoked, i.e. following the symlink's location, + same story as the volume path above). == The native deploy runner @@ -224,9 +239,12 @@ on a push to `main`, with `runs-on: cube-host`: `actions/checkout@v4` — a leftover from when this job ran in a Node-less container; kept as-is since there's no reason to bring Node back in for something this already does. -. Copies the checkout into `/srv/podman/maptool/` using plain `cp`/`rm`: - clears everything in the target except `data/`, copies the fresh - checkout over, then drops the copied `.git`. +. Wipes and replaces `/srv/podman/maptool/build/` with the fresh + checkout (plain `cp`/`rm`, dropping the copied `.git`), then + `ln -sf`s `docker-compose.yaml` up to it — self-healing (harmless + to redo every deploy) and, being a fresh checkout each time, nothing + in `build/` needs preserving the way `data/`/`.env` (both a level + up, see "Layout on the server" above) do. . `sudo systemctl restart podman-compose@maptool.service`. The service (`/etc/systemd/system/podman-compose@.service`, a systemd template instantiated as `podman-compose@maptool.service`) owns the actual