-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdeploy.sh
More file actions
125 lines (104 loc) · 2.92 KB
/
deploy.sh
File metadata and controls
125 lines (104 loc) · 2.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#!/usr/bin/env bash
set -euo pipefail
APP_DIR="${APP_DIR:-/opt/heartbeat}"
APP_NAME="${APP_NAME:-heartbeat-live}"
IMAGE_NAME="${IMAGE_NAME:-heartbeat-live}"
ENV_FILE="${ENV_FILE:-$APP_DIR/.env}"
CADDY_CONTAINER="${CADDY_CONTAINER:-caddy}"
DOMAIN="${DOMAIN:-heartbeat.example.com}"
if [[ ! -d "$APP_DIR" ]]; then
echo "App dir not found: $APP_DIR" >&2
exit 1
fi
if [[ -f "$ENV_FILE" ]]; then
set -a
# shellcheck disable=SC1090
source "$ENV_FILE"
set +a
fi
: "${OPENAI_API_KEY:?Missing OPENAI_API_KEY. Put it in $ENV_FILE}"
: "${OPENAI_BASE_URL:=}"
: "${HEARTBEAT_LLM_MODEL:=gpt-4o-mini}"
: "${HEARTBEAT_HOST:=0.0.0.0}"
: "${HEARTBEAT_PORT:=8000}"
cd "$APP_DIR"
mkdir -p "$APP_DIR/keys"
echo "[1/4] Building image..."
docker build -t "$IMAGE_NAME" .
echo "[2/4] Restarting app container..."
docker rm -f "$APP_NAME" >/dev/null 2>&1 || true
network="$(
docker inspect "$CADDY_CONTAINER" \
--format '{{range $k,$v := .NetworkSettings.Networks}}{{println $k}}{{end}}' \
| head -n1 | tr -d '\r'
)"
if [[ -z "$network" ]]; then
echo "Could not detect Docker network from $CADDY_CONTAINER" >&2
exit 1
fi
docker run -d \
--name "$APP_NAME" \
--restart unless-stopped \
--network "$network" \
-e OPENAI_API_KEY="$OPENAI_API_KEY" \
-e OPENAI_BASE_URL="$OPENAI_BASE_URL" \
-e HEARTBEAT_LLM_MODEL="$HEARTBEAT_LLM_MODEL" \
-e HEARTBEAT_HOST="$HEARTBEAT_HOST" \
-e HEARTBEAT_PORT="$HEARTBEAT_PORT" \
-v "$APP_DIR/keys:/app/keys" \
"$IMAGE_NAME" >/dev/null
echo "[3/4] Patching Caddyfile..."
caddyfile="$(
docker inspect "$CADDY_CONTAINER" \
--format '{{range .Mounts}}{{if eq .Destination "/etc/caddy/Caddyfile"}}{{.Source}}{{end}}{{end}}' \
| tr -d '\r'
)"
if [[ -z "$caddyfile" ]]; then
echo "Could not find host Caddyfile path from $CADDY_CONTAINER" >&2
exit 1
fi
backup="${caddyfile}.bak_$(date +%Y%m%d%H%M%S)"
cp "$caddyfile" "$backup"
python3 - "$caddyfile" "$APP_NAME" "$DOMAIN" <<'PY'
from pathlib import Path
import sys
path = Path(sys.argv[1])
app_name = sys.argv[2]
domain = sys.argv[3]
text = path.read_text(encoding="utf-8")
begin = "# BEGIN HEARTBEAT"
end = "# END HEARTBEAT"
lines = text.splitlines()
out = []
inside = False
for line in lines:
if line.strip() == begin:
inside = True
continue
if line.strip() == end:
inside = False
continue
if not inside:
out.append(line)
block = f"""
{begin}
{domain} {{
encode gzip
reverse_proxy {app_name}:8000
}}
{end}
"""
result = "\n".join(out).rstrip() + block
path.write_text(result + "\n", encoding="utf-8")
PY
echo "[4/4] Validating Caddy config..."
if ! docker exec "$CADDY_CONTAINER" caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile >/dev/null 2>&1; then
echo "Caddy config validation failed, restoring backup: $backup" >&2
cp "$backup" "$caddyfile"
exit 1
fi
echo "[4/4] Restarting Caddy..."
docker restart "$CADDY_CONTAINER" >/dev/null
echo
echo "Done."
echo "Open: https://$DOMAIN"