Fix: persistent volume provjera + sekvencijalni startup + env kredencijali
Browse files- Dockerfile +6 -1
- backup_restore.sh +40 -9
- setup_endpoints.sh +13 -3
Dockerfile
CHANGED
|
@@ -27,4 +27,9 @@ RUN chmod +x /app/setup_endpoints.sh /app/backup_restore.sh
|
|
| 27 |
|
| 28 |
EXPOSE 8080
|
| 29 |
|
| 30 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 27 |
|
| 28 |
EXPOSE 8080
|
| 29 |
|
| 30 |
+
# POPRAVLJENI STARTUP REDOSLIJED:
|
| 31 |
+
# 1. Restore se zavrsi PRIJE nego WebUI krene (semicolon = sekvencijalan)
|
| 32 |
+
# 2. Backup loop pokrenuti u pozadini (&)
|
| 33 |
+
# 3. setup_endpoints.sh ceka 10s i konfigurira endpointe u pozadini (&)
|
| 34 |
+
# 4. start.sh ostaje glavni proces (foreground)
|
| 35 |
+
CMD bash -lc "bash /app/backup_restore.sh restore; bash /app/backup_restore.sh loop & sleep 10 && bash /app/setup_endpoints.sh & bash start.sh"
|
backup_restore.sh
CHANGED
|
@@ -19,17 +19,29 @@ if [ -z "$HF_REPO" ] || [ -z "$HF_TOKEN" ]; then
|
|
| 19 |
exit 0
|
| 20 |
fi
|
| 21 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
backup_archive() {
|
| 23 |
local archive_path="$1"
|
| 24 |
mkdir -p "$(dirname "$archive_path")"
|
| 25 |
tar -czf "$archive_path" -C "$DATA_DIR" .
|
| 26 |
}
|
| 27 |
|
| 28 |
-
|
| 29 |
-
echo "Pokusavam restore Open WebUI data iz ${HF_REPO}..."
|
| 30 |
-
|
| 31 |
mkdir -p "$DATA_DIR"
|
| 32 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
HTTP_STATUS=$(curl -s -o /tmp/openwebui_restore.tar.gz -w "%{http_code}" \
|
| 34 |
-L \
|
| 35 |
-H "Authorization: Bearer ${HF_TOKEN}" \
|
|
@@ -79,10 +91,29 @@ backup_archive_to_hf() {
|
|
| 79 |
fi
|
| 80 |
}
|
| 81 |
|
| 82 |
-
|
|
|
|
| 83 |
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
exit 0
|
| 20 |
fi
|
| 21 |
|
| 22 |
+
# Provjera: da li /data vec ima sadrzaj (persistent volume nije prazan)
|
| 23 |
+
data_is_populated() {
|
| 24 |
+
FILE_COUNT=$(find "$DATA_DIR" -mindepth 1 -maxdepth 2 2>/dev/null | wc -l)
|
| 25 |
+
[ "$FILE_COUNT" -ge 2 ]
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
backup_archive() {
|
| 29 |
local archive_path="$1"
|
| 30 |
mkdir -p "$(dirname "$archive_path")"
|
| 31 |
tar -czf "$archive_path" -C "$DATA_DIR" .
|
| 32 |
}
|
| 33 |
|
| 34 |
+
do_restore() {
|
|
|
|
|
|
|
| 35 |
mkdir -p "$DATA_DIR"
|
| 36 |
|
| 37 |
+
# NOVA LOGIKA: Preskoci restore ako persistent volume vec ima podatke
|
| 38 |
+
if data_is_populated; then
|
| 39 |
+
echo "Persistent volume vec ima podatke ($(find "$DATA_DIR" -mindepth 1 -maxdepth 2 | wc -l) fajlova) — preskacem restore iz HF."
|
| 40 |
+
return
|
| 41 |
+
fi
|
| 42 |
+
|
| 43 |
+
echo "Pokusavam restore Open WebUI data iz ${HF_REPO}..."
|
| 44 |
+
|
| 45 |
HTTP_STATUS=$(curl -s -o /tmp/openwebui_restore.tar.gz -w "%{http_code}" \
|
| 46 |
-L \
|
| 47 |
-H "Authorization: Bearer ${HF_TOKEN}" \
|
|
|
|
| 91 |
fi
|
| 92 |
}
|
| 93 |
|
| 94 |
+
# Podrska za mode argument: restore | loop | all (default)
|
| 95 |
+
MODE="${1:-all}"
|
| 96 |
|
| 97 |
+
case "$MODE" in
|
| 98 |
+
restore)
|
| 99 |
+
# Samo uradi restore, pa izadji (za sekvencijalni startup)
|
| 100 |
+
do_restore
|
| 101 |
+
;;
|
| 102 |
+
loop)
|
| 103 |
+
# Samo backup loop (bez restore)
|
| 104 |
+
echo "Periodicki backup svakih ${BACKUP_INTERVAL_SECONDS} sekundi je aktivan."
|
| 105 |
+
while true; do
|
| 106 |
+
sleep "$BACKUP_INTERVAL_SECONDS"
|
| 107 |
+
backup_archive_to_hf
|
| 108 |
+
done
|
| 109 |
+
;;
|
| 110 |
+
all|*)
|
| 111 |
+
# Legacy mode: restore pa loop
|
| 112 |
+
do_restore
|
| 113 |
+
echo "Periodicki backup svakih ${BACKUP_INTERVAL_SECONDS} sekundi je aktivan."
|
| 114 |
+
while true; do
|
| 115 |
+
sleep "$BACKUP_INTERVAL_SECONDS"
|
| 116 |
+
backup_archive_to_hf
|
| 117 |
+
done
|
| 118 |
+
;;
|
| 119 |
+
esac
|
setup_endpoints.sh
CHANGED
|
@@ -2,6 +2,16 @@
|
|
| 2 |
|
| 3 |
BASE_URL="http://localhost:8080"
|
| 4 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5 |
echo "Čekam da WebUI bude spreman..."
|
| 6 |
for i in {1..30}; do
|
| 7 |
STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$BASE_URL/health")
|
|
@@ -17,7 +27,7 @@ done
|
|
| 17 |
echo "Logujem se kao admin..."
|
| 18 |
LOGIN_RESPONSE=$(curl -s -X POST "$BASE_URL/api/v1/auths/signin" \
|
| 19 |
-H "Content-Type: application/json" \
|
| 20 |
-
-d
|
| 21 |
|
| 22 |
TOKEN=$(echo $LOGIN_RESPONSE | python3 -c "import sys, json; print(json.load(sys.stdin).get('token', ''))")
|
| 23 |
|
|
@@ -25,7 +35,7 @@ if [ -z "$TOKEN" ]; then
|
|
| 25 |
echo "❌ Login neuspješan, pokušavam registraciju..."
|
| 26 |
REGISTER_RESPONSE=$(curl -s -X POST "$BASE_URL/api/v1/auths/signup" \
|
| 27 |
-H "Content-Type: application/json" \
|
| 28 |
-
-d
|
| 29 |
TOKEN=$(echo $REGISTER_RESPONSE | python3 -c "import sys, json; print(json.load(sys.stdin).get('token', ''))")
|
| 30 |
fi
|
| 31 |
|
|
@@ -77,7 +87,7 @@ curl -s -X POST "$BASE_URL/openai/config/update" \
|
|
| 77 |
\"$CEREBRAS_API_KEY\",
|
| 78 |
\"$FIREWORKS_API_KEY\",
|
| 79 |
\"$XAI_API_KEY\",
|
| 80 |
-
\"$
|
| 81 |
\"$COHERE_API_KEY\",
|
| 82 |
\"${POLLINATIONS_API_KEY:-noapikey}\"
|
| 83 |
],
|
|
|
|
| 2 |
|
| 3 |
BASE_URL="http://localhost:8080"
|
| 4 |
|
| 5 |
+
# Koristimo env varijable umjesto hardkodiranih kredencijala
|
| 6 |
+
ADMIN_EMAIL="${WEBUI_ADMIN_EMAIL:-}"
|
| 7 |
+
ADMIN_PASSWORD="${WEBUI_ADMIN_PASSWORD:-}"
|
| 8 |
+
ADMIN_NAME="${WEBUI_ADMIN_NAME:-admin}"
|
| 9 |
+
|
| 10 |
+
if [ -z "$ADMIN_EMAIL" ] || [ -z "$ADMIN_PASSWORD" ]; then
|
| 11 |
+
echo "❌ WEBUI_ADMIN_EMAIL ili WEBUI_ADMIN_PASSWORD nisu postavljeni u Space Secrets."
|
| 12 |
+
exit 0
|
| 13 |
+
fi
|
| 14 |
+
|
| 15 |
echo "Čekam da WebUI bude spreman..."
|
| 16 |
for i in {1..30}; do
|
| 17 |
STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$BASE_URL/health")
|
|
|
|
| 27 |
echo "Logujem se kao admin..."
|
| 28 |
LOGIN_RESPONSE=$(curl -s -X POST "$BASE_URL/api/v1/auths/signin" \
|
| 29 |
-H "Content-Type: application/json" \
|
| 30 |
+
-d "{\"email\": \"${ADMIN_EMAIL}\", \"password\": \"${ADMIN_PASSWORD}\"}")
|
| 31 |
|
| 32 |
TOKEN=$(echo $LOGIN_RESPONSE | python3 -c "import sys, json; print(json.load(sys.stdin).get('token', ''))")
|
| 33 |
|
|
|
|
| 35 |
echo "❌ Login neuspješan, pokušavam registraciju..."
|
| 36 |
REGISTER_RESPONSE=$(curl -s -X POST "$BASE_URL/api/v1/auths/signup" \
|
| 37 |
-H "Content-Type: application/json" \
|
| 38 |
+
-d "{\"name\": \"${ADMIN_NAME}\", \"email\": \"${ADMIN_EMAIL}\", \"password\": \"${ADMIN_PASSWORD}\"}")
|
| 39 |
TOKEN=$(echo $REGISTER_RESPONSE | python3 -c "import sys, json; print(json.load(sys.stdin).get('token', ''))")
|
| 40 |
fi
|
| 41 |
|
|
|
|
| 87 |
\"$CEREBRAS_API_KEY\",
|
| 88 |
\"$FIREWORKS_API_KEY\",
|
| 89 |
\"$XAI_API_KEY\",
|
| 90 |
+
\"$HF_INFERENCE_TOKEN\",
|
| 91 |
\"$COHERE_API_KEY\",
|
| 92 |
\"${POLLINATIONS_API_KEY:-noapikey}\"
|
| 93 |
],
|