|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+#!/usr/bin/env bash
|
|
|
2
|
+#
|
|
|
3
|
+# deploy.sh — run this ON THE SERVER, from inside the cloned repo
|
|
|
4
|
+# (the app lives at /opt/bizgaze-support).
|
|
|
5
|
+#
|
|
|
6
|
+# What it does:
|
|
|
7
|
+# 1. Snapshots the current working tree (code + .env + certs, excluding .git)
|
|
|
8
|
+# into a rotating backup, keeping the newest $KEEP_BACKUPS.
|
|
|
9
|
+# 2. Pulls the latest commit of $GIT_BRANCH (git reset --hard, so the box
|
|
|
10
|
+# always matches origin exactly).
|
|
|
11
|
+# 3. Rebuilds the image and recreates the container. The named data volume
|
|
|
12
|
+# (data.db) persists; the untracked .env / server/cert.pem / server/key.pem
|
|
|
13
|
+# are gitignored and therefore preserved across every pull.
|
|
|
14
|
+# 4. Verifies the app is serving.
|
|
|
15
|
+#
|
|
|
16
|
+# Usage (on the server):
|
|
|
17
|
+# cd /opt/bizgaze-support
|
|
|
18
|
+# ./deploy.sh # pull latest + rebuild
|
|
|
19
|
+# ./deploy.sh --no-pull # rebuild current checkout (no git pull)
|
|
|
20
|
+# ./deploy.sh --rollback # restore newest backup snapshot + rebuild
|
|
|
21
|
+#
|
|
|
22
|
+# Fire it from your laptop without logging in:
|
|
|
23
|
+# plink -ssh -P 61 -pw '<pw>' root@118.95.33.89 \
|
|
|
24
|
+# "cd /opt/bizgaze-support && ./deploy.sh"
|
|
|
25
|
+
|
|
|
26
|
+set -euo pipefail
|
|
|
27
|
+
|
|
|
28
|
+GIT_BRANCH="${GIT_BRANCH:-master}"
|
|
|
29
|
+KEEP_BACKUPS="${KEEP_BACKUPS:-3}"
|
|
|
30
|
+CONTAINER="${CONTAINER:-bizgaze-support}"
|
|
|
31
|
+
|
|
|
32
|
+cd "$(dirname "$(readlink -f "$0")")"
|
|
|
33
|
+APP_DIR="$(pwd)"
|
|
|
34
|
+BK_DIR="${APP_DIR}.backups"
|
|
|
35
|
+
|
|
|
36
|
+log() { printf '\033[1;36m==>\033[0m %s\n' "$*"; }
|
|
|
37
|
+ok() { printf '\033[1;32m ✓\033[0m %s\n' "$*"; }
|
|
|
38
|
+warn(){ printf '\033[1;33m ! %s\033[0m\n' "$*"; }
|
|
|
39
|
+die() { printf '\033[1;31mERROR:\033[0m %s\n' "$*" >&2; exit 1; }
|
|
|
40
|
+
|
|
|
41
|
+[ -d .git ] || die "Not a git checkout. Run the one-time bootstrap first (see DEPLOY.md)."
|
|
|
42
|
+command -v docker >/dev/null || die "docker not found on this host."
|
|
|
43
|
+
|
|
|
44
|
+# --- args ---
|
|
|
45
|
+DO_PULL=1; ROLLBACK=0
|
|
|
46
|
+for a in "$@"; do case "$a" in
|
|
|
47
|
+ --no-pull) DO_PULL=0 ;;
|
|
|
48
|
+ --rollback) ROLLBACK=1 ;;
|
|
|
49
|
+ -h|--help) grep '^#' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
|
|
|
50
|
+ *) die "Unknown argument: $a" ;;
|
|
|
51
|
+esac; done
|
|
|
52
|
+
|
|
|
53
|
+snapshot() {
|
|
|
54
|
+ mkdir -p "$BK_DIR"
|
|
|
55
|
+ local ts rev
|
|
|
56
|
+ ts="$(date +%Y%m%d-%H%M%S)"
|
|
|
57
|
+ rev="$(git rev-parse --short HEAD 2>/dev/null || echo nogit)"
|
|
|
58
|
+ log "Snapshot -> $BK_DIR/${ts}-${rev}.tgz"
|
|
|
59
|
+ tar --exclude=./.git --exclude=./node_modules \
|
|
|
60
|
+ --exclude=./server/node_modules -czf "$BK_DIR/${ts}-${rev}.tgz" -C "$APP_DIR" .
|
|
|
61
|
+ # rotate: keep newest $KEEP_BACKUPS
|
|
|
62
|
+ local old
|
|
|
63
|
+ old="$(ls -1t "$BK_DIR"/*.tgz 2>/dev/null | tail -n +$((KEEP_BACKUPS + 1)) || true)"
|
|
|
64
|
+ if [ -n "$old" ]; then
|
|
|
65
|
+ echo "Pruning old backups:"; echo "$old" | sed 's/^/ rm /'
|
|
|
66
|
+ echo "$old" | xargs -r rm -f
|
|
|
67
|
+ fi
|
|
|
68
|
+}
|
|
|
69
|
+
|
|
|
70
|
+rebuild() {
|
|
|
71
|
+ [ -f .env ] || warn "No .env present — TURN/SSO secrets will be unset."
|
|
|
72
|
+ log "Rebuilding and recreating the container …"
|
|
|
73
|
+ docker compose config >/dev/null || die "docker-compose.yml is invalid."
|
|
|
74
|
+ docker compose up -d --build
|
|
|
75
|
+ docker compose ps
|
|
|
76
|
+}
|
|
|
77
|
+
|
|
|
78
|
+verify() {
|
|
|
79
|
+ log "Verifying /api/ice …"
|
|
|
80
|
+ if docker exec "$CONTAINER" wget -qO- http://localhost:8090/api/ice 2>/dev/null | grep -q iceServers; then
|
|
|
81
|
+ ok "App is serving."
|
|
|
82
|
+ else
|
|
|
83
|
+ warn "Could not confirm /api/ice — check: docker logs $CONTAINER"
|
|
|
84
|
+ fi
|
|
|
85
|
+}
|
|
|
86
|
+
|
|
|
87
|
+# --- rollback mode ---
|
|
|
88
|
+if [ "$ROLLBACK" -eq 1 ]; then
|
|
|
89
|
+ latest="$(ls -1t "$BK_DIR"/*.tgz 2>/dev/null | head -n1 || true)"
|
|
|
90
|
+ [ -n "$latest" ] || die "No backups found in $BK_DIR"
|
|
|
91
|
+ log "Rolling back from: $latest"
|
|
|
92
|
+ snapshot # snapshot the (broken) current state first
|
|
|
93
|
+ tar -xzf "$latest" -C "$APP_DIR"
|
|
|
94
|
+ rebuild; verify
|
|
|
95
|
+ ok "Rolled back to $latest"
|
|
|
96
|
+ exit 0
|
|
|
97
|
+fi
|
|
|
98
|
+
|
|
|
99
|
+# --- normal deploy ---
|
|
|
100
|
+snapshot
|
|
|
101
|
+if [ "$DO_PULL" -eq 1 ]; then
|
|
|
102
|
+ log "Fetching origin/$GIT_BRANCH …"
|
|
|
103
|
+ git fetch origin "$GIT_BRANCH"
|
|
|
104
|
+ git reset --hard "origin/$GIT_BRANCH" # untracked .env / *.pem are preserved
|
|
|
105
|
+ ok "Now at $(git rev-parse --short HEAD): $(git log -1 --pretty=%s)"
|
|
|
106
|
+fi
|
|
|
107
|
+rebuild
|
|
|
108
|
+verify
|
|
|
109
|
+ok "Deploy complete. Backups kept: $KEEP_BACKUPS (in $BK_DIR)."
|
|
|
110
|
+echo " Rollback with: ./deploy.sh --rollback"
|