deploy-kvm4.sh99 lines · main
| 1 | #!/usr/bin/env bash |
| 2 | # Deploy main to briven.tech on kvm4. Runs from the operator's local |
| 3 | # machine — wraps git push + ssh pull + docker compose build/up so the |
| 4 | # rollout becomes one command: |
| 5 | # |
| 6 | # ./scripts/deploy-kvm4.sh # api+web+docs |
| 7 | # ./scripts/deploy-kvm4.sh api # just api |
| 8 | # ./scripts/deploy-kvm4.sh api web docs runtime # explicit set |
| 9 | # ./scripts/deploy-kvm4.sh --no-push api # local build only |
| 10 | # # (use when konnos is down) |
| 11 | # |
| 12 | # What it does: |
| 13 | # 1. push current HEAD to konnos (skipped with --no-push) |
| 14 | # 2. ssh into kvm4, git stash any drift, git pull origin main |
| 15 | # 3. docker compose build the requested services with |
| 16 | # BRIVEN_BUILD_SHA + BRIVEN_BUILD_AT injected as build-args so |
| 17 | # /info reflects the running commit |
| 18 | # 4. up -d --force-recreate the same services |
| 19 | # 5. wait + curl /info on api so the operator sees the new sha live |
| 20 | # |
| 21 | # Doesn't redeploy database / redis / minio — they survive across |
| 22 | # code changes. Pass them explicitly if you need to. |
| 23 | |
| 24 | set -euo pipefail |
| 25 | |
| 26 | HOST="root@187.124.209.17" |
| 27 | REMOTE_REPO="/etc/dokploy/compose/briven/code" |
| 28 | PROJECT_NAME="briven" |
| 29 | COMPOSE_FILE="infra/dokploy/compose.dokploy.yml" |
| 30 | |
| 31 | PUSH=1 |
| 32 | SERVICES=() |
| 33 | for arg in "$@"; do |
| 34 | case "$arg" in |
| 35 | --no-push) PUSH=0 ;; |
| 36 | -h|--help) |
| 37 | sed -n '2,22p' "$0" | sed 's/^# \{0,1\}//' |
| 38 | exit 0 |
| 39 | ;; |
| 40 | *) SERVICES+=("$arg") ;; |
| 41 | esac |
| 42 | done |
| 43 | |
| 44 | if [[ ${#SERVICES[@]} -eq 0 ]]; then |
| 45 | SERVICES=(api web docs) |
| 46 | fi |
| 47 | |
| 48 | repo_root="$(cd "$(dirname "$0")/.." && pwd)" |
| 49 | cd "$repo_root" |
| 50 | |
| 51 | SHA=$(git rev-parse --short HEAD) |
| 52 | NOW=$(date -u +"%Y-%m-%dT%H:%M:%SZ") |
| 53 | DIRTY="" |
| 54 | if ! git diff --quiet HEAD; then |
| 55 | DIRTY=" (dirty tree — uncommitted local changes will NOT deploy)" |
| 56 | fi |
| 57 | |
| 58 | echo "→ deploying $SHA at $NOW to $HOST$DIRTY" |
| 59 | echo "→ services: ${SERVICES[*]}" |
| 60 | |
| 61 | # ─── 1. push to konnos ───────────────────────────────────────────────── |
| 62 | if [[ "$PUSH" -eq 1 ]]; then |
| 63 | echo "→ pushing to konnos" |
| 64 | if ! git push origin main; then |
| 65 | echo "✖ push to konnos failed. pass --no-push to deploy from rsync only." |
| 66 | exit 1 |
| 67 | fi |
| 68 | fi |
| 69 | |
| 70 | # ─── 2-5. pull + build + up + verify on kvm4 ─────────────────────────── |
| 71 | ssh "$HOST" " |
| 72 | set -euo pipefail |
| 73 | cd $REMOTE_REPO |
| 74 | |
| 75 | echo ' → stash any drift' |
| 76 | git stash --include-untracked >/dev/null 2>&1 || true |
| 77 | |
| 78 | echo ' → git pull origin main' |
| 79 | git pull origin main | tail -3 |
| 80 | |
| 81 | echo ' → docker compose build (sha=$SHA)' |
| 82 | docker compose --project-name $PROJECT_NAME --env-file .env -f $COMPOSE_FILE build \ |
| 83 | --build-arg BRIVEN_BUILD_SHA=$SHA --build-arg BRIVEN_BUILD_AT='$NOW' \ |
| 84 | ${SERVICES[*]} 2>&1 | tail -3 |
| 85 | |
| 86 | echo ' → docker compose up -d --force-recreate' |
| 87 | docker compose --project-name $PROJECT_NAME --env-file .env -f $COMPOSE_FILE up -d \ |
| 88 | --force-recreate --no-deps ${SERVICES[*]} 2>&1 | tail -3 |
| 89 | |
| 90 | if printf '%s\n' ${SERVICES[*]} | grep -q '^api$'; then |
| 91 | sleep 5 |
| 92 | echo |
| 93 | echo ' → verify /info reflects the new build' |
| 94 | curl -sS https://api.briven.tech/info |
| 95 | echo |
| 96 | fi |
| 97 | " |
| 98 | |
| 99 | echo "✔ deploy complete" |