summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVoid Agent <void@jayrup.hermes>2026-10-22 23:12:30 +0100
committerVoid Agent <void@jayrup.hermes>2026-10-22 23:12:30 +0100
commit1e58fcb98fd17dbec3a2b477d3737b83101a18b5 (patch)
tree000c68ffa8cb69807b2f922f21d05704becbeddc
parent70dffce202a8cc1d15473bbc2750bdf29a54b0fb (diff)
deploy: write nginx.conf in place so the container's bind mount sees it
nginx.conf is mounted as a single file. rsync renames a temp over the destination, which replaces the inode, so the container kept reading the old inode: nginx -t validated the old bytes, reload was a no-op, and the deploy reported success while the live config was unchanged. Stage to nginx.conf.new, copy in place with cat so the mounted inode keeps its identity, then test and reload. Rollback copies in place too, for the same reason.
-rwxr-xr-xdeploy-docker.sh14
-rwxr-xr-xdeploy.sh16
2 files changed, 20 insertions, 10 deletions
diff --git a/deploy-docker.sh b/deploy-docker.sh
index 716bb8d..12d4a54 100755
--- a/deploy-docker.sh
+++ b/deploy-docker.sh
@@ -70,18 +70,22 @@ printf 'deployed %s commit %s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "$SHORT_SHA" >
echo ">> pushing to $DEPLOY_HOST"
rsync -avz --delete public/ "$DEPLOY_HOST":~/homepage/public/
-# nginx config is bind-mounted into the container, so it does not travel with
-# public/. Test before reloading: a bad file must not take down the running
-# workers, so restore the previous one and fail loudly instead.
+# nginx config is bind-mounted into the container as a SINGLE FILE, so rsync's
+# rename-into-place would swap the inode the mount points at and the container
+# would keep reading the old file while `nginx -t` validated the old bytes.
+# Stage to a sidecar, copy in place so the mounted inode keeps its identity,
+# test, and only then reload; restore the previous content on failure.
echo ">> pushing nginx.conf"
+rsync -avz nginx.conf "$DEPLOY_HOST":~/homepage/nginx.conf.new
ssh "$DEPLOY_HOST" 'cp -a ~/homepage/nginx.conf ~/homepage/nginx.conf.prev'
-rsync -avz nginx.conf "$DEPLOY_HOST":~/homepage/nginx.conf
+ssh "$DEPLOY_HOST" 'cat ~/homepage/nginx.conf.new > ~/homepage/nginx.conf'
if ssh "$DEPLOY_HOST" 'docker exec homepage nginx -t'; then
ssh "$DEPLOY_HOST" 'docker exec homepage nginx -s reload'
+ ssh "$DEPLOY_HOST" 'rm -f ~/homepage/nginx.conf.new'
echo ">> nginx reloaded"
else
echo "!! nginx config failed its test - restoring previous config" >&2
- ssh "$DEPLOY_HOST" 'mv ~/homepage/nginx.conf.prev ~/homepage/nginx.conf'
+ ssh "$DEPLOY_HOST" 'cat ~/homepage/nginx.conf.prev > ~/homepage/nginx.conf'
exit 1
fi
diff --git a/deploy.sh b/deploy.sh
index 306f666..e68ee92 100755
--- a/deploy.sh
+++ b/deploy.sh
@@ -61,17 +61,23 @@ echo "Pushing to vps"
# 7. Content. Only reached if all renders succeeded (set -e)
rsync -avz --delete public/ "$DEPLOY_HOST":~/homepage/public/
-# 8. nginx config. It is bind-mounted into the container, so it does not travel
-# with public/. Test it before reloading: a bad file must not take down the
-# running workers, so restore the previous one and fail loudly instead.
+# 8. nginx config. It is bind-mounted into the container as a SINGLE FILE, so
+# it does not travel with public/, and rsync's rename-into-place would swap
+# the inode the mount points at: the container would keep reading the old
+# inode while `nginx -t` cheerfully validated it. Stage to a sidecar, then
+# copy in place (cat >) so the mounted inode keeps its identity.
+# Test before reloading; on failure restore the previous content the same
+# way and fail loudly instead of taking the running workers down.
echo "Pushing nginx.conf"
+rsync -avz nginx.conf "$DEPLOY_HOST":~/homepage/nginx.conf.new
ssh "$DEPLOY_HOST" 'cp -a ~/homepage/nginx.conf ~/homepage/nginx.conf.prev'
-rsync -avz nginx.conf "$DEPLOY_HOST":~/homepage/nginx.conf
+ssh "$DEPLOY_HOST" 'cat ~/homepage/nginx.conf.new > ~/homepage/nginx.conf'
if ssh "$DEPLOY_HOST" 'docker exec homepage nginx -t'; then
ssh "$DEPLOY_HOST" 'docker exec homepage nginx -s reload'
+ ssh "$DEPLOY_HOST" 'rm -f ~/homepage/nginx.conf.new'
echo "nginx reloaded"
else
echo "!! nginx config failed its test - restoring previous config" >&2
- ssh "$DEPLOY_HOST" 'mv ~/homepage/nginx.conf.prev ~/homepage/nginx.conf'
+ ssh "$DEPLOY_HOST" 'cat ~/homepage/nginx.conf.prev > ~/homepage/nginx.conf'
exit 1
fi