feat(ops): production resilience — healthchecks, restart_policy, log-rotation, --wait deploy [skip ci]
This commit is contained in:
@@ -152,11 +152,11 @@ jobs:
|
|||||||
if [ -n '${{ inputs.service }}' ]; then
|
if [ -n '${{ inputs.service }}' ]; then
|
||||||
echo '🚀 Deploying service: ${{ inputs.service }}'
|
echo '🚀 Deploying service: ${{ inputs.service }}'
|
||||||
docker compose build ${BUILD_ARGS} ${{ inputs.service }}
|
docker compose build ${BUILD_ARGS} ${{ inputs.service }}
|
||||||
docker compose up -d --force-recreate ${{ inputs.service }}
|
docker compose up -d --wait --force-recreate ${{ inputs.service }}
|
||||||
else
|
else
|
||||||
echo '🚀 Deploying all services'
|
echo '🚀 Deploying all services'
|
||||||
docker compose build ${BUILD_ARGS}
|
docker compose build ${BUILD_ARGS}
|
||||||
docker compose up -d --force-recreate
|
docker compose up -d --wait --force-recreate
|
||||||
fi
|
fi
|
||||||
"
|
"
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ RUN dotnet publish -c Release -o /app/publish
|
|||||||
FROM mcr.microsoft.com/dotnet/aspnet:10.0-alpine
|
FROM mcr.microsoft.com/dotnet/aspnet:10.0-alpine
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY --from=build /app/publish .
|
COPY --from=build /app/publish .
|
||||||
|
RUN apk add --no-cache curl
|
||||||
USER $APP_UID
|
USER $APP_UID
|
||||||
EXPOSE 8080
|
EXPOSE 8080
|
||||||
ENTRYPOINT ["dotnet", "Nexus.Api.dll"]
|
ENTRYPOINT ["dotnet", "Nexus.Api.dll"]
|
||||||
|
|||||||
@@ -15,12 +15,24 @@ services:
|
|||||||
interval: 10s
|
interval: 10s
|
||||||
timeout: 5s
|
timeout: 5s
|
||||||
retries: 5
|
retries: 5
|
||||||
|
start_period: 30s
|
||||||
networks: [nexus]
|
networks: [nexus]
|
||||||
|
logging:
|
||||||
|
driver: "json-file"
|
||||||
|
options:
|
||||||
|
max-size: "10m"
|
||||||
|
max-file: "3"
|
||||||
|
|
||||||
api:
|
api:
|
||||||
build:
|
build:
|
||||||
context: ./backend
|
context: ./backend
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
deploy:
|
||||||
|
restart_policy:
|
||||||
|
condition: on-failure
|
||||||
|
delay: 5s
|
||||||
|
max_attempts: 3
|
||||||
|
window: 120s
|
||||||
environment:
|
environment:
|
||||||
ASPNETCORE_ENVIRONMENT: Production
|
ASPNETCORE_ENVIRONMENT: Production
|
||||||
ASPNETCORE_URLS: http://+:8080
|
ASPNETCORE_URLS: http://+:8080
|
||||||
@@ -40,6 +52,12 @@ services:
|
|||||||
depends_on:
|
depends_on:
|
||||||
postgres:
|
postgres:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "curl -f http://localhost:8080/health || exit 1"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 15s
|
||||||
volumes:
|
volumes:
|
||||||
- /opt/openclaw/data/openclaw/openclaw.json:/home/node/.openclaw/openclaw.json:ro
|
- /opt/openclaw/data/openclaw/openclaw.json:/home/node/.openclaw/openclaw.json:ro
|
||||||
- /opt/openclaw/data/openclaw/workspace-iris:/mnt/workspace-iris
|
- /opt/openclaw/data/openclaw/workspace-iris:/mnt/workspace-iris
|
||||||
@@ -51,15 +69,37 @@ services:
|
|||||||
networks:
|
networks:
|
||||||
- nexus
|
- nexus
|
||||||
- openclaw_default
|
- openclaw_default
|
||||||
|
logging:
|
||||||
|
driver: "json-file"
|
||||||
|
options:
|
||||||
|
max-size: "10m"
|
||||||
|
max-file: "3"
|
||||||
|
|
||||||
web:
|
web:
|
||||||
build:
|
build:
|
||||||
context: ./frontend
|
context: ./frontend
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
deploy:
|
||||||
|
restart_policy:
|
||||||
|
condition: on-failure
|
||||||
|
delay: 5s
|
||||||
|
max_attempts: 3
|
||||||
|
window: 120s
|
||||||
ports:
|
ports:
|
||||||
- "127.0.0.1:18880:80"
|
- "127.0.0.1:18880:80"
|
||||||
depends_on: [api]
|
depends_on: [api]
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:80/ || exit 1"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 10s
|
||||||
networks: [nexus]
|
networks: [nexus]
|
||||||
|
logging:
|
||||||
|
driver: "json-file"
|
||||||
|
options:
|
||||||
|
max-size: "10m"
|
||||||
|
max-file: "3"
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
nexus:
|
nexus:
|
||||||
|
|||||||
+8
-7
@@ -12,18 +12,21 @@ echo "Verzeichnis: $NEXUS_DIR"
|
|||||||
cd "$NEXUS_DIR"
|
cd "$NEXUS_DIR"
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "[1/3] Prüfe Konfiguration..."
|
echo "[1/4] Prüfe Konfiguration..."
|
||||||
docker compose config --quiet && echo " ✅ Konfiguration gültig"
|
docker compose config --quiet && echo " ✅ Konfiguration gültig"
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "[2/3] Starte Stack..."
|
echo "[2/4] Starte Stack (mit Healthchecks)..."
|
||||||
docker compose up -d
|
docker compose up -d --wait
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "[3/3] Warte auf Services..."
|
echo "[3/4] Status nach Deployment..."
|
||||||
sleep 5
|
|
||||||
docker compose ps
|
docker compose ps
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "[4/4] Verifikation..."
|
||||||
|
curl -fsS http://localhost:18880/health && echo " ✅ Health-Check bestanden"
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "=== Fertig ==="
|
echo "=== Fertig ==="
|
||||||
echo "Nexus Web: http://nexus.noveria.net:18880"
|
echo "Nexus Web: http://nexus.noveria.net:18880"
|
||||||
@@ -32,5 +35,3 @@ echo "Passwort: wird beim ersten Start im Container-Log ausgegeben"
|
|||||||
echo ""
|
echo ""
|
||||||
echo "Logs: docker compose logs api | grep 'Initial owner'"
|
echo "Logs: docker compose logs api | grep 'Initial owner'"
|
||||||
echo "Status: docker compose ps"
|
echo "Status: docker compose ps"
|
||||||
# Patch für compose.yaml
|
|
||||||
sed -i 's/${OWNER_PASSWORD:?Set OWNER_PASSWORD in .env}/${OWNER_PASSWORD:-}/' "$NEXUS_DIR/compose.yaml"
|
|
||||||
|
|||||||
Reference in New Issue
Block a user