Aller au contenu
English
Compte : non connecté, synchronisation possible Mon apprentissage
Selectionner le thème
English

Forgejo : monter de version avec ses critères de validation

Par mis à jour le

Améliorer cette page

Pour monter Forgejo de version, on lit les notes de version, on vide les files de tâches, on sauvegarde à froid, on répète la montée sur une copie restaurée de la production, puis on change l'image épinglée par son digest et on compare une liste de critères avant et après. Le retour arrière ne passe pas par l'ancienne image : la base a été migrée dans un seul sens, et c'est la sauvegarde d'avant montée qu'on restaure. La leçon s'adresse à l'administrateur dont la forge tourne sur Docker Compose et qui veut savoir quand il peut monter, comment, et à quoi reconnaître que tout va bien.

Vous repartez avec quatre preuves : une montée directe de la LTS 15.0.10 à la stable 17.0.0 sur une copie (la LTS est la branche à support long, la stable la plus récente), un tableau de critères relevés avant et après, un échec de signature diagnostiqué puis corrigé, et un retour arrière par la sauvegarde. Un runner de CI est aussi vérifié sur la 17. Les commandes ont été exécutées sur la pile de la leçon Installer Forgejo LTS, avec PostgreSQL 17.11. La montée de la production elle-même n'a pas été jouée : c'est la répétition sur copie qui l'a été, et c'est tout le propos.

  • Choisir la version cible d'après le cycle de publication, sans passer par chaque branche.
  • Préparer la montée : notes de version, forgejo manager flush-queues, sauvegarde à froid.
  • Répéter la montée sur une copie restaurée de la production, et lire le journal de migration.
  • Valider l'instance par une liste de critères relevés avant et après, runner de CI compris.
  • Diagnostiquer l'échec de signature qui suit une restauration ou une montée.
  • Revenir en arrière par la restauration, et comprendre pourquoi l'ancienne image refuse de démarrer.

Il vous faut la forge des leçons précédentes : Forgejo 15 LTS sur Docker Compose dans /opt/forgejo-lab, avec PostgreSQL et le compte fjadmin (installation). La sauvegarde à froid et la restauration sur une pile vierge sont celles de Sauvegarder et restaurer Forgejo : cette leçon les utilise sans les redire, et vous y trouverez le mécanisme des verrous gpg. Le diagnostic forgejo doctor check est expliqué dans Maintenance courante, la signature des commits dans Sécuriser l'instance.

Le runner de CI est celui de Exploiter le runner. Son enregistrement et un job qui lit un secret ont été rejoués sur la copie montée en Forgejo 17.0.0 : voir la section « Un runner fonctionne-t-il encore après la montée ? ».

Vous devez savoir lire un code de sortie et du JSON, et lancer docker compose en root sur la VM. Un numéro de version se lit MAJEUR.MINEUR.CORRECTIF, selon le versionnage sémantique : dans 15.0.10, 15 est la branche majeure et 10 le dixième correctif.

Quelle version viser et faut-il passer par chaque branche ?

Section intitulée « Quelle version viser et faut-il passer par chaque branche ? »

La documentation de Forgejo 17 recommande d'aller directement à la dernière version : la procédure de montée prend en charge les migrations intermédiaires, et le saut de 15.0.10 à 17.0.0 a été joué sans passer par la 16. Au 2026-10-16, trois lignes sont disponibles : la LTS 15.0.10, la 16.0.6 et la stable 17.0.0, publiée le 2026-10-15. Il n'existe pas de 15.0.11 : la dernière version de la LTS est la 15.0.10.

Le cycle explique le choix. D'après le calendrier des versions, une version stable est maintenue environ trois mois après sa parution, une version LTS environ quinze mois (le calendrier donne des dates, pas une règle écrite). Pour la 15, le support court jusqu'au 2027-07-15 ; la 17.0.0 s'arrête le 2027-01-28. Rester en LTS demande donc moins de montées ; viser la stable donne les nouveautés plus tôt, au prix d'une montée tous les quelques mois.

Le tableau donne aussi le digest de chaque image : c'est son empreinte, et l'épingler garantit que la montée installe exactement le contenu testé, même si une étiquette est déplacée. Un tag seul ne le garantit pas.

