Private
Public Access
deploy/upgrade.sh now fetches tags and checks out whichever sorts newest (detached HEAD) instead of git pull --ff-only on a branch, now that the project has a real release process (dated tags, e.g. v2026.9.3) and a public mirror. Keeps production from ever landing on an untagged commit. DEPLOYMENT.md's initial-clone steps and Upgrades section updated to match. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
69 lines
2.2 KiB
Bash
Executable File
69 lines
2.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Day-2 deploy/upgrade script for the DS Chat app server. Run by hand
|
|
# over SSH as the `ds-chat` user (or via sudo -u ds-chat):
|
|
#
|
|
# sudo -u ds-chat /srv/ds-chat/deploy/upgrade.sh
|
|
#
|
|
# Fails loudly and stops before touching the running service if any step
|
|
# fails -- the previous deploy keeps running rather than being torn down
|
|
# mid-upgrade. See ../DEPLOYMENT.md for what each step assumes is already
|
|
# in place (venv, /etc/ds-chat/env, the systemd unit, Node.js).
|
|
|
|
set -euo pipefail
|
|
|
|
REPO_DIR="/srv/ds-chat"
|
|
BACKEND_DIR="${REPO_DIR}/backend"
|
|
FRONTEND_DIR="${REPO_DIR}/frontend"
|
|
ENV_FILE="/etc/ds-chat/env"
|
|
|
|
echo "==> Fetching latest release"
|
|
cd "$REPO_DIR"
|
|
git fetch --tags --force
|
|
LATEST_TAG="$(git tag --sort=-creatordate | head -n1)"
|
|
if [[ -z "$LATEST_TAG" ]]; then
|
|
echo "No tags found -- nothing to deploy" >&2
|
|
exit 1
|
|
fi
|
|
echo "Deploying $LATEST_TAG"
|
|
# Detached HEAD, not a branch checkout -- this directory only ever runs a
|
|
# tagged release, never whatever the default branch's tip happens to be.
|
|
git checkout --quiet --detach "$LATEST_TAG"
|
|
|
|
echo "==> Installing backend dependencies"
|
|
cd "$BACKEND_DIR"
|
|
.venv/bin/pip install -e . --quiet
|
|
|
|
echo "==> Running database migrations"
|
|
# alembic reads DATABASE_URL from the environment (backend/alembic/env.py),
|
|
# so the env file has to actually be sourced into this shell first -- it's
|
|
# not read automatically just because systemd's EnvironmentFile= points at
|
|
# it (that only applies to the ds-chat.service process, not this script).
|
|
set -a
|
|
# shellcheck disable=SC1090
|
|
source "$ENV_FILE"
|
|
set +a
|
|
.venv/bin/alembic upgrade head
|
|
|
|
echo "==> Building frontend"
|
|
cd "$FRONTEND_DIR"
|
|
npm ci --silent
|
|
npm run build --silent
|
|
|
|
echo "==> Restarting ds-chat"
|
|
# Active WebSocket connections drop here and reconnect automatically within
|
|
# a few seconds (frontend/src/ws/useChatSocket.ts's exponential-backoff
|
|
# reconnect) -- expected, not a bug, and not worth a blue-green setup for.
|
|
sudo systemctl restart ds-chat
|
|
|
|
echo "==> Verifying"
|
|
sleep 2
|
|
if curl -sf http://127.0.0.1:8000/api/health >/dev/null; then
|
|
echo "Health check OK"
|
|
else
|
|
echo "Health check FAILED -- check: sudo journalctl -u ds-chat -n 50" >&2
|
|
exit 1
|
|
fi
|
|
sudo systemctl status ds-chat --no-pager -l | head -10
|
|
|
|
echo "==> Done. journalctl -u ds-chat -f to watch logs."
|