Deploying by hand failed in two different ways. Once the files went to
/home/sema_gopa/pwa/dist, which nothing serves, so a fix looked live for a week
while the site ran an August build. Then pruning stale assets kept being undone:
that directory is not a git checkout, it has simply accumulated every asset ever
copied into it — 226 files against a build of 47 — so deploying from it restores
every stale chunk, including bundles still carrying the unrotated API token.
The script makes the served directory mirror a freshly built dist. It also
carries the things a plain copy keeps getting wrong here:
- The docroot is root-owned, so files go in through `docker cp`; the container
runs as root and /var/www/html is a bind mount to the host.
- macOS tar writes AppleDouble `._*` companions, and `.htaccess` once arrived
as `._.htaccess`. COPYFILE_DISABLE=1 plus a sweep handles that.
- `dist/*` silently skips `.htaccess`, which carries the rewrite rules, so
everything is copied with `.` and the transfer is refused unless the staged
file count matches the build and .htaccess survived.
It backs the docroot up before touching it, prunes assets/ to exactly the build,
and verifies over HTTP afterwards — including that the live service worker
version matches the one just built. Files outside assets/ are reported rather
than deleted, since someone may have put them there deliberately; --prune-all
removes them.
That caution paid for itself on the first run: it found a legacy icons/
directory, eleven files from May, left behind when the icons moved to
app-icons/. Apache had been 404ing them regardless, because Debian's
alias.conf maps /icons/ to /usr/share/apache2/icons/ for directory listings —
which is presumably why the directory was renamed. Removed with --prune-all.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>