VersionStatut au 2026-10-16Digest de l'image
15.0.10dernière de la LTS 15sha256:7b2f61163ff1d19f2aaf62d37ae4e805e822c2f86d6628b2bd468470929beacb
16.0.6dernière de la 16, traversée en saut directsha256:e2c34a699543ca8a00217ee9ab2bea5feedc98bd6d0ea95ec287d3b7ae1355c6
17.0.0stablesha256:06d38310de496a10186d952bdad5ca764c153c8023ede8dfa0944c79a1dc5412

Comment se déroule une montée de version sans mauvaise surprise ?

Section intitulée « Comment se déroule une montée de version sans mauvaise surprise ? »

Une montée sûre suit toujours le même ordre : lire, vider, sauvegarder, répéter sur une copie, changer l'image, valider, puis seulement monter la production ou revenir en arrière. Le schéma suivant montre ce chemin. Suivez la flèche épaisse du haut vers le bas : le changement d'image qui précède la décision se joue d'abord sur la copie. Le losange est la décision : critères satisfaits, on refait le geste sur la production ; sinon, on restaure. Les flèches pointillées montrent le piège de l'ancienne image, détaillé plus bas.

Chemin d'une montée de version Forgejo, de haut en bas : lire les notes de version des branches traversées, forgejo manager flush-queues puis sauvegarde à froid, répétition sur une copie restaurée de la production, changement de l'image épinglée par digest avec docker compose up -d server, puis décision : tous les critères de validation sont-ils satisfaits ? Si oui, même geste sur la production après une sauvegarde fraîche. Si non, retour arrière en restaurant la sauvegarde d'avant montée. Une branche pointillée montre que remettre l'ancienne image seule fait refuser le démarrage, car la base est déjà migrée, ce qui renvoie aussi à la restauration.ouinonimage ancienne seuleLire les notes de versiondes branches traverséesforgejo manager flush-queuespuis sauvegarde à froidRépétition sur une copie restauréede la productionChanger l'image épinglée par digestdocker compose up -d serverCritères de validationtous satisfaits ?Même geste sur la productionsauvegarde fraîche juste avantRetour arrière :restaurer la sauvegarde d'avant montéeRefus de démarrer :base déjà migrée
Source · SVG
Échap pour fermer, + et − pour zoomer, défilement pour se déplacer. 100 %

La copie est le cœur de la méthode. Elle coûte une restauration, que vous savez déjà faire, et elle vous apprend avant la production ce que la montée change : durée d'arrêt, migrations jouées, comportement des fonctions que vous utilisez. Une montée jouée pour la première fois sur la production est un pari ; sur une copie, c'est une mesure.

Avant la montée, on fait trois choses : lire les notes de version des branches traversées, vider les files avec forgejo manager flush-queues, et sauvegarder à froid. La documentation de Forgejo 17 présente la sauvegarde comme une exigence pour monter vers une nouvelle stable, et c'est la seule voie de retour, comme le montre la section sur le retour arrière.

Les notes de version se lisent d'abord, parce qu'elles annoncent les changements qui touchent votre configuration. Voici les points relevés pour 15 vers 17 dans les notes de version 16.0.0 et 17.0.0 ; relisez-les avant de monter votre instance, car le lab n'en a pas éprouvé tous les effets.

BranchePoint relevéCe qu'il faut vérifier chez vous
16.0.0le réglage REVERSE_PROXY_TRUSTED_PROXIES par défaut est retiré de la configuration Dockervotre proxy (Caddy) : les adresses clientes lues par Forgejo. Non éprouvé : la copie du lab n'avait pas de proxy
16.0.0contrôles renforcés des migrations de dépôts (import, miroirs), réglages [migrations] : un miroir HTTP dont la source répond par une redirection peut cesser de fonctionnervos miroirs et imports de dépôts (rien à voir avec la migration de la base de données)
17.0.0durées de la configuration analysées strictementtoute durée de votre app.ini ou de vos variables FORGEJO__… doit être valide
17.0.0fichier de journal par défaut forgejo.log, avec un lien symbolique gitea.log pour la compatibilitétout outil qui lit le journal par son ancien nom
17.0.0liens absolus (commençant par /) du Markdown résolus depuis la racine du dépôt, plus depuis le dossier du fichierl'aspect de vos pages d'accueil de dépôt et de vos documents imbriqués

