summaryrefslogtreecommitdiff
path: root/scripts/deploy
diff options
context:
space:
mode:
authorPeter Stone <thepeterstone@gmail.com>2026-09-20 00:23:59 +0000
committerPeter Stone <thepeterstone@gmail.com>2026-09-20 00:25:17 +0000
commitde3a2ba7280ab66cc4ec05a80925291b9648706d (patch)
tree93d894edf3b32a2b095f2f5cd4763304ff2a5ffc /scripts/deploy
parent51090f85ff8a4dd345c6617b2a876c3ab14d6189 (diff)
Stop deploy stripping the execute bit from site binaries
The permission step ran find ${SITE_DIR} -type f -exec chmod 644 {} + chmod +x ${SITE_DIR}/app over the whole site directory, so it cleared +x on every other executable there and restored it only for doot's own app. Four binaries were caught: services/scout/app scout.service services/hawaii/app hawaii sub-service bin/claudomator claudomator@doot.terst.org.service bin/claude exec'd by claudomator via --claude-bin Nothing appears to break at deploy time: a running service keeps executing from its already-open file. The damage surfaces at the next reboot, when systemd cannot exec the binary and the unit dies with status=203/EXEC. scout.service went down that way at the 2026-08-25 reboot and stayed down three and a half weeks, serving 502s behind /scout/; claudomator has been crash-looping on the same error, 426k restarts and counting. Neither is alerted on, because doot itself is healthy and only those paths fail. Permission fixing is now scoped to the directories this script actually manages (public, templates, migrations) plus doot's own binary and .env. Every executable under services/*/app and bin/* is then re-asserted +x, since that is what an outage looks like when it is wrong and asserting it is free. Verified against a synthetic site tree: all five binaries keep 755, assets 644. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018AwnALZL6bD4VBtATDVv3B
Diffstat (limited to 'scripts/deploy')
-rwxr-xr-xscripts/deploy34
1 files changed, 31 insertions, 3 deletions
diff --git a/scripts/deploy b/scripts/deploy
index 6b3d498..6579839 100755
--- a/scripts/deploy
+++ b/scripts/deploy
@@ -37,12 +37,40 @@ echo "==> Swapping binary..."
mv app ${SITE_DIR}/app
echo "==> Setting permissions..."
-chown -R www-data:www-data ${SITE_DIR}
-find ${SITE_DIR} -type d -exec chmod 755 {} +
-find ${SITE_DIR} -type f -exec chmod 644 {} +
+# Scope permission fixing to the directories this script actually manages.
+#
+# This previously ran `find ${SITE_DIR} -type f -exec chmod 644 {} +` across the
+# whole site directory and then restored +x on ${SITE_DIR}/app alone. That also
+# stripped the execute bit from every sub-service binary under
+# ${SITE_DIR}/services/, e.g. services/scout/app. Those services keep running
+# from their already-open file, so nothing appears to break — until the next
+# reboot, when systemd cannot exec them and they fail with 203/EXEC. Scout was
+# down for three and a half weeks that way, serving 502s behind /scout/, because
+# the failure is invisible until someone opens the page.
+for managed in public templates migrations; do
+ [ -d "${SITE_DIR}/${managed}" ] || continue
+ chown -R www-data:www-data "${SITE_DIR}/${managed}"
+ find "${SITE_DIR}/${managed}" -type d -exec chmod 755 {} +
+ find "${SITE_DIR}/${managed}" -type f -exec chmod 644 {} +
+done
+
+chown www-data:www-data ${SITE_DIR}/app
chmod +x ${SITE_DIR}/app
chmod 600 ${SITE_DIR}/.env 2>/dev/null || true
+# Belt and braces: re-assert +x on every executable the site depends on. Even
+# though the blanket chmod above is gone, a missing execute bit here is what an
+# outage looks like, and asserting it costs nothing.
+#
+# The old blanket chmod took out four binaries in one go — services/scout/app,
+# services/hawaii/app, bin/claudomator and bin/claude (which claudomator execs
+# via --claude-bin). Only ${SITE_DIR}/app survived, because it was the single
+# path the script put the bit back on. Both locations are covered here.
+for svc_bin in ${SITE_DIR}/services/*/app ${SITE_DIR}/bin/*; do
+ [ -f "$svc_bin" ] || continue
+ chmod +x "$svc_bin"
+done
+
echo "==> Starting service..."
systemctl start ${SERVICE}
sleep 1