added deploy watch, pull script. minor refactors

This commit is contained in:
Hunter
2026-10-03 14:31:43 -04:00
parent 6dbaa647dc
commit 30c8ad9293
30 changed files with 370 additions and 213 deletions

View File

@@ -0,0 +1,18 @@
[Unit]
Description=hwilliams dev root watcher
After=docker.service network-online.target
Wants=network-online.target
Requires=docker.service
[Service]
Type=simple
User=__DEPLOY_USER__
WorkingDirectory=__REPO_DIR__
Environment=REPO_DIR=__REPO_DIR__
Environment=SERVICE=__SERVICE__
ExecStart=__REPO_DIR__/scripts/deploy-watch.sh
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target

30
scripts/deploy-watch.sh Normal file
View File

@@ -0,0 +1,30 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_DIR="${REPO_DIR:-$(dirname "$SCRIPT_DIR")}"
TRIGGER_FILE="${TRIGGER_FILE:-$REPO_DIR/deploy-trigger/redeploy.flag}"
POLL_INTERVAL="${POLL_INTERVAL:-10}"
# Compose service name from docker-compose.yml (not the generated image name).
SERVICE="${SERVICE:-portfolio}"
log() { echo "[deploy-watch] $(date -Iseconds) $*"; }
log "watching for $TRIGGER_FILE (repo: $REPO_DIR, service: $SERVICE, interval: ${POLL_INTERVAL}s)"
while true; do
if [ -f "$TRIGGER_FILE" ]; then
log "trigger detected, redeploying"
rm -f "$TRIGGER_FILE"
# set -e is ignored inside a subshell that is part of an && / || list, so
# each step is chained explicitly to stop at the first failure.
(
cd "$REPO_DIR" &&
git pull --ff-only &&
docker compose build "$SERVICE" &&
docker compose up -d "$SERVICE" &&
docker image prune -f
) && log "redeploy complete" || log "redeploy FAILED, see output above"
fi
sleep "$POLL_INTERVAL"
done

View File

@@ -0,0 +1,62 @@
#!/usr/bin/env bash
# Installs deploy-watch.sh as a systemd service so it survives reboots and
# restarts on failure. Run on the host that runs `docker compose` for this
# stack (i.e. where ./deploy-trigger and the repo checkout actually live).
#
# Usage: sudo ./scripts/install-deploy-watch.sh [user]
# user account to run the watcher as (must be in the `docker` group).
# Defaults to $SUDO_USER, or the current user if not run via sudo.
set -euo pipefail
if [ "$(id -u)" -ne 0 ]; then
echo "Run this with sudo (writes to /etc/systemd/system)." >&2
exit 1
fi
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_DIR="$(dirname "$SCRIPT_DIR")"
DEPLOY_USER="${1:-${SUDO_USER:-$(id -un)}}"
UNIT_NAME="deploy-watch-hwilliams-dev.service"
UNIT_DEST="/etc/systemd/system/$UNIT_NAME"
# Compose service name from docker-compose.yml.
SERVICE="portfolio"
if ! id "$DEPLOY_USER" >/dev/null 2>&1; then
echo "User '$DEPLOY_USER' does not exist." >&2
exit 1
fi
if ! id -nG "$DEPLOY_USER" | grep -qw docker; then
echo "Warning: '$DEPLOY_USER' is not in the 'docker' group;" \
"docker compose calls in deploy-watch.sh will fail until you add it" \
"(sudo usermod -aG docker $DEPLOY_USER) and re-login." >&2
fi
TRIGGER_DIR="$REPO_DIR/deploy-trigger"
# The web container (uid/gid 1001, see Dockerfile) writes the flag through a
# bind mount and the watcher deletes it, so both need write access.
CONTAINER_GID=1001
mkdir -p "$TRIGGER_DIR"
chown "$DEPLOY_USER:$CONTAINER_GID" "$TRIGGER_DIR"
chmod 2775 "$TRIGGER_DIR"
if ! sudo -u "$DEPLOY_USER" test -w "$TRIGGER_DIR"; then
echo "Warning: '$DEPLOY_USER' cannot write to $TRIGGER_DIR;" \
"the watcher will fail to clear the trigger file and restart-loop." >&2
fi
chmod +x "$SCRIPT_DIR/deploy-watch.sh"
sed \
-e "s|__REPO_DIR__|$REPO_DIR|g" \
-e "s|__SERVICE__|$SERVICE|g" \
-e "s|__DEPLOY_USER__|$DEPLOY_USER|g" \
"$SCRIPT_DIR/deploy-watch.service" > "$UNIT_DEST"
systemctl daemon-reload
systemctl enable "$UNIT_NAME"
# restart (not start) so a reinstall picks up changes to the unit or script.
systemctl restart "$UNIT_NAME"
echo "Installed and started $UNIT_NAME (repo: $REPO_DIR, user: $DEPLOY_USER)."
echo "Check status with: systemctl status $UNIT_NAME"
echo "Follow logs with: journalctl -u $UNIT_NAME -f"

View File

@@ -0,0 +1,29 @@
#!/usr/bin/env bash
# Stops and removes the deploy-watch systemd service installed by
# install-deploy-watch.sh.
#
# Usage: sudo ./scripts/uninstall-deploy-watch.sh
set -euo pipefail
if [ "$(id -u)" -ne 0 ]; then
echo "Run this with sudo (modifies /etc/systemd/system)." >&2
exit 1
fi
UNIT_NAME="deploy-watch-hwilliams-dev.service"
UNIT_DEST="/etc/systemd/system/$UNIT_NAME"
if systemctl list-unit-files | grep -q "^$UNIT_NAME"; then
systemctl disable --now "$UNIT_NAME"
else
echo "$UNIT_NAME is not installed; nothing to disable."
fi
if [ -f "$UNIT_DEST" ]; then
rm "$UNIT_DEST"
systemctl daemon-reload
echo "Removed $UNIT_DEST."
else
echo "$UNIT_DEST not found; nothing to remove."
fi