Ensuite, forgejo manager flush-queues vide les files de tâches internes. La raison est que ces files contiennent des données sérialisées, et que leur compatibilité d'une version à l'autre n'est pas garantie : on les laisse donc se vider avant de changer de binaire. La commande rend Flushed :

Fenêtre de terminal
docker exec -u git forgejo-upgrade-server-1 forgejo manager flush-queues
Flushed

Enfin, relevez un état de référence du diagnostic, car doctor rend un code de sortie 0 même quand il signale une erreur (Maintenance courante). Sur la copie en 15.0.10, le contrôle gc-lfs affichait déjà ERROR avant la montée :

Fenêtre de terminal
docker exec -u git forgejo-upgrade-server-1 forgejo doctor check --run gc-lfs
[1] Garbage collect LFS
ERROR
All done (checks: 1).

Cette erreur existe donc avant la montée : on ne la met pas sur le compte de la 17, et c'est pourquoi on compare des relevés au lieu de chercher zéro erreur.

Comment répéter la montée sur une copie de la production ?

Section intitulée « Comment répéter la montée sur une copie de la production ? »

On répète sur une pile jetable restaurée depuis la sauvegarde de la production : même .env, mêmes images, autre nom de projet Compose, autre port et aucun proxy. La sauvegarde et la restauration sont celles de la leçon précédente ; seule la forme de la copie est propre à cette leçon.

La copie vit dans /opt/forgejo-upgrade. On y reprend le .env de la production, qui porte les mêmes secrets : protégez-le comme l'original. On change l'adresse publique pour le port local, et la liste des fichiers Compose qui s'ajoutent à compose.yaml :

Fenêtre de terminal
sed -i 's|^ROOT_URL=.*|ROOT_URL=http://127.0.0.1:3200/|; s|^COMPOSE_FILE=.*|COMPOSE_FILE=compose.yaml:webhooks.yaml:signature.yaml|' /opt/forgejo-upgrade/.env

Le compose.yaml de la copie reprend celui de l'installation, avec trois écarts : name: forgejo-upgrade pour que volumes et réseau ne se mélangent pas avec ceux de la production, 127.0.0.1:3200:3000 comme seul port publié, et l'image de départ épinglée sur la 15.0.10 :

image: codeberg.org/forgejo/forgejo:15.0.10@sha256:7b2f61163ff1d19f2aaf62d37ae4e805e822c2f86d6628b2bd468470929beacb

La restauration reprend les gestes de la leçon précédente : base d'abord, conteneur créé sans démarrer, extraction du volume avec --xattrs --selinux --numeric-owner, puis démarrage. $O est le dossier de la sauvegarde de la production, $V le volume de la copie et $B son adresse locale.

Fenêtre de terminal
O=/root/l11/avant
V=/var/lib/docker/volumes/forgejo-upgrade_forgejo-data/_data
B=http://127.0.0.1:3200
cd /opt/forgejo-upgrade
docker compose up -d --no-deps --wait db
DB=$(docker compose ps -q db)
docker cp $O/forgejo.dump $DB:/tmp/forgejo.dump
docker exec $DB pg_restore -U forgejo -d forgejo --no-owner --exit-on-error /tmp/forgejo.dump
docker exec $DB rm /tmp/forgejo.dump
docker compose create server
tar --xattrs --selinux --numeric-owner -C $V -xpf $O/data.tar
docker compose up -d server
curl -sf http://127.0.0.1:3200/api/forgejo/v1/version

La copie répondait en 6,8 s et annonçait la version de départ :

{"version":"15.0.10+gitea-1.22.0"}

Avant de monter, on garnit la copie de données témoins que la montée pourrait abîmer : un dépôt avec deux commits dont un workflow, un utilisateur lecteur-l11, une issue, un collaborateur en écriture, un webhook vers un récepteur HTTP minimal local, un secret de dépôt L11_SECRET et un commit signé par l'instance. Un webhook ne part que vers un hôte autorisé : la copie l'autorise dans son .env, comme l'explique Sécuriser l'instance.

