From 5e8ae0c39404c872856bdd9171b33785f01ea490 Mon Sep 17 00:00:00 2001 From: juanminsanz Date: Sun, 20 Sep 2026 12:10:36 +0200 Subject: [PATCH] 20-sep: watchdog Gitea (systemd) + fix monitor Kuma --- CHANGELOG_INFRA.md | 8 +++++ changelog_infra.json | 12 +++++++ vps/gitea/README.md | 56 +++++++++++++++++++++++++++++ vps/gitea/gitea-watchdog.service | 8 +++++ vps/gitea/gitea-watchdog.timer | 10 ++++++ vps/gitea/gitea_watchdog.sh | 60 ++++++++++++++++++++++++++++++++ 6 files changed, 154 insertions(+) create mode 100644 vps/gitea/README.md create mode 100644 vps/gitea/gitea-watchdog.service create mode 100644 vps/gitea/gitea-watchdog.timer create mode 100644 vps/gitea/gitea_watchdog.sh diff --git a/CHANGELOG_INFRA.md b/CHANGELOG_INFRA.md index 824539e..d2ab85b 100644 --- a/CHANGELOG_INFRA.md +++ b/CHANGELOG_INFRA.md @@ -42,3 +42,11 @@ - **Transferible**: no - **Aplicado en**: VPS - **Detalle**: git.v-encore-lab.com (185.187.169.109) devolvia 502. Causa: contenedor gitea con capa de escritura corrupta (/app/gitea/gitea Permission denied, 3595 reinicios). Fix: recrear solo el contenedor desde /root/docker-compose.yml (docker compose up -d --force-recreate --no-deps gitea). Datos intactos en /root/gitea/data. Gitea 1.25.5, healthz pass. + +### 2026-09-20 · Gitea: watchdog systemd (recrea contenedor) + fix URL monitor Kuma +- **id**: `2026-09-20-gitea-watchdog-systemd-recrea-contenedor-fix-url-monitor-kum` +- **Equipo**: VPS +- **Categoria**: servicios +- **Transferible**: no +- **Aplicado en**: VPS +- **Detalle**: VPS: /opt/gitea-watchdog/gitea_watchdog.sh + timer systemd cada 2min (recrea gitea si falla 2 veces). Verificado parando gitea. Monitor Uptime-Kuma 'Gitea - Repositorios' corregido (URL tenia punto final) con alerta email SMTP. Ficheros en INFRAESTRUCTURA/vps/gitea/. diff --git a/changelog_infra.json b/changelog_infra.json index 4890d1b..8fdb6f3 100644 --- a/changelog_infra.json +++ b/changelog_infra.json @@ -48,6 +48,18 @@ "VPS" ], "detalle": "git.v-encore-lab.com (185.187.169.109) devolvia 502. Causa: contenedor gitea con capa de escritura corrupta (/app/gitea/gitea Permission denied, 3595 reinicios). Fix: recrear solo el contenedor desde /root/docker-compose.yml (docker compose up -d --force-recreate --no-deps gitea). Datos intactos en /root/gitea/data. Gitea 1.25.5, healthz pass." + }, + { + "id": "2026-09-20-gitea-watchdog-systemd-recrea-contenedor-fix-url-monitor-kum", + "fecha": "2026-09-20", + "equipo": "VPS", + "categoria": "servicios", + "titulo": "Gitea: watchdog systemd (recrea contenedor) + fix URL monitor Kuma", + "transferible": false, + "aplicado_en": [ + "VPS" + ], + "detalle": "VPS: /opt/gitea-watchdog/gitea_watchdog.sh + timer systemd cada 2min (recrea gitea si falla 2 veces). Verificado parando gitea. Monitor Uptime-Kuma 'Gitea - Repositorios' corregido (URL tenia punto final) con alerta email SMTP. Ficheros en INFRAESTRUCTURA/vps/gitea/." } ] } diff --git a/vps/gitea/README.md b/vps/gitea/README.md new file mode 100644 index 0000000..a36ee5b --- /dev/null +++ b/vps/gitea/README.md @@ -0,0 +1,56 @@ +# Gitea (VPS Contabo) — watchdog + monitor + +## Contexto + +- `git.v-encore-lab.com` → **185.187.169.109** (VPS Contabo). +- Contenedor `gitea` definido en `/root/docker-compose.yml` (proyecto `root`, red `root_gitea_gitea`). +- Datos en el bind **`/root/gitea/data`** (recrear el contenedor NO los toca). +- Delante: `nginx-proxy-manager` (Gitea escucha en el 3000 interno, sin puerto publicado). + +## Incidente 20-sep-2026 (502) + +El contenedor `gitea` entró en **bucle de reinicio** (3595 reinicios) por una capa de +escritura corrupta: `/app/gitea/gitea: Permission denied`. La imagen y la DB estaban bien. +Se resolvió recreando el contenedor: + +```bash +cd /root && docker compose up -d --force-recreate --no-deps gitea +``` + +## Watchdog (recrea el contenedor si vuelve a pasar) + +`gitea_watchdog.sh` comprueba cada 2 min: +1. Estado del contenedor (`docker inspect`). +2. `docker exec gitea wget -qO- http://127.0.0.1:3000/api/healthz`. + +Si falla **2 veces seguidas** (`MAX_FAILS=2`), recrea el contenedor con +`docker compose up -d --force-recreate --no-deps gitea`. + +- Log: `/var/log/gitea-watchdog.log` (rota a 1 MB). +- Estado: `/var/lib/gitea-watchdog/fails`. + +### Instalación (en el VPS) + +```bash +mkdir -p /opt/gitea-watchdog /var/lib/gitea-watchdog +cp gitea_watchdog.sh /opt/gitea-watchdog/ && chmod +x /opt/gitea-watchdog/gitea_watchdog.sh +cp gitea-watchdog.service gitea-watchdog.timer /etc/systemd/system/ +systemctl daemon-reload +systemctl enable --now gitea-watchdog.timer +``` + +Comprobar: + +```bash +systemctl list-timers gitea-watchdog.timer +tail -20 /var/log/gitea-watchdog.log +``` + +## Monitor en Uptime-Kuma + +Monitor existente `Gitea - Repositorios` (id 1): `https://git.v-encore-lab.com`, cada 60 s, +notificación **ALERTA MONITORES** (email SMTP). Se corrigió la URL (tenía un punto final: +`https://git.v-encore-lab.com.`). + +> Editar el monitor en la DB: parar `uptime-kuma`, `sqlite3 /root/uptime-kuma/kuma.db "UPDATE ..."`, +> y volver a arrancarlo (Uptime-Kuma lee la DB al iniciar). diff --git a/vps/gitea/gitea-watchdog.service b/vps/gitea/gitea-watchdog.service new file mode 100644 index 0000000..b282bc2 --- /dev/null +++ b/vps/gitea/gitea-watchdog.service @@ -0,0 +1,8 @@ +[Unit] +Description=Vigilante de Gitea (recrea el contenedor si entra en bucle o deja de responder) +After=docker.service +Requires=docker.service + +[Service] +Type=oneshot +ExecStart=/opt/gitea-watchdog/gitea_watchdog.sh diff --git a/vps/gitea/gitea-watchdog.timer b/vps/gitea/gitea-watchdog.timer new file mode 100644 index 0000000..3c99859 --- /dev/null +++ b/vps/gitea/gitea-watchdog.timer @@ -0,0 +1,10 @@ +[Unit] +Description=Ejecuta el vigilante de Gitea cada 2 minutos + +[Timer] +OnBootSec=2min +OnUnitActiveSec=2min +AccuracySec=15s + +[Install] +WantedBy=timers.target diff --git a/vps/gitea/gitea_watchdog.sh b/vps/gitea/gitea_watchdog.sh new file mode 100644 index 0000000..4b887e1 --- /dev/null +++ b/vps/gitea/gitea_watchdog.sh @@ -0,0 +1,60 @@ +#!/bin/bash +# Vigilante de Gitea (VPS Contabo). +# Si el contenedor no esta sano N veces seguidas, lo recrea desde /root/docker-compose.yml. +# Los datos viven en el bind /root/gitea/data, por lo que recrear NO los toca. +set -u + +DOCKER=/usr/bin/docker +COMPOSE_DIR=/root +CONTAINER=gitea +HEALTH_URL=http://127.0.0.1:3000/api/healthz +LOG=/var/log/gitea-watchdog.log +STATE_DIR=/var/lib/gitea-watchdog +STATE=$STATE_DIR/fails +MAX_FAILS=2 + +mkdir -p "$STATE_DIR" +touch "$STATE" + +log() { echo "$(date '+%F %T') $*" >> "$LOG"; } + +# Rotar log si crece demasiado (1 MB) +if [ -f "$LOG" ] && [ "$(stat -c%s "$LOG" 2>/dev/null || echo 0)" -gt 1048576 ]; then + mv -f "$LOG" "$LOG.1" +fi + +status=$("$DOCKER" inspect "$CONTAINER" --format '{{.State.Status}}' 2>/dev/null || echo missing) + +healthy=0 +if [ "$status" = "running" ]; then + body=$("$DOCKER" exec "$CONTAINER" wget -qO- --timeout=8 "$HEALTH_URL" 2>/dev/null || true) + if echo "$body" | grep -q '"status": *"pass"'; then + healthy=1 + fi +fi + +if [ "$healthy" = "1" ]; then + if [ "$(cat "$STATE" 2>/dev/null || echo 0)" != "0" ]; then + log "Gitea vuelve a estar OK (status=$status)." + fi + echo 0 > "$STATE" + exit 0 +fi + +fails=$(cat "$STATE" 2>/dev/null || echo 0) +case "$fails" in ''|*[!0-9]*) fails=0 ;; esac +fails=$((fails + 1)) +echo "$fails" > "$STATE" +log "Gitea NO saludable (status=$status, fallo $fails/$MAX_FAILS)." + +if [ "$fails" -ge "$MAX_FAILS" ]; then + log "Recreando contenedor '$CONTAINER' desde $COMPOSE_DIR ..." + cd "$COMPOSE_DIR" || { log "ERROR: no existe $COMPOSE_DIR"; exit 1; } + if "$DOCKER" compose version >/dev/null 2>&1; then + "$DOCKER" compose up -d --force-recreate --no-deps "$CONTAINER" >> "$LOG" 2>&1 + else + docker-compose up -d --force-recreate --no-deps "$CONTAINER" >> "$LOG" 2>&1 + fi + log "Recreacion lanzada (exit=$?)." + echo 0 > "$STATE" +fi