Update Dockerfile
Browse files- Dockerfile +71 -58
Dockerfile
CHANGED
|
@@ -2,102 +2,115 @@
|
|
| 2 |
FROM lbjlaq/antigravity-manager:latest
|
| 3 |
|
| 4 |
USER root
|
| 5 |
-
|
| 6 |
-
# curl is the only thing we need for Supabase REST API
|
| 7 |
-
RUN apt-get update && apt-get install -y --no-install-recommends curl && rm -rf /var/lib/apt/lists/*
|
| 8 |
|
| 9 |
ENV DATA_DIR=/root/.antigravity_tools
|
| 10 |
ENV SYNC_INTERVAL=30
|
| 11 |
-
|
| 12 |
EXPOSE 8045
|
| 13 |
|
| 14 |
-
# Inline entrypoint β pull on start, push on change, push on shutdown
|
| 15 |
COPY --chmod=755 <<'SCRIPT' /entrypoint.sh
|
| 16 |
#!/bin/bash
|
| 17 |
set -e
|
| 18 |
|
| 19 |
DATA_DIR="${DATA_DIR:-/root/.antigravity_tools}"
|
| 20 |
SYNC_INTERVAL="${SYNC_INTERVAL:-30}"
|
| 21 |
-
SYNC_FILE="/tmp/antigravity_data.tar.gz"
|
| 22 |
LAST_SYNC="/tmp/.last_sync"
|
| 23 |
|
| 24 |
-
|
| 25 |
-
local
|
| 26 |
-
|
| 27 |
-
"${SUPABASE_URL}/storage/v1/object/${SUPABASE_BUCKET}
|
| 28 |
-H "Authorization: Bearer ${SUPABASE_KEY}" \
|
| 29 |
-
-H "
|
| 30 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 31 |
}
|
| 32 |
|
| 33 |
-
|
| 34 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 35 |
curl -s -X POST \
|
| 36 |
-
"${SUPABASE_URL}/storage/v1/object/${SUPABASE_BUCKET}/
|
| 37 |
-H "Authorization: Bearer ${SUPABASE_KEY}" \
|
| 38 |
-
-H "Content-Type: application/
|
| 39 |
-H "x-upsert: true" \
|
| 40 |
-
--data-binary
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 41 |
touch "$LAST_SYNC"
|
| 42 |
-
echo "[Sync]
|
| 43 |
}
|
| 44 |
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 48 |
}
|
| 49 |
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
tar xzf "$SYNC_FILE" -C "$(dirname "$DATA_DIR")" 2>/dev/null
|
| 57 |
-
touch "$LAST_SYNC"
|
| 58 |
-
echo "[Sync] Restore complete!"
|
| 59 |
-
else
|
| 60 |
-
echo "[Sync] No backup found β first run."
|
| 61 |
-
fi
|
| 62 |
-
rm -f "$SYNC_FILE"
|
| 63 |
-
else
|
| 64 |
-
echo "[Sync] No Supabase config β running without sync."
|
| 65 |
fi
|
| 66 |
|
| 67 |
-
# ββ Step 2: Start the app ββ
|
| 68 |
/app/antigravity-tools --headless &
|
| 69 |
APP_PID=$!
|
| 70 |
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
echo "[Sync] Waiting for data directory..."
|
| 74 |
while [ ! -d "$DATA_DIR" ]; do sleep 2; done
|
| 75 |
-
sleep 5
|
| 76 |
-
supabase_upload
|
| 77 |
fi
|
| 78 |
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
(
|
| 82 |
-
while kill -0 $APP_PID 2>/dev/null; do
|
| 83 |
-
sleep "$SYNC_INTERVAL"
|
| 84 |
-
has_changes && supabase_upload
|
| 85 |
-
done
|
| 86 |
-
) &
|
| 87 |
SYNC_PID=$!
|
| 88 |
fi
|
| 89 |
|
| 90 |
-
# ββ Step 5: Final sync on shutdown ββ
|
| 91 |
cleanup() {
|
| 92 |
-
echo "[Sync] Shutting down
|
| 93 |
-
[ -n "$
|
| 94 |
-
kill $APP_PID 2>/dev/null
|
| 95 |
-
|
| 96 |
-
wait $APP_PID 2>/dev/null
|
| 97 |
-
exit 0
|
| 98 |
}
|
| 99 |
trap cleanup SIGTERM SIGINT
|
| 100 |
-
|
| 101 |
wait $APP_PID
|
| 102 |
SCRIPT
|
| 103 |
|
|
|
|
| 2 |
FROM lbjlaq/antigravity-manager:latest
|
| 3 |
|
| 4 |
USER root
|
| 5 |
+
RUN apt-get update && apt-get install -y --no-install-recommends curl jq && rm -rf /var/lib/apt/lists/*
|
|
|
|
|
|
|
| 6 |
|
| 7 |
ENV DATA_DIR=/root/.antigravity_tools
|
| 8 |
ENV SYNC_INTERVAL=30
|
|
|
|
| 9 |
EXPOSE 8045
|
| 10 |
|
|
|
|
| 11 |
COPY --chmod=755 <<'SCRIPT' /entrypoint.sh
|
| 12 |
#!/bin/bash
|
| 13 |
set -e
|
| 14 |
|
| 15 |
DATA_DIR="${DATA_DIR:-/root/.antigravity_tools}"
|
| 16 |
SYNC_INTERVAL="${SYNC_INTERVAL:-30}"
|
|
|
|
| 17 |
LAST_SYNC="/tmp/.last_sync"
|
| 18 |
|
| 19 |
+
supabase_list() {
|
| 20 |
+
local prefix="$1" response files folders
|
| 21 |
+
response=$(curl -s -X POST \
|
| 22 |
+
"${SUPABASE_URL}/storage/v1/object/list/${SUPABASE_BUCKET}" \
|
| 23 |
-H "Authorization: Bearer ${SUPABASE_KEY}" \
|
| 24 |
+
-H "Content-Type: application/json" \
|
| 25 |
+
-d "{\"prefix\":\"${prefix}\",\"limit\":1000}" 2>/dev/null)
|
| 26 |
+
files=$(echo "$response" | jq -r '.[]? | select(.id != null) | .name' 2>/dev/null)
|
| 27 |
+
folders=$(echo "$response" | jq -r '.[]? | select(.id == null) | .name' 2>/dev/null)
|
| 28 |
+
for f in $files; do [ -n "$f" ] && echo "${prefix}${f}"; done
|
| 29 |
+
for d in $folders; do [ -n "$d" ] && supabase_list "${prefix}${d}/"; done
|
| 30 |
}
|
| 31 |
|
| 32 |
+
supabase_pull() {
|
| 33 |
+
echo "[Sync] Pulling files from Supabase..."
|
| 34 |
+
supabase_list "" | while read -r fp; do
|
| 35 |
+
mkdir -p "$(dirname "$DATA_DIR/$fp")"
|
| 36 |
+
curl -s -o "$DATA_DIR/$fp" \
|
| 37 |
+
"${SUPABASE_URL}/storage/v1/object/${SUPABASE_BUCKET}/${fp}" \
|
| 38 |
+
-H "Authorization: Bearer ${SUPABASE_KEY}"
|
| 39 |
+
echo "[Sync] <- $fp"
|
| 40 |
+
done
|
| 41 |
+
touch "$LAST_SYNC"
|
| 42 |
+
echo "[Sync] Pull complete!"
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
supabase_push_file() {
|
| 46 |
+
local rel="${1#$DATA_DIR/}"
|
| 47 |
curl -s -X POST \
|
| 48 |
+
"${SUPABASE_URL}/storage/v1/object/${SUPABASE_BUCKET}/${rel}" \
|
| 49 |
-H "Authorization: Bearer ${SUPABASE_KEY}" \
|
| 50 |
+
-H "Content-Type: application/octet-stream" \
|
| 51 |
-H "x-upsert: true" \
|
| 52 |
+
--data-binary "@${1}" > /dev/null 2>&1
|
| 53 |
+
}
|
| 54 |
+
|
| 55 |
+
supabase_push_all() {
|
| 56 |
+
echo "[Sync] Pushing all files..."
|
| 57 |
+
find "$DATA_DIR" -type f | while read -r f; do
|
| 58 |
+
supabase_push_file "$f"
|
| 59 |
+
echo "[Sync] -> ${f#$DATA_DIR/}"
|
| 60 |
+
done
|
| 61 |
touch "$LAST_SYNC"
|
| 62 |
+
echo "[Sync] Push complete!"
|
| 63 |
}
|
| 64 |
|
| 65 |
+
supabase_push_changed() {
|
| 66 |
+
local changed
|
| 67 |
+
changed=$(find "$DATA_DIR" -type f -newer "$LAST_SYNC" 2>/dev/null)
|
| 68 |
+
[ -z "$changed" ] && return 1
|
| 69 |
+
echo "$changed" | while read -r f; do
|
| 70 |
+
supabase_push_file "$f"
|
| 71 |
+
echo "[Sync] -> ${f#$DATA_DIR/}"
|
| 72 |
+
done
|
| 73 |
+
touch "$LAST_SYNC"
|
| 74 |
+
}
|
| 75 |
+
|
| 76 |
+
supabase_has_data() {
|
| 77 |
+
local r
|
| 78 |
+
r=$(curl -s -X POST \
|
| 79 |
+
"${SUPABASE_URL}/storage/v1/object/list/${SUPABASE_BUCKET}" \
|
| 80 |
+
-H "Authorization: Bearer ${SUPABASE_KEY}" \
|
| 81 |
+
-H "Content-Type: application/json" -d '{"prefix":"","limit":1}' 2>/dev/null)
|
| 82 |
+
[ "$(echo "$r" | jq 'length' 2>/dev/null)" != "0" ]
|
| 83 |
}
|
| 84 |
|
| 85 |
+
SYNC=""
|
| 86 |
+
[ -n "$SUPABASE_URL" ] && [ -n "$SUPABASE_KEY" ] && [ -n "$SUPABASE_BUCKET" ] && SYNC="1"
|
| 87 |
+
|
| 88 |
+
if [ -n "$SYNC" ]; then
|
| 89 |
+
echo "[Sync] Checking Supabase..."
|
| 90 |
+
if supabase_has_data; then supabase_pull; else echo "[Sync] Empty bucket β first run."; fi
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 91 |
fi
|
| 92 |
|
|
|
|
| 93 |
/app/antigravity-tools --headless &
|
| 94 |
APP_PID=$!
|
| 95 |
|
| 96 |
+
if [ -n "$SYNC" ] && [ ! -f "$LAST_SYNC" ]; then
|
| 97 |
+
echo "[Sync] Waiting for data dir..."
|
|
|
|
| 98 |
while [ ! -d "$DATA_DIR" ]; do sleep 2; done
|
| 99 |
+
sleep 5 && supabase_push_all
|
|
|
|
| 100 |
fi
|
| 101 |
|
| 102 |
+
if [ -n "$SYNC" ]; then
|
| 103 |
+
( while kill -0 $APP_PID 2>/dev/null; do sleep "$SYNC_INTERVAL"; supabase_push_changed || true; done ) &
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 104 |
SYNC_PID=$!
|
| 105 |
fi
|
| 106 |
|
|
|
|
| 107 |
cleanup() {
|
| 108 |
+
echo "[Sync] Shutting down..."
|
| 109 |
+
[ -n "$SYNC" ] && [ -d "$DATA_DIR" ] && supabase_push_all
|
| 110 |
+
kill $APP_PID 2>/dev/null; [ -n "$SYNC_PID" ] && kill $SYNC_PID 2>/dev/null
|
| 111 |
+
wait $APP_PID 2>/dev/null; exit 0
|
|
|
|
|
|
|
| 112 |
}
|
| 113 |
trap cleanup SIGTERM SIGINT
|
|
|
|
| 114 |
wait $APP_PID
|
| 115 |
SCRIPT
|
| 116 |
|