Fenêtre de terminal
R=http://127.0.0.1:3200/api/v1/repos/fjadmin/temoin-l11
api -X POST $R/issues -d '{"title":"Issue temoin L11","body":"corps temoin L11"}'
api -X PUT $R/collaborators/lecteur-l11 -d '{"permission":"write"}'
api -X PUT $R/actions/secrets/L11_SECRET -d '{"data":"valeur-temoin-l11"}'

Ici api est une fonction curl qui ajoute l'en-tête Authorization: token … lu dans un fichier lisible de vous seul : ne l'affichez jamais. Relevez ensuite les critères de la section dédiée sur cette copie encore en 15.0.10 : c'est le relevé de référence.

On sauvegarde la copie à froid, on remplace l'image par la 17.0.0 épinglée, puis docker compose up -d server recrée le conteneur : la base est migrée au démarrage, en 2,05 s d'indisponibilité sur ce volume de 400 Ko. Cette durée est celle d'une petite base de lab et ne se généralise pas : la vôtre dépend de sa taille et des migrations à jouer.

La sauvegarde d'avant montée est la voie de la leçon précédente, sur la copie : pg_dump -Fc et tar, service arrêté. Elle est rangée dans $A, distinct de la sauvegarde de la production. Elle a pris 1,46 s, arrêt compris, et produit deux fichiers de 411 749 et 634 880 octets. Gardez-les : ils sont votre retour arrière.

Fenêtre de terminal
A=/root/l11/avant-montee
docker compose stop server
docker exec $DB pg_dump -U forgejo -d forgejo -Fc -f /tmp/forgejo.dump
docker cp $DB:/tmp/forgejo.dump $A/forgejo.dump
tar --xattrs --selinux --numeric-owner -C $V -cf $A/data.tar .

Puis le changement d'image : la ligne image: de compose.yaml passe à la 17.0.0, toujours avec son digest, et le service est recréé.

Fenêtre de terminal
NEW=codeberg.org/forgejo/forgejo:17.0.0@sha256:06d38310de496a10186d952bdad5ca764c153c8023ede8dfa0944c79a1dc5412
sed -i "s|image: codeberg.org/forgejo/forgejo:.*|image: $NEW|" compose.yaml
docker compose up -d server
image: codeberg.org/forgejo/forgejo:17.0.0@sha256:06d38310de496a10186d952bdad5ca764c153c8023ede8dfa0944c79a1dc5412
indisponibilite_depuis_up_s=2.04587

Le journal du conteneur est la preuve de la migration. Il annonce la version (Forgejo version: 17.0.0+gitea-1.22.0) et le Git embarqué qui change avec l'image : 2.52.0 dans la 15.0.10, 2.54.0 dans la 17.0.0. Il liste ensuite chaque migration jouée, préfixée Migration[…], avec des noms qui se rattachent aux branches traversées : v16a_ à v16e_ pour la 16, v17a_ pour la 17.

Migrate() [I] Migration[v16a_add_authorized_integration]: add authorized_integration tables
Migrate() [I] Migration[v16e_add-granular-watch]: Add granular watch settings to repos.
Migrate() [I] Migration[v17a_add_package_version_total_size]: Add TotalSize to PackageVersion

Le saut direct a donc joué les migrations de la 16 au passage, sans intervention. Le journal comptait 17 migrations, aucune erreur et aucune mention de dépréciation ; la seule ligne qui contient « warn » est le nom de la migration v16d_action_run_warnings, pas un avertissement. Un grep sur deprecat|error|fatal est un bon réflexe après chaque montée.

Quels critères prouvent que la montée a réussi ?

Section intitulée « Quels critères prouvent que la montée a réussi ? »

La montée réussit quand les mêmes critères, relevés avant et après, ne diffèrent que par la version et par des écarts qu'on sait expliquer : un seul relevé « après » ne prouve rien, parce qu'on ignore ce qui marchait déjà. Le tableau compare le relevé sur la 15.0.10 et celui sur la 17.0.0 de la copie.

