main
sh 66 lines 1.81 KB
Raw
1 #!/usr/bin/env bash
2 set -euo pipefail
3
4 default_images() {
5 docker compose config --images 2>/dev/null \
6 | grep -E '^ghcr\.io/gosuda/portal(:|-frontend:|-api:)' \
7 | sort -u \
8 | tr '\n' ' ' || true
9 }
10
11 IMAGES="${IMAGES:-$(default_images)}"
12 IMAGES="${IMAGES:-ghcr.io/gosuda/portal:2 ghcr.io/gosuda/portal-frontend:2 ghcr.io/gosuda/portal-api:2}"
13 DIGEST_FILE="${DIGEST_FILE:-.portal_image_digest}"
14 INTERVAL="${INTERVAL:-60}"
15 SERVICES="${SERVICES:-portal portal-frontend portal-api}"
16 RELOAD_NGINX="${RELOAD_NGINX:-true}"
17
18 get_remote_digest() {
19 for image in $IMAGES; do
20 digest="$(docker manifest inspect "$image" 2>/dev/null \
21 | grep -m1 '"digest"' \
22 | awk -F'"' '{print $4}')"
23 if [[ -z "$digest" ]]; then
24 return 1
25 fi
26 printf '%s=%s\n' "$image" "$digest"
27 done
28 }
29
30 echo "Watching $IMAGES for digest changes (interval: ${INTERVAL}s)"
31 echo "Compose services: $SERVICES"
32
33 update_services() {
34 docker compose pull $SERVICES
35 docker compose up -d $SERVICES
36
37 if [[ "$RELOAD_NGINX" == "true" ]]; then
38 docker compose exec -T nginx nginx -s reload
39 fi
40 }
41
42 while true; do
43 if ! NEW_DIGEST=$(get_remote_digest); then
44 NEW_DIGEST=""
45 fi
46
47 if [[ -z "$NEW_DIGEST" ]]; then
48 echo "[$(date '+%Y-%m-%d %H:%M:%S')] Failed to fetch digest, retrying in ${INTERVAL}s"
49 sleep "$INTERVAL"
50 continue
51 fi
52
53 OLD_DIGEST=""
54 if [[ -f "$DIGEST_FILE" ]]; then
55 OLD_DIGEST=$(cat "$DIGEST_FILE")
56 fi
57
58 if [[ "$NEW_DIGEST" != "$OLD_DIGEST" ]]; then
59 echo "[$(date '+%Y-%m-%d %H:%M:%S')] Digest changed: ${OLD_DIGEST:-<none>} -> $NEW_DIGEST"
60 update_services
61 echo "$NEW_DIGEST" > "$DIGEST_FILE"
62 echo "[$(date '+%Y-%m-%d %H:%M:%S')] Update completed"
63 fi
64
65 sleep "$INTERVAL"
66 done