Pour superviser Forgejo 15 LTS, on active l'endpoint /metrics protégé par un
jeton, on le fait scraper (interroger à intervalle fixe) par Prometheus
(le serveur qui collecte et stocke ces mesures), on écrit deux règles d'alerte
(up == 0 et gitea_users == 0) et, quand une alerte tombe, on remonte à la
cause par le journal du conteneur. Le fait qui change la manière de
superviser : quand la base de données s'arrête, l'endpoint répond toujours
200 et la série up reste à 1. La leçon s'adresse à l'administrateur
dont la forge tourne déjà et qui veut être prévenu avant ses utilisateurs.
Vous repartez avec cinq preuves : un niveau debug ajouté puis retiré à
chaud, un endpoint de métriques qui refuse les requêtes sans jeton, une
alerte relevée en train de passer d'inactive à pending puis firing,
une panne aveugle (base arrêtée) rattrapée par une seconde règle, et deux
pannes diagnostiquées par leur journal. Les
commandes ont été exécutées le 2026-10-16 sur la pile de la leçon
Installer Forgejo LTS (Forgejo
15.0.10, PostgreSQL 17.11, Caddy 2.11.7), avec Prometheus 3.15.0 épinglé par
son digest.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Retrouver où Forgejo écrit ses journaux, activer un fichier et un journal d'accès, et monter le niveau en
debugsans redémarrer. - Activer
/metrics, le protéger par un jeton et lire ce qu'il expose, y compris ce qu'il n'expose pas. - Configurer Prometheus pour scraper Forgejo avec un jeton lu dans un fichier.
- Rédiger une règle d'alerte et observer ses trois états.
- Comprendre pourquoi
up == 0ne voit pas une base arrêtée, et quelle règle la voit. - Diagnostiquer une panne par la méthode symptôme, journal, cause, réparation, vérification.
Quels sont les prérequis ?
Section intitulée « Quels sont les prérequis ? »Il vous faut la forge des leçons précédentes : Forgejo 15 LTS sur Docker
Compose dans /opt/forgejo-lab, avec PostgreSQL et Caddy
(installation). Les notions de
fichier de surcharge et de variables FORGEJO__section__CLE viennent de
Maintenance courante, la montée de
version et ses critères de Mettre à jour Forgejo,
la restauration de Sauvegarder et restaurer Forgejo.
Vous devez savoir lancer docker compose et docker logs, lire un code HTTP
(401, 424, 502) et du JSON. Les concepts de Prometheus ne sont pas redits
ici : ils sont dans
Prometheus : monitoring et types de métriques
et dans Configuration de Prometheus.
Rappel en trois lignes : Prometheus scrape périodiquement des URL de
métriques et range chaque valeur dans une série ; une règle d'alerte est
une expression PromQL (son langage de requête) évaluée en continu. Cette
leçon montre ce qu'il faut en faire pour Forgejo.
Dans cette pile, le service Compose server tourne dans le conteneur
forgejo et le service db (PostgreSQL) dans le conteneur forgejo-db.
docker compose prend le nom du service, docker logs, docker exec et
docker stop celui du conteneur, et Prometheus ne voit que le nom du
service sur le réseau Docker (server, db).
Où Forgejo écrit-il ses journaux ?
Section intitulée « Où Forgejo écrit-il ses journaux ? »Par défaut, Forgejo écrit tous ses journaux sur la sortie standard du
conteneur : on les lit avec docker logs forgejo. Dans cette installation,
[log] MODE = console et LEVEL = info, et le dossier ROOT_PATH = /data/gitea/log est vide. Chaque ligne a la forme 2026/10/16 11:51:33 chemin.go:ligne:fonction() [I] message, et le niveau se lit entre crochets :
[T] trace, [D] debug, [I] info, [W] warning, [E] erreur, [F] fatal.
Le journal du routeur (une ligne par requête HTTP traitée) est actif par
défaut au niveau info :
router: completed GET /metrics for 172.30.0.4:39218, 200 OK in 14.6ms @ web/metrics.go:16(web.Metrics).
Le piège vient de la supervision elle-même : Prometheus, installé plus bas,
scrape Forgejo toutes les 5 secondes dans le lab, donc chaque scrape ajoute
une ligne. Filtrez ce bruit pour lire le reste (le filtre ne montre que les
lignes qui ne contiennent pas GET /metrics) :
docker logs forgejo 2>&1 | grep -v "GET /metrics"Une autre limite se règle ailleurs que dans Forgejo : le pilote Docker
json-file de ce conteneur n'a aucune rotation configurée
(LogConfig.Config est vide ; la documentation Docker indique que max-size
vaut -1, soit illimité, par défaut). Sur une instance qui vit des mois, le
journal du conteneur grossit sans borne. La rotation se règle au niveau du
démon Docker ou du service, à traiter avant la mise en production.
Comment activer le fichier et le journal d'accès ?
Section intitulée « Comment activer le fichier et le journal d'accès ? »Pour écrire aussi dans un fichier, on passe FORGEJO__log__MODE à
console,file ; pour un journal d'accès au format Apache, on règle
FORGEJO__log__LOGGER_ACCESS_MODE à file. On ajoute les deux variables au
service server du compose.yaml (ou d'un fichier de surcharge, comme dans la
leçon de maintenance), puis on recrée le conteneur.
FORGEJO__log__MODE: console,fileFORGEJO__log__LOGGER_ACCESS_MODE: filedocker compose up -d serverdocker exec forgejo ls /data/gitea/logLa commande doit lister gitea.log et access.log. Le journal
principal s'appelle bien gitea.log : le nom n'a pas changé en 15.0.10 et il
n'y a pas de forgejo.log. La documentation 15 donne gitea.log par défaut,
mais celle de la branche la plus récente annonce forgejo.log : ce nom
dépend de la version, vérifiez-le avant une montée de version. Le
journal d'accès est écrit dans access.log, avec des lignes comme
172.30.0.1 - - [16/Oct/2026:11:53:35 +0000] "GET /inexistant HTTP/1.1" 404 11 "" "curl/8.5.0".
L'ancienne option ENABLE_ACCESS_LOG est dépréciée et ne crée rien :
si vous l'essayez, le journal affiche [E] Deprecated config option [log] ENABLE_ACCESS_LOG present. Use [log] LOGGER_ACCESS_MODE instead. Aucune des
rotations évoquées dans cette section n'a été testée : ni celle du démon Docker
vue plus haut, ni celle des fichiers (ROTATE, MAX_SIZE).
Un piège de persistance rend ce message tenace : les variables FORGEJO__*
sont écrites dans app.ini au démarrage et y restent quand on les
retire du compose. La clé dépréciée a donc continué d'être signalée jusqu'à sa
suppression à la main, avec la commande suivante.
docker exec forgejo sed -i '/^ENABLE_ACCESS_LOG/d' /data/gitea/conf/app.inidocker restart forgejoAprès cette commande et le redémarrage, la ligne [E] Deprecated config option ne revient plus dans docker logs forgejo. Un message deprecated
isolé est resté une fois dans le journal sans que son origine soit
identifiée : un reste d'avant le nettoyage, à surveiller plutôt qu'à
chercher.
Comment passer en debug sans redémarrer ?
Section intitulée « Comment passer en debug sans redémarrer ? »La commande forgejo manager logging add file ajoute un écrivain de
journal à chaud, au niveau debug, et forgejo manager logging remove le
retire : aucun redémarrage, aucun changement d'app.ini. C'est le bon outil
pour une panne qu'on observe en direct, parce qu'un niveau debug permanent
noie le disque.
docker exec -u git forgejo forgejo manager logging add file \ --logger default --writer debug-temp --level debug \ --filename /data/gitea/log/debug-temp.logLa réponse est Added. L'option se nomme --writer (il n'y a pas de
--name). Seuls les types file et conn s'ajoutent ainsi, pas console.
Pour l'observer, demandez une page inexistante avec curl -sk -o /dev/null https://forge.lab.test/inexistant, puis lisez debug-temp.log dans
/data/gitea/log. La requête y produit [D] GetUserByName: user redirect does not exist [name: inexistant], suivi d'une pile d'appels Go de plusieurs
dizaines de lignes (76 lignes au total dans le fichier pour cette seule
requête). Les lignes du routeur n'y figurent pas : elles appartiennent à un
autre logger. Quand vous avez fini d'observer, retirez l'écrivain :
docker exec -u git forgejo forgejo manager logging remove debug-temp --logger defaultLa réponse est Removed. L'autre voie, FORGEJO__log__LEVEL: debug avec
recréation du conteneur, n'a pas été rejouée : elle écrit dans app.ini et
impose de penser à la défaire.
Quelles métriques Forgejo expose-t-il ?
Section intitulée « Quelles métriques Forgejo expose-t-il ? »Forgejo expose ses métriques sur /metrics, désactivé par défaut, protégé par
un jeton, et elles sont toutes préfixées gitea_ : aucune forgejo_* n'existe
en 15.0.10. Deux variables suffisent dans le service server du compose. Le
jeton est une valeur aléatoire (par exemple openssl rand -hex 24) rangée dans
le .env, jamais dans le YAML.
FORGEJO__metrics__ENABLED: "true"FORGEJO__metrics__TOKEN: ${JETON_METRIQUES}Le .env porte la ligne JETON_METRIQUES=<valeur aléatoire de votre choix>
(gabarit : ne copiez aucune valeur d'un exemple). Le client présente ce
jeton dans l'en-tête HTTP Authorization: Bearer <jeton> : c'est un jeton
bearer (« porteur »), que n'importe quel porteur peut utiliser, d'où le soin
à ne pas l'afficher. Après docker compose up -d server, trois requêtes sur
https://forge.lab.test/metrics montrent que l'endpoint se protège :
| Requête | Code |
|---|---|
| sans en-tête | 401 |
Authorization: Bearer faux | 401 |
Authorization: Bearer <jeton> | 200, environ 11 100 octets, 66 familles |
Pour rejouer les trois requêtes sans afficher le jeton, lisez-le dans le
.env depuis /opt/forgejo-lab (la taille varie de quelques octets d'un
appel à l'autre) :
cd /opt/forgejo-labJETON=$(grep '^JETON_METRIQUES=' .env | cut -d= -f2)curl -sk -o /dev/null -w '%{http_code}\n' https://forge.lab.test/metricscurl -sk -o /dev/null -w '%{http_code}\n' \ -H "Authorization: Bearer faux" https://forge.lab.test/metricscurl -sk -o /dev/null -w '%{http_code} %{size_download}\n' \ -H "Authorization: Bearer $JETON" https://forge.lab.test/metricsLa sortie attendue est 401, 401, puis 200 suivi de la taille.
Sans [metrics] ENABLED, l'endpoint n'existe pas (réglage par défaut false,
non rejoué). Le contenu appartient à deux groupes de métriques. Les jauges
applicatives gitea_* (une jauge est une valeur qui monte et descend)
comptent les objets de l'instance : gitea_users,
gitea_repositories, gitea_organizations, gitea_teams, gitea_issues,
gitea_issues_open, gitea_comments, gitea_releases, gitea_webhooks,
gitea_publickeys, gitea_mirrors, gitea_attachments, et gitea_build_info
(étiquettes version, goversion). Sur l'instance propre, gitea_users vaut
1 et le reste 0. Le Go standard apporte go_*, process_* (dont
process_start_time_seconds, process_resident_memory_bytes,
process_open_fds) et promhttp_*. Deux réglages facultatifs, ENABLED_ISSUE_BY_LABEL et
ENABLED_ISSUE_BY_REPOSITORY (faux par défaut), ajoutent des séries de tickets
par étiquette ou par dépôt ; ils n'étaient pas activés ici.
Il faut aussi savoir ce qui manque : aucune métrique de file de tâches,
de latence HTTP ni de runner. Une file qui grossit n'est donc pas
alertable dans cette version ; elle se lit avec forgejo manager flush-queues
ou dans l'administration web (non rejoué ici). Pour le runner, voir
Exploiter le runner.
Comment Prometheus scrape-t-il Forgejo avec le jeton ?
Section intitulée « Comment Prometheus scrape-t-il Forgejo avec le jeton ? »Prometheus lit le jeton dans un fichier grâce à authorization.credentials_file
et interroge Forgejo directement sur son port interne 3000, sans passer par
Caddy. Le jeton circule alors en clair sur le réseau Docker, pas sur le LAN :
c'est un compromis assumé, à refaire autrement si Prometheus tourne sur une
autre machine. Le répertoire /opt/prometheus-lab/ contient quatre fichiers :
compose.yaml, prometheus.yml, regles.yml et forgejo.jeton. Le dossier
appartient à root : écrivez ces fichiers avec sudo tee ou un éditeur lancé par
sudo.
Le fichier forgejo.jeton contient le jeton seul, sans retour à la ligne,
appartient à l'utilisateur 65534 (celui du conteneur) et a le mode 0400. Le
conteneur rejoint le réseau externe de la pile, forgejo-lab_forgejo, et publie
son port seulement sur 127.0.0.1:9090. On crée le dossier et le fichier du
jeton (copié depuis le .env, sans l'afficher) :
sudo mkdir /opt/prometheus-lab && cd /opt/prometheus-labgrep '^JETON_METRIQUES=' /opt/forgejo-lab/.env | cut -d= -f2 \ | tr -d '\n' | sudo tee forgejo.jeton > /dev/nullsudo chown 65534 forgejo.jeton && sudo chmod 0400 forgejo.jetonVoici le fichier compose.yaml. L'image est épinglée par son digest (le
docker compose up -d qui la tire vient plus bas, après l'écriture des
deux fichiers de configuration) :
services: prometheus: image: quay.io/prometheus/prometheus:v3.15.0@sha256:efd719c99d83b060d9daefdcf00360461adf279f45ef5391f8d111892118753e ports: - "127.0.0.1:9090:9090" volumes: - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro - ./regles.yml:/etc/prometheus/regles.yml:ro - ./forgejo.jeton:/etc/prometheus/forgejo.jeton:ro - prom-data:/prometheus networks: - forgejonetworks: forgejo: name: forgejo-lab_forgejo external: truevolumes: prom-data:Le scrape se déclare dans prometheus.yml : le job forgejo présente le jeton
du fichier monté et interroge la cible server:3000. L'intervalle de 5 secondes sert à
observer vite les changements d'état pendant la démonstration ; en production,
gardez l'intervalle habituel de votre Prometheus.
global: scrape_interval: 5s evaluation_interval: 5srule_files: - /etc/prometheus/regles.ymlscrape_configs: - job_name: forgejo authorization: type: Bearer credentials_file: /etc/prometheus/forgejo.jeton static_configs: - targets: ["server:3000"]Avant de démarrer, créez aussi regles.yml avec la règle ForgejoInjoignable
donnée dans la section suivante : si ce fichier n'existe pas, Docker crée à sa
place un dossier de ce nom et Prometheus échoue. Puis lancez la pile et
laissez 10 secondes au premier scrape :
docker compose up -ddocker compose exec -T prometheus promtool check config /etc/prometheus/prometheus.ymlpromtool doit répondre SUCCESS: 1 rule files found puis SUCCESS: 1 rules found. La commande suivante interroge l'API de Prometheus pour vérifier
la cible : elle doit afficher health: up, scrapeUrl à
http://server:3000/metrics, et la série up{job="forgejo"} doit valoir 1.
curl -s http://127.0.0.1:9090/api/v1/targetsComment déclencher une alerte quand Forgejo s'arrête ?
Section intitulée « Comment déclencher une alerte quand Forgejo s'arrête ? »Une règle d'alerte compare une expression à un seuil, et passe par trois
états : inactive (condition fausse), pending (vraie depuis moins de la durée
for) puis firing (vraie assez longtemps). La durée for évite qu'un
scrape raté une fois réveille quelqu'un. La règle de base surveille la série
up, que Prometheus fabrique lui-même : 1 si le scrape a réussi, 0 sinon.
L'expression PromQL up{job="forgejo"} == 0 sélectionne la série up du job
forgejo et ne garde que les valeurs égales à 0. Ce bloc est le contenu de
regles.yml :
groups: - name: forgejo rules: - alert: ForgejoInjoignable expr: up{job="forgejo"} == 0 for: 20sAvec un scrape et une évaluation à 5 secondes, un for: 20s laisse
quelques relevés en pending. L'action déclenchante est l'arrêt du service
server, depuis le dossier de la forge ; on relit ensuite l'état des alertes
par l'API de Prometheus, à répéter toutes les quelques secondes :
cd /opt/forgejo-lab && docker compose stop servercurl -s http://127.0.0.1:9090/api/v1/alertsLa réponse JSON ne liste aucune alerte avant l'arrêt, puis porte
ForgejoInjoignable avec son champ state. Voici les relevés obtenus, jusqu'au redémarrage par
docker compose start server :
| Heure | État de ForgejoInjoignable |
|---|---|
| 11:50:48 (avant l'arrêt) | aucune alerte, donc inactive |
| 11:50:55, 11:51:01, 11:51:07 | pending (activeAt à 11:50:51) |
| 11:51:13 et suivants | firing |
après docker compose start server (11:51:38) | disparue, up = 1 |
Pendant l'arrêt, /api/v1/targets donne la cause du scrape raté dans
lastError : lookup server on 127.0.0.11:53: server misbehaving, c'est-à-dire
que le nom server ne se résout plus puisque le conteneur n'existe plus sur le
réseau. Une règle de plus, hors des deux de regles.yml, compare l'âge du
processus à un seuil : time() - process_start_time_seconds{job="forgejo"} < 120 signale « redémarré récemment », et elle est passée en firing à chaque
recréation du conteneur.
L'envoi de la notification (courriel, chat, astreinte) revient à
Alertmanager, présenté dans
Alertmanager :
il n'a pas été testé dans cette leçon, qui s'arrête à l'alerte firing
visible dans Prometheus. Pour écrire des expressions plus fines, voir
PromQL.
Pourquoi une base arrêtée ne fait-elle pas tomber up ?
Section intitulée « Pourquoi une base arrêtée ne fait-elle pas tomber up ? »Quand PostgreSQL s'arrête, l'endpoint /metrics de Forgejo répond encore 200,
donc up reste à 1 et la règle up == 0 ne dit rien : il faut une seconde
règle sur gitea_users == 0. C'est le résultat le plus important de la leçon.
Le schéma suivant montre les deux chaînes. En haut, la panne qui fait tomber la
cible (conteneur arrêté, mot de passe faux) déclenche la règle up == 0, nommée
ForgejoInjoignable. En pointillés, la panne aveugle : la base s'arrête,
l'endpoint répond 200 avec des compteurs à zéro, ForgejoInjoignable reste
muette, et seule la règle gitea_users == 0, nommée ForgejoBaseVide,
alerte.
Le relevé le confirme. Arrêtez PostgreSQL, attendez 5 secondes, puis relisez
les deux compteurs avec le jeton (la variable JETON posée plus haut) :
docker stop forgejo-dbcurl -sk -H "Authorization: Bearer $JETON" https://forge.lab.test/metrics \ | grep -E '^gitea_(users|repositories) 'L'endpoint répond 200 avec gitea_users 0 et gitea_repositories 0 : le
collecteur n'arrive plus à compter, il publie zéro. Le journal de
Forgejo se remplit d'une rafale de [Error SQL Query] SELECT count(*) …. La
règle qui fonctionne est celle-ci, avec for: 20s. Elle s'ajoute dans la liste
rules de regles.yml, à la suite de la première, avec la même indentation :
- alert: ForgejoBaseVide expr: gitea_users == 0 for: 20sModifiez le fichier en place (sans mv, voir les pièges plus bas), puis
demandez à Prometheus de relire ses règles : il ne le fait pas tout
seul.
cd /opt/prometheus-labdocker compose exec -T prometheus promtool check rules /etc/prometheus/regles.ymldocker compose kill -s HUP prometheuspromtool doit annoncer SUCCESS: 2 rules found. Le message Killing /
Killed de Compose est trompeur : le signal HUP demande seulement un
rechargement, le conteneur reste actif. Avec la base arrêtée, la règle passe en
pending (quatre relevés à 5 secondes d'intervalle au rejeu du 2026-10-16,
de 12:10:03 à 12:10:18) puis firing (12:10:23) ; au premier essai, elle
était passée en pending à 11:57:09 et en firing à 11:57:27.
Après docker start forgejo-db, gitea_users revient à 1 et /api/healthz
répond 200 sans qu'on touche à Forgejo : la base revient et le pool de
connexions (les connexions à la base que Forgejo garde ouvertes) se rétablit
seul. Cette règle suppose que l'instance compte au moins un utilisateur ; sur
une forge vide, elle serait toujours en alerte.
Que dit /api/healthz, et peut-on le scraper ?
Section intitulée « Que dit /api/healthz, et peut-on le scraper ? »/api/healthz est un contrôle de santé public, sans jeton, qui ne vérifie que
la base et le cache : il répond 200 {"status":"pass", …} ou 424 si un contrôle
échoue. Il ne dit rien de Git, de SSH, du runner ni du disque. Chaque appel
écrit une ligne PING DATABASE pgx et une ligne du routeur dans le journal.
On peut être tenté de le donner à Prometheus comme cible : l'essai a échoué.
Prometheus 3 marque la cible down en permanence, même en bonne santé, avec
l'erreur received unsupported Content-Type "application/json" and no fallback_scrape_protocol specified. Ce point d'accès est fait pour un
contrôleur HTTP (un équilibreur, un script, un blackbox_exporter, l'exporter
de Prometheus qui sonde des URL), pas pour un scrape. Prometheus propose bien un
réglage fallback_scrape_protocol, mais la documentation le décrit pour un
Content-Type vide, illisible ou invalide ; le corps de /api/healthz est du
JSON et non le format d'exposition de Prometheus. Ce contournement et le
blackbox_exporter n'ont pas été essayés ici, et le premier ne donnerait
sans doute pas de métriques exploitables. Utilisez /api/healthz à la main ou
dans un script pour confirmer une réparation, et laissez /metrics à
Prometheus.
Comment diagnostiquer une panne par le journal ?
Section intitulée « Comment diagnostiquer une panne par le journal ? »La méthode tient en cinq temps : le symptôme observé, le journal qui le
confirme, la cause, la réparation, la vérification. On ne devine pas, on ne
redémarre pas au hasard : on lit d'abord ce que Forgejo dit de lui-même
(docker logs forgejo), puis ce que PostgreSQL dit de son côté quand la base
est en cause (docker logs forgejo-db). Deux pannes réelles, provoquées sur le
lab, servent d'exemples.
Que faire quand PostgreSQL est arrêté ?
Section intitulée « Que faire quand PostgreSQL est arrêté ? »Symptôme : /api/healthz répond 424 et les pages qui lisent la base répondent
500, alors que la page d'accueil répond encore 200. Mesuré 5 secondes après
docker stop forgejo-db :
| URL | Code |
|---|---|
/api/healthz | 424, database:ping en fail |
/user/login, /explore/repos, /api/v1/repos/search, /api/v1/users/search | 500 |
/, /api/v1/version | 200 (pas d'accès à la base) |
/metrics avec jeton | 200, gitea_users 0 |
Le journal nomme la cause : checkDatabase() [E] database ping failed with error: failed to connect to user=forgejo database=forgejo: hostname resolving error: lookup db on 127.0.0.11:53: server misbehaving. Le mot à retenir est
lookup db : le nom db ne se résout plus, donc le conteneur forgejo-db
n'existe plus sur le réseau. La réparation est de le redémarrer
(docker start forgejo-db), et la vérification est /api/healthz en 200 et
gitea_users revenu à 1. L'alerte à surveiller est ForgejoBaseVide, pas
ForgejoInjoignable.
Que faire quand Forgejo n'arrive pas à se connecter à la base ?
Section intitulée « Que faire quand Forgejo n'arrive pas à se connecter à la base ? »Symptôme : le conteneur est Up mais Caddy répond 502 partout, y compris sur
/api/healthz. La panne a été provoquée en changeant le mot de passe
FORGEJO__database__PASSWD dans le compose, puis docker compose up -d server.
Pour provoquer la panne, remplacez la valeur de FORGEJO__database__PASSWD par
une chaîne quelconque. Forgejo tente alors 10 fois de se connecter, puis le
processus sort, et restart: always le relance. Le compteur de redémarrages le
montre (1 ou 2 en moins d'une minute) :
docker inspect forgejo --format '{{.RestartCount}}'Le journal de Forgejo donne la cause :
InitDBEngine() [E] ORM engine initialization attempt #3/10 failed. Error: failed to connect to user=forgejo database=forgejo: 172.30.0.2:5432 (db): failed SASL auth: FATAL: password authentication failed for user "forgejo" (SQLSTATE 28P01). Le journal de PostgreSQL (docker logs forgejo-db) la confirme de
l'autre côté : FATAL: password authentication failed for user "forgejo", suivi de
Connection matched file ".../pg_hba.conf" line 128: "host all all all scram-sha-256". Le code SQLSTATE 28P01 (le code d'erreur normalisé que
PostgreSQL renvoie pour un mot de passe invalide) présent des deux côtés est
la signature d'un mauvais mot de passe.
La réparation est de remettre ${POSTGRES_PASSWORD} dans le compose, puis
docker compose up -d server. Vérification : /api/healthz répond 200 avec
"pass" en moins de 15 secondes. Contrairement à la panne précédente, la
cible tombe ici : l'alerte ForgejoInjoignable passe en pending puis
firing.
Quels pièges attendent la supervision de Forgejo ?
Section intitulée « Quels pièges attendent la supervision de Forgejo ? »Trois pièges de la supervision méritent une explication : un fichier monté seul qui reste figé, un contrôle de syntaxe qui échoue hors de la pile, et un jeton qui s'affiche. Le tableau de dépannage plus bas les reprend avec leur correction, ainsi que ceux déjà vus plus haut (le bruit des scrapes dans le journal, la clé dépréciée).
Un fichier monté seul dans le conteneur (./regles.yml:/etc/prometheus/regles.yml)
est lié à son inode, l'identifiant du fichier sur le disque. Si vous le
remplacez sur l'hôte avec mv, l'inode change : le conteneur garde l'ancienne
version, et un kill -HUP ne suffit pas. Il faut docker compose restart prometheus, ou éditer le fichier en place.
Pour contrôler la syntaxe, promtool check config lancé dans un conteneur
éphémère (docker run --rm --entrypoint promtool -v ...) échoue si les
chemins listés dans rule_files ne sont pas montés : la sortie est
FAILED: "/etc/prometheus/regles.yml" does not point to an existing file.
Montez le fichier des règles dans ce conteneur aussi, ou lancez promtool avec
docker compose exec -T prometheus, comme plus haut.
Enfin, un jeton affiché par un sed ou un grep -A finit dans vos
captures : masquez-le avant toute capture d'écran ou copie de
session.
Que faire quand la supervision ne se passe pas comme prévu ?
Section intitulée « Que faire quand la supervision ne se passe pas comme prévu ? »Chaque échec de cette leçon se lit dans un code HTTP, une ligne de journal ou l'état d'une alerte. Le tableau relie le symptôme à sa cause et à la correction qui a été appliquée sur le lab.
| Symptôme | Cause | Correction |
|---|---|---|
La cible /api/healthz est down en permanence | Prometheus 3 refuse le Content-Type application/json (sans fallback_scrape_protocol) | ne pas la scraper ; l'utiliser à la main ou dans un script |
Base arrêtée, aucune alerte up == 0 | /metrics répond 200, up reste à 1 | règle gitea_users == 0 |
/api/healthz répond 424 et les pages 500 | PostgreSQL arrêté (lookup db dans le journal) | docker start forgejo-db |
502 partout, conteneur Up, RestartCount qui monte | mot de passe de base faux (SQLSTATE 28P01) | remettre ${POSTGRES_PASSWORD}, docker compose up -d server |
[E] Deprecated config option [log] ENABLE_ACCESS_LOG | l'option est dépréciée et sa clé reste dans app.ini | LOGGER_ACCESS_MODE: file et suppression de la clé avec sed |
docker logs noyé de lignes GET /metrics | scrape toutes les 5 s, journal du routeur à info | grep -v "GET /metrics" |
| Règle modifiée sur l'hôte, ancienne version active | fichier monté seul, inode changé par mv | docker compose restart prometheus |
promtool check config en conteneur éphémère : FAILED: ... does not point to an existing file | le fichier des règles n'est pas monté dans ce conteneur | le monter aussi, ou docker compose exec -T prometheus promtool ... |
forgejo manager logging add : option inconnue | l'option --name n'existe pas | utiliser --writer |
Pas de forgejo.log dans /data/gitea/log | le fichier s'appelle gitea.log en 15.0.10 | lire gitea.log |
Le diagnostic commence toujours par la même question : la panne fait-elle
tomber la cible (up == 0) ou seulement les compteurs (gitea_users == 0) ? La
réponse oriente vers le bon journal, celui de Forgejo ou celui de PostgreSQL.
Comment défaire cette configuration ?
Section intitulée « Comment défaire cette configuration ? »On détruit la pile Prometheus avec son volume, on retire du compose.yaml et
du .env ce que la leçon y a ajouté, puis on recrée Forgejo. Les variables
metrics et log retirées du compose restent dans app.ini (voir le piège de
persistance plus haut) : il faut aussi les retirer à la main de ce fichier.
cd /opt/prometheus-lab && docker compose down -vcd /opt/forgejo-labsed -i '/FORGEJO__metrics__/d;/FORGEJO__log__/d' compose.yamlsed -i '/^JETON_METRIQUES/d' .envdocker exec forgejo sed -i -e '/^MODE = console,file/d' \ -e '/^LOGGER_ACCESS_MODE/d' -e '/^\[metrics\]/,/^$/d' /data/gitea/conf/app.inidocker compose up -d --force-recreate serverContrôlez le résultat avec curl -sk https://forge.lab.test/api/healthz,
qui doit répondre 200, et avec docker exec forgejo grep -c '^\[metrics\]' /data/gitea/conf/app.ini, qui doit afficher 0. Attention : le sed sur
compose.yaml supprime toutes les lignes FORGEJO__log__* et
FORGEJO__metrics__*, y compris celles que vous auriez ajoutées pour un autre
usage ; sur une forge qui n'est pas un lab, retirez-les une à une.
Supprimez ensuite le dossier avec sudo rm -r /opt/prometheus-lab (il ne
contient plus que des fichiers de configuration et le jeton). Les fichiers
gitea.log, access.log et debug-temp.log restent dans le volume
/data/gitea/log. Sur un lab jetable, ce geste ramène la pile à l'état de la
leçon d'installation.
À retenir
Section intitulée « À retenir »- Les journaux de Forgejo sortent par défaut sur la console du conteneur (
docker logs forgejo), niveau info, sans rotation du pilotejson-fileconfigurée. MODE: console,fileécritgitea.log(le nom restegitea.logen 15.0.10) ; le journal d'accès se règle parLOGGER_ACCESS_MODE: file, pas parENABLE_ACCESS_LOG, déprécié. Les variablesFORGEJO__*retirées du compose restent dansapp.ini: il faut supprimer la clé à la main.forgejo manager logging add file --writer …ajoute un niveau debug à chaud,removele retire, sans redémarrage./metricsse protège par un jeton (401 sans, 200 avec) ; ses familles sontgitea_*plus le Go standard, sans file, latence ni runner.- Prometheus scrape
server:3000aveccredentials_file; une règle passe deinactiveàpendingpuisfiring, lisible dans/api/v1/alerts. - Base arrêtée :
/metricsrépond 200 etupreste à 1. Alerter aussi surgitea_users == 0(ForgejoBaseVide), en plus deup == 0(ForgejoInjoignable). /api/healthz(base et cache seulement, 424 en panne) n'est pas scrapable tel quel par Prometheus 3 : il sert à confirmer une réparation, à la main ou dans un script.- Un diagnostic suit symptôme, journal, cause, réparation, vérification :
lookup dbpour une base arrêtée,SQLSTATE 28P01des deux côtés pour un mauvais mot de passe.
Contrôle de connaissances
Section intitulée « Contrôle de connaissances »Six questions tirées sur huit : les journaux de Forgejo, l'endpoint /metrics et son jeton, les règles d'alerte Prometheus et le diagnostic de deux pannes par le journal.
Contrôle de connaissances
Validez vos connaissances avec ce quiz interactif
Informations
- Le chronomètre démarre au clic sur Démarrer
- Questions à choix multiples, vrai/faux et réponses courtes
- Vous pouvez naviguer entre les questions
- Les résultats détaillés sont affichés à la fin
Lance le quiz et démarre le chronomètre
Vérification
(0/0)Score par domaine
Un domaine regroupe plusieurs guides et reçoit plusieurs questions : son score est plus fiable qu'un score par thème, qui porte souvent sur une seule question.
Bilan
Points forts
Aucun sujet réussi à 80 % sur au moins deux questions pour l’instant.
Points faibles
Aucun sujet sous le seuil de réussite.
À faire ensuite
Des indices pour retenter votre chance ?
Continuer le cours : Migrer une organisation : import, miroirs et bascule
Nouveau quiz complet avec des questions aléatoires
Retravailler uniquement les questions ratées
Retour à la liste des certifications