CritèreVérificationEn 15.0.10En 17.0.0
Versioncurl -s $B/api/forgejo/v1/version15.0.10+gitea-1.22.017.0.0+gitea-1.22.0
Santécurl -s $B/api/healthzpasspass
Diagnosticforgejo doctor check --allcode 0, une ligne ERROR (gc-lfs)code 0, une ligne ERROR, la même
ConnexionGET /api/v1/user en lecteur-l11is_admin= Falseis_admin= False
Clonegit clone puis git log --onelinehistorique completmême historique, plus les nouveaux commits
Pushcommit poussé par lecteur-l11push rc=0push rc=0
IssueGET …/issues/1Issue temoin L11identique
CollaborateurGET …/collaborators['lecteur-l11']identique
WebhookGET …/hooks, récepteur localid 30, 2 livraisons reçuesid 30, une 3e livraison reçue
SecretGET …/actions/secrets (noms)['L11_SECRET']identique
Signaturecréation de fichier par l'APIverified= Trueéchec, puis True après correction

La colonne « diagnostic » montre l'intérêt de l'état de référence : l'ERROR est la même dans les deux relevés, donc elle n'est pas une régression. La dernière ligne est le piège de la section suivante. Les données (issue, collaborateur, secret, webhook) survivent telles quelles : la migration ne les touche pas.

Un runner fonctionne-t-il encore après la montée ?

Section intitulée « Un runner fonctionne-t-il encore après la montée ? »

Oui : un runner 13.2.0 (celui de la leçon sur le runner), enregistré hors ligne sur la copie montée en 17.0.0, a exécuté un job qui lit un secret. Le runner est le processus qui exécute les workflows de CI ; une montée de la forge peut le casser sans que l'interface le montre, d'où ce critère à part.

L'enregistrement s'est fait hors ligne, avec forgejo-cli actions generate-secret, puis forgejo-cli actions register --secret-stdin --name l11-runner --labels host, exécutées dans le conteneur forgejo-upgrade-server-1. Le démon, lancé avec une connexion url: http://127.0.0.1:3200/ dans son config.yml, a affiché runner: runner, with version: v13.2.0, with labels: [host], ephemeral: false, declared successfully. L'API d'administration (GET /api/v1/admin/actions/runners) le listait en idle, alors que le runner hérité de la sauvegarde restait offline.

