diff options
| author | Anders Betts <anders.betts@gmail.com> | 2026-09-18 10:35:11 +0200 |
|---|---|---|
| committer | Anders Betts <anders.betts@gmail.com> | 2026-09-18 10:35:11 +0200 |
| commit | 1e5b4927e5ae1d542d51158eb995d4f4b5a8b1c5 (patch) | |
| tree | 5d2b414abbe6550eaf403c6aa4b5f75eb703fa01 /scripts/deploy.sh | |
| parent | 7a0771215d9bd52dc9d6913abee56a9f62893d3e (diff) | |
| download | bokf-1e5b4927e5ae1d542d51158eb995d4f4b5a8b1c5.tar.gz bokf-1e5b4927e5ae1d542d51158eb995d4f4b5a8b1c5.zip | |
deploy: --dev hot-reloads the daemon via docker cp + SIGHUPv0.1.14
- bokfd re-execs its own binary on SIGHUP, closing listeners/db first
- scripts/deploy.sh --dev cross-builds and copies binaries into the
running container, then verifies the reported version
Diffstat (limited to 'scripts/deploy.sh')
| -rwxr-xr-x | scripts/deploy.sh | 116 |
1 files changed, 88 insertions, 28 deletions
diff --git a/scripts/deploy.sh b/scripts/deploy.sh index c345a21..79d731f 100755 --- a/scripts/deploy.sh +++ b/scripts/deploy.sh @@ -1,7 +1,12 @@ #!/usr/bin/env bash # Deploy a locally built bokf image to BOKF_HOST over SSH. See docs/DEPLOY.md. # -# scripts/deploy.sh [tag] +# scripts/deploy.sh [--dev] [tag] +# +# Normal mode builds an image (cross-compiled on this machine when the target +# architecture differs) and recreates the container. --dev skips the image: +# it copies the fresh binaries into the running container and reloads the +# daemon with SIGHUP, which re-execs them in place. # # BOKF_HOST (user@host) and BOKF_REMOTE_DIR are read from the environment or # from .env in the repository root. The host needs only Docker and Compose. @@ -23,6 +28,12 @@ fi BOKF_REMOTE_DIR="${BOKF_REMOTE_DIR:-/srv/bokf}" SSH=(ssh "$BOKF_HOST") +DEV=0 +if [ "${1:-}" = "--dev" ]; then + DEV=1 + shift +fi + TAG="${1:-}" if [ -z "$TAG" ]; then TAG="$(git describe --tags --always --dirty 2>/dev/null || echo dev)" @@ -36,11 +47,41 @@ esac remote() { "${SSH[@]}" "$1"; } +wait_healthy() { + for _ in $(seq 1 30); do + cid="$(remote "cd '$BOKF_REMOTE_DIR' && docker compose ps -q bokfd" 2>/dev/null || true)" + if [ -n "$cid" ]; then + st="$(remote "docker inspect --format '{{.State.Health.Status}}' '$cid'" 2>/dev/null || true)" + if [ "$st" = "healthy" ]; then + return 0 + fi + fi + sleep 2 + done + return 1 +} + +cross_build() { + echo "deploy: cross-compiling $host_arch binaries on this machine" + rm -rf .prebuilt + mkdir -p .prebuilt + docker build -q -f deploy/Dockerfile.cross -t bokf-cross deploy/ >/dev/null + docker run --rm -e "VERSION=$TAG" -v "$PWD":/src:ro \ + -v "$PWD/.prebuilt":/out bokf-cross + if command -v file >/dev/null 2>&1 && + ! file .prebuilt/bokfd | grep -q aarch64; then + echo "deploy: cross-build produced no arm64 binary" >&2 + rm -rf .prebuilt + exit 1 + fi +} + echo "deploy: gate: build + tests" make -j"$(nproc)" make test BOKF_BUILD="${BOKF_BUILD:-auto}" +host_arch="$(uname -m)" case "$BOKF_BUILD" in auto) host_arch="$(remote 'uname -m' 2>/dev/null || echo unknown)" @@ -51,31 +92,64 @@ case "$BOKF_BUILD" in BOKF_BUILD=remote fi ;; - local | remote) ;; + local | remote) + host_arch="$(remote 'uname -m' 2>/dev/null || echo unknown)" + ;; *) echo "deploy: BOKF_BUILD must be auto, local or remote" >&2 exit 1 ;; esac +if [ "$DEV" = 1 ]; then + if ! remote "test -f '$BOKF_REMOTE_DIR/var/db/bokfd.db'"; then + echo "deploy: no database on $BOKF_HOST; run a normal deploy first" >&2 + exit 1 + fi + if [ "$BOKF_BUILD" = local ]; then + prebin="build" + echo "deploy: dev: using the locally built binaries" + else + cross_build + prebin=".prebuilt" + fi + echo "deploy: dev: copying binaries into the running container" + remote "mkdir -p /tmp/bokf-dev" + scp -q "$prebin/bokfd" "$prebin/bokfctl" "$prebin/bokftui" \ + "$BOKF_HOST:/tmp/bokf-dev/" + remote "cd '$BOKF_REMOTE_DIR' + cid=\$(docker compose ps -q bokfd) + test -n \"\$cid\" || { echo 'deploy: bokfd is not running' >&2; exit 1; } + docker cp /tmp/bokf-dev/bokfd \"\$cid:/usr/local/bin/bokfd\" + docker cp /tmp/bokf-dev/bokfctl \"\$cid:/usr/local/bin/bokfctl\" + docker cp /tmp/bokf-dev/bokftui \"\$cid:/usr/local/bin/bokftui\" + docker kill --signal=HUP \"\$cid\"" + if [ "$prebin" = ".prebuilt" ]; then + rm -rf .prebuilt + fi + ver="" + for _ in $(seq 1 15); do + ver="$(remote "cd '$BOKF_REMOTE_DIR' && docker exec \$(docker compose ps -q bokfd) bokfctl meta 2>/dev/null" | + sed -n 's/.*"version": *"\([^"]*\)".*/\1/p' || true)" + [ "$ver" = "$TAG" ] && break + sleep 1 + done + if [ "$ver" = "$TAG" ]; then + echo "deploy: dev reloaded, daemon reports $ver" + exit 0 + fi + echo "deploy: dev reload did not come back with $TAG (got '${ver:-nothing}')" >&2 + remote "cd '$BOKF_REMOTE_DIR' && docker compose logs --tail=30 bokfd" >&2 || true + exit 1 +fi + if [ "$BOKF_BUILD" = local ]; then echo "deploy: building image bokf:$TAG locally" docker build --build-arg "VERSION=$TAG" -t "bokf:$TAG" . echo "deploy: shipping image to $BOKF_HOST" docker save "bokf:$TAG" | gzip | "${SSH[@]}" 'gunzip | docker load' else - echo "deploy: cross-compiling $host_arch binaries on this machine" - rm -rf .prebuilt - mkdir -p .prebuilt - docker build -q -f deploy/Dockerfile.cross -t bokf-cross deploy/ >/dev/null - docker run --rm -e "VERSION=$TAG" -v "$PWD":/src:ro \ - -v "$PWD/.prebuilt":/out bokf-cross - if command -v file >/dev/null 2>&1 && - ! file .prebuilt/bokfd | grep -q aarch64; then - echo "deploy: cross-build produced no arm64 binary" >&2 - rm -rf .prebuilt - exit 1 - fi + cross_build echo "deploy: assembling image bokf:$TAG on $BOKF_HOST" tar -cf - \ --exclude=./.git --exclude=./build --exclude=./var --exclude=./.env \ @@ -106,20 +180,6 @@ fi echo "deploy: starting containers" remote "cd '$BOKF_REMOTE_DIR' && docker compose up -d --no-build" -wait_healthy() { - for _ in $(seq 1 30); do - cid="$(remote "cd '$BOKF_REMOTE_DIR' && docker compose ps -q bokfd" 2>/dev/null || true)" - if [ -n "$cid" ]; then - st="$(remote "docker inspect --format '{{.State.Health.Status}}' '$cid'" 2>/dev/null || true)" - if [ "$st" = "healthy" ]; then - return 0 - fi - fi - sleep 2 - done - return 1 -} - if wait_healthy; then echo "deploy: bokf:$TAG is healthy on $BOKF_HOST" exit 0 |