Le workflow témoin .forgejo/workflows/ci.yaml (runs-on: host, il affiche seulement ${#L11_SECRET}) a été exécuté deux fois : sur un commit déjà poussé, puis sur un nouveau commit créé par l'API. Les deux jobs sont en success, le journal contient secret_len=17 (la longueur de la valeur du secret L11_SECRET) et Job succeeded. Le secret est donc lu par le job, ce que sa seule présence dans la liste ne prouvait pas.

Le nouveau commit a d'abord échoué avec waiting for lock, le piège de la section suivante : la sauvegarde restaurée contenait des verrous gpg, qu'on retire avant de pousser. Le journal du runner signale aussi Could not start the cache server quand deux runners partagent le même ~/.cache : sans effet sur le job, et propre à ce lab où le runner de la production tournait sur la même VM.

Ce que cette épreuve ne couvre pas : l'exécuteur host (le job tourne directement sur la machine) est le seul éprouvé. Le label docker (job en conteneur), le mode éphémère et l'exécution du démon comme service systemd n'ont pas été rejoués sur la 17 : ajoutez-les à vos critères si vous les utilisez.

Pourquoi la signature échoue-t-elle après la montée ?

Section intitulée « Pourquoi la signature échoue-t-elle après la montée ? »

Parce que des verrous gpg périmés traînent dans le volume : le premier commit signé par l'instance attend un verrou que plus aucun processus ne tient, et l'API répond par une erreur de signature. C'est le piège de la leçon Sauvegarder et restaurer Forgejo, et le symptôme est identique. La signature fonctionnait en 15.0.10 sur la copie et ne fonctionnait plus après la montée ; le mécanisme est présumé le même que dans cette leçon (le démon gpg tué à l'arrêt du conteneur sans retirer ses verrous), sans qu'il ait été isolé davantage.

Après la montée, la création d'un fichier par l'API échouait avec ceci, et les commits précédents passaient à verified= False :

error: gpg failed to sign the data:
gpg: Note: database_open 134217901 waiting for lock (held by 170) ...
gpg: keydb_search failed: Operation timed out
gpg: signing failed: Operation timed out

Le correctif est celui de la leçon précédente : retirer les verrous dans le dossier .gnupg du volume de données, soit pubring.db.lock et le fichier .#lk…. Un nouvel appel rend alors un commit vérifié, et le commit signé précédent redevient vérifié :

Fenêtre de terminal
find $V/gitea/home/.gnupg \( -name '*.lock' -o -name '.#lk*' \) -delete
d4eaf06 commit signe 17 apres retrait verrous verified= True
5fda424 commit signe apres montee verified= True

Mettez cette vérification dans vos critères : une forge qui répond, clone et pousse peut très bien ne plus signer. Le dossier à nettoyer est celui du volume de données de la copie, ici le chemin de $V.

Pourquoi l'ancienne image refuse-t-elle de démarrer ?

Section intitulée « Pourquoi l'ancienne image refuse-t-elle de démarrer ? »

Parce que la base a été migrée vers un schéma que l'ancienne version ne connaît pas : Forgejo compare les migrations de la base à celles qu'il connaît, et sort plutôt que de risquer vos données. Un retour arrière par simple changement d'image, de la 17.0.0 vers la 15.0.10, a été essayé sur la copie : le conteneur s'arrête dans les secondes qui suivent et la forge ne répond plus (http healthz: 000).

Fenêtre de terminal
OLD=codeberg.org/forgejo/forgejo:15.0.10@sha256:7b2f61163ff1d19f2aaf62d37ae4e805e822c2f86d6628b2bd468470929beacb
sed -i "s|image: codeberg.org/forgejo/forgejo:.*|image: $OLD|" compose.yaml
docker compose up -d server
docker logs forgejo-upgrade-server-1

Le journal donne la raison, en toutes lettres :

Migrate() [F] Your Forgejo database has 17 migration(s) (v16c_action_run_priority, …
Forgejo will exit to keep your database safe and unchanged. Please use the correct Forgejo release, do not change the migration version manually (incorrect manual operation may cause data loss).

Ce refus est une protection que la documentation décrit, pas une panne. Il dit aussi quoi ne pas faire : ne retouchez jamais la table des versions de migration à la main pour contourner le message, car le schéma réel ne correspondrait plus à ce que la 15 attend. Le seul retour fiable est la restauration.

Comment revenir en arrière avec la sauvegarde d'avant montée ?

Section intitulée « Comment revenir en arrière avec la sauvegarde d'avant montée ? »

Le retour arrière restaure la sauvegarde faite juste avant la montée : base puis volume, avec l'image d'avant remise dans compose.yaml, en 6,6 s sur la copie. Les données écrites après la sauvegarde sont perdues : c'est le prix d'un retour arrière, d'où l'intérêt de monter à un moment calme.

On repart d'une pile vide (docker compose down -v), on remet l'image 15.0.10 épinglée dans compose.yaml, puis on rejoue la restauration de la leçon précédente avec le dump et le tar d'avant montée :

Fenêtre de terminal
docker compose down -v
docker compose up -d --no-deps --wait db
DB=$(docker compose ps -q db)
docker cp $A/forgejo.dump $DB:/tmp/forgejo.dump
docker exec $DB pg_restore -U forgejo -d forgejo --no-owner --exit-on-error /tmp/forgejo.dump
docker compose create server
tar --xattrs --selinux --numeric-owner -C $V -xpf $A/data.tar
docker compose up -d server
restauration_s=6.59729
{"version":"15.0.10+gitea-1.22.0"}

L'état d'avant montée est bien revenu : le commit poussé en 17 a disparu de l'historique, qui s'arrête de nouveau à 5fda424. Un détail piège : les verrous gpg, restaurés avec l'archive (le lab en a compté deux), ont fait repasser les commits à verified= False. Retirez-les comme dans la section précédente avant de conclure que le retour arrière a cassé la signature.

Une montée de correctif dans la LTS, par exemple de 15.0.10 vers une future 15.0.11, est le même geste : sauvegarde, changement du tag et du digest de l'image, docker compose up -d server, puis les mêmes critères. Elle n'a pas été rejouée, faute de version supérieure à la 15.0.10 au 2026-10-16.

Ne la prenez pas pour autant à la légère. La documentation de Forgejo recommande la sauvegarde pour une version corrective comme « une bonne précaution », et seule la lecture du journal dit si des migrations de base ont été jouées ; le retour arrière reste la restauration. Quand elle paraîtra, rejouez le relevé de critères sur une copie avant la production, puis mettez à jour le digest : un digest ne reçoit aucun correctif tout seul.

Que faire quand la montée ne se passe pas comme prévu ?

Section intitulée « Que faire quand la montée ne se passe pas comme prévu ? »

On lit d'abord le journal du conteneur, puis on compare avec le relevé de référence : la plupart des échecs sont soit un refus de migration, soit un verrou gpg. Le tableau reprend les cas rencontrés en lab et un faux positif.

SymptômeCauseSolution
Le conteneur sort, Migrate() [F] Your Forgejo database has N migration(s)image plus ancienne que la base migréeremettre l'image récente, ou restaurer la sauvegarde d'avant montée
Création de fichier refusée, waiting for lock (held by N)verrous gpg périmés dans le volumesupprimer pubring.db.lock et .#lk* du dossier .gnupg
Commits en verified= False après la restaurationmême verrou : la clé publique ne s'exporte pasmême correction
doctor check --all affiche ERROR après la montéepeut exister avant : ici gc-lfs en 15.0.10comparer au relevé de référence avant d'accuser la montée
15.0.11 introuvablecette version n'existe pas au 2026-10-16rester sur 15.0.10, dernière de la LTS

On supprime la copie entière, avec ses volumes, l'image de la 17 et les fichiers qui contiennent des secrets : la production n'a pas bougé. La répétition n'a modifié que la pile forgejo-upgrade.

Fenêtre de terminal
cd /opt/forgejo-upgrade && docker compose down -v
docker rmi codeberg.org/forgejo/forgejo:17.0.0

Arrêtez aussi le récepteur de webhook local. Supprimez ensuite à la main les dossiers /opt/forgejo-upgrade et /root/l11 : le lab les a laissés en place, et ils contiennent le .env de la copie, un jeton et un mot de passe de test. Contrôlez enfin qu'aucun volume ni réseau upgrade ne reste, et que la forge de production répond toujours en 15.0.10.

  • La documentation recommande d'aller directement à la dernière version : le saut 15.0.10 vers 17.0.0 a été joué, sans passer par la 16.
  • Avant de monter : notes de version, forgejo manager flush-queues (réponse Flushed), sauvegarde à froid.
  • On répète sur une copie restaurée de la production, avec l'image épinglée par digest, et on lit le journal : 17 migrations, aucune erreur dans le lab.
  • La validation compare des critères relevés avant et après, pas un seul relevé : l'ERROR gc-lfs existait déjà en 15.0.10.
  • La signature peut échouer après une restauration ou une montée : retirer les verrous gpg.
  • Remettre l'ancienne image est refusé (Forgejo will exit to keep your database safe) : le retour arrière est la restauration de la sauvegarde d'avant montée.
  • Un runner 13.2.0 enregistré hors ligne sur la copie en 17.0.0 a exécuté un job qui lit un secret (secret_len=17, Job succeeded) : mettez un job réel dans vos critères.

Six questions tirées sur huit : le chemin de montée, la vidange des files, les relevés avant et après, les verrous gpg et le retour arrière par restauration.

Contrôle de connaissances

Validez vos connaissances avec ce quiz interactif

6 questions
6 min.
70% requis

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

Ce projet vous est utile ?

Les guides, formations, quiz et labs restent gratuits. Si vous les utilisez régulièrement, vous pouvez contribuer à leur maintenance et à leur développement.

Devenir membre de soutien (nouvel onglet) Soutenir une fois (nouvel onglet) En savoir plus

Suivez aussi le projet sur LinkedIn