Guide d’installation Forgejo sur Proxmox adapté au contexte (VM, PostgreSQL externe, Ceph, et LDAP via Heimdall/Keycloak).
🚀 Installation Forgejo sur Proxmox
1. Créer la VM dans Proxmox
-
OS : Debian 12 (Bookworm) ou Ubuntu 24.04
-
Ressources : 2 vCPU, 4 Go RAM, 30 Go disque système
-
Stockage :
-
Disque système → Ceph RBD (ou SSD local si tu préfères vitesse)
-
Repos Forgejo → CephFS (simple) ou RBD dédié (performant) monté sur
/var/lib/forgejo
-
2. Préparer le système
apt update && apt upgrade -y
apt install -y git wget curl unzip postgresql-client
adduser --system --shell /bin/bash --gecos 'Forgejo' --group --disabled-password --home /var/lib/forgejo forgejo
3. Créer la base PostgreSQL (sur ton cluster PG existant)
Sur ton serveur PostgreSQL :
CREATE USER forgejo WITH PASSWORD 'MotDePasseSolide';
CREATE DATABASE forgejo OWNER forgejo;
4. Installer Forgejo
mkdir -p /opt/forgejo && cd /opt/forgejo
wget https://codeberg.org/forgejo/forgejo/releases/download/v9.0.2/forgejo-9.0.2-linux-amd64
chmod +x forgejo-9.0.2-linux-amd64
ln -s forgejo-9.0.2-linux-amd64 forgejo
Créer l’arborescence :
mkdir -p /etc/forgejo /var/lib/forgejo /var/log/forgejo
chown -R forgejo:forgejo /var/lib/forgejo /var/log/forgejo
5. Configurer Forgejo (/etc/forgejo/app.ini
)
[database]
DB_TYPE = postgres
HOST = pgsql-toncluster.local:5432
NAME = forgejo
USER = forgejo
PASSWD = MotDePasseSolide
SSL_MODE = disable
[repository]
ROOT = /var/lib/forgejo/repos
[server]
DOMAIN = git.chezlepro.ca
HTTP_PORT = 3000
ROOT_URL = https://git.chezlepro.ca/
DISABLE_SSH = false
START_SSH_SERVER = true
SSH_PORT = 22
LFS_START_SERVER = true
[log]
MODE = file
LEVEL = Info
ROOT_PATH = /var/log/forgejo
[service]
DISABLE_REGISTRATION = true
ENABLE_NOTIFY_MAIL = true
[mailer]
ENABLED = true
FROM = "Forgejo <git@chezlepro.ca>"
HOST = mail.chezlepro.ca:587
USER = git
PASSWD = ton_mot_de_passe
SKIP_VERIFY = true
[auth.ldap]
NAME = Heimdall
HOST = ldap.chezlepro.ca
PORT = 389
USE_SSL = false
BIND_DN = cn=admin,dc=chezlepro,dc=ca
BIND_PASSWORD = ton_pass
USER_BASE = ou=users,dc=chezlepro,dc=ca
USER_FILTER = (&(objectClass=person)(uid=%s))
ATTRIBUTE_USERNAME = uid
ATTRIBUTE_NAME = cn
ATTRIBUTE_MAIL = mail
6. Service systemd
/etc/systemd/system/forgejo.service
[Unit]
Description=Forgejo
After=network.target
[Service]
User=forgejo
Group=forgejo
WorkingDirectory=/var/lib/forgejo
ExecStart=/opt/forgejo/forgejo web --config /etc/forgejo/app.ini
Restart=always
Environment=USER=forgejo HOME=/var/lib/forgejo
[Install]
WantedBy=multi-user.target
Puis :
systemctl daemon-reload
systemctl enable --now forgejo
7. Proxy HTTPS avec Nginx (si tu veux Let’s Encrypt ou ton CA maison)
/etc/nginx/sites-available/forgejo.conf
server {
listen 80;
server_name git.chezlepro.ca;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name git.chezlepro.ca;
ssl_certificate /etc/letsencrypt/live/git.chezlepro.ca/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/git.chezlepro.ca/privkey.pem;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
}
}
Activation :
ln -s /etc/nginx/sites-available/forgejo.conf /etc/nginx/sites-enabled/
systemctl reload nginx
8. Tests
-
Ouvrir https://git.chezlepro.ca
-
Premier compte = admin initial
-
Vérifier login LDAP via Heimdall
-
Vérifier création d’un dépôt, push/pull via SSH et HTTPS
👉 Résultat : tu as un Forgejo moderne, léger, branché sur ton PG cluster, avec stockage Ceph et login centralisé LDAP.
C’est robuste, souverain, et tu peux rajouter Forgejo Actions ou Woodpecker pour la CI/CD selon besoin.
On ajoute Forgejo Actions. Voilà un setup simple, léger et propre (runner rootless avec Podman).
1) Activer Actions dans Forgejo
/etc/forgejo/app.ini
:
[actions]
ENABLED = true
# facultatif, limite de jobs simultanés côté serveur
DEFAULT_CONCURRENCY = 4
Puis :
systemctl restart forgejo
2) Créer un jeton de runner
Dans l’UI Forgejo (admin) → Site Administration → Actions → Runners → New registration token.
Note le Registration Token et l’URL (ex.: https://git.chezlepro.ca
).
3) VM “Runner” (déconseillé sur la même VM que Forgejo si tu veux isoler)
OS: Debian 12 / Ubuntu 24.04
Ressources: 2 vCPU, 2–4 Go RAM (selon le nombre de jobs parallèles)
3.1 Paquets de base + Podman rootless
apt update && apt install -y curl tar podman uidmap slirp4netns fuse-overlayfs
# utilisateur non-root dédié
useradd -m -s /bin/bash forgejorun
loginctl enable-linger forgejorun
su - forgejorun -c 'podman info' # initialise le rootless
3.2 Installer le runner Forgejo
su - forgejorun
mkdir -p ~/runner && cd ~/runner
# Ajuste la version au besoin :
curl -L -o runner.tgz https://codeberg.org/forgejo/runner/releases/download/v3.4.0/runner-linux-amd64.tgz
tar xzf runner.tgz
./forgejo-runner --version
3.3 Enregistrer le runner
./forgejo-runner register
# Réponds aux questions :
# Forge URL: https://git.chezlepro.ca
# Registration token: (colle le token)
# Runner name: ortrux-actions-01
# Runner labels: self-hosted,linux,podman,chezlepro
# Concurrency: 2 (ou plus selon CPU/RAM)
# Executor: podman
# Image par défaut: docker.io/library/debian:stable-slim (ou ubuntu:24.04)
Un fichier config.yml
est créé dans ~/runner
.
3.4 Service systemd (user service, rootless)
/etc/systemd/system/forgejo-runner@.service
:
[Unit]
Description=Forgejo Actions Runner (%i)
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=%i
WorkingDirectory=/home/%i/runner
ExecStart=/home/%i/runner/forgejo-runner daemon
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target
Active avec l’utilisateur forgejorun
:
systemctl enable --now forgejo-runner@forgejorun
systemctl status forgejo-runner@forgejorun
4) (Option) Runner sans conteneur
Si tu refuses tout container en prod, tu peux utiliser l’exécuteur shell :
./forgejo-runner register
# Executor: shell
# Labels: self-hosted,linux,shell
⚠️ Pas d’isolation : les jobs s’exécutent directement sur l’OS du runner.
5) Workflow type (dans un dépôt)
Créer .forgejo/workflows/ci.yml
:
name: CI
on:
push:
branches: [ main ]
pull_request:
jobs:
build:
runs-on: [self-hosted, linux, podman] # ou [self-hosted, linux, shell]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install deps
run: npm ci
- name: Test
run: npm test -- --ci
6) Bonnes pratiques de Chezlepro
-
Isolation : runner(s) sur VM dédiée; 1 runner = 1 VM si tu veux cloisonner par projet/tenant.
-
Réseau : si builds docker/podman doivent pousser des images internes, donne un accès restreint à ton registry privé (si tu en as un) ou publie vers un registry par projet.
-
Stockage cache : garde
~/runner/_work
sur un disque rapide (RBD SSD ou NVMe) pour accélérer les builds. -
Sécurité : labels différents pour runners « trusted » vs « publics ». N’expose pas un runner “puissant” aux PR non-fiables.
-
Quotas : ajuste la concurrency côté runner et
DEFAULT_CONCURRENCY
côté Forgejo pour éviter d’étrangler ta grappe.
7) Vérification rapide
-
Dans Forgejo → repo → Actions : le runner doit apparaître Online.
-
Lancer un push → le job démarre → logs temps réel dispo dans l’onglet Actions.
Excellent 👌 Concentrons-nous sur Forgejo + CI/CD dans le contexte de ta semence numérique (où tout doit être autonome, reproductible et sans dépendance externe).
🌱 Pourquoi Forgejo Actions colle à ton projet
-
Souveraineté : tout est local (Forgejo + runner), pas de dépendance à GitHub ou à GitLab.com.
-
Standardisation : c’est compatible avec le format GitHub Actions (fichiers YAML dans
.forgejo/workflows/
). -
Sobriété : tu peux choisir le mode d’exécution (rootless Podman, Docker, ou même shell direct).
-
Flexibilité : tes workflows CI/CD deviennent des briques réutilisables pour automatiser la construction, les tests, et la génération de ton ISO/USB “semence numérique”.
⚙️ Architecture type pour ta CI/CD
-
Forgejo (VM/Proxmox)
-
Git central, issues, PR, wiki.
-
Stockage Ceph (repos + artefacts si tu veux).
-
-
Forgejo Actions Runner(s)
-
VM(s) dédiées, rootless Podman.
-
Labelisées selon rôle (ex.
builder-debian
,test-proxmox
,publish-iso
).
-
-
Artefacts produits
-
ISO bootable Debian (préseed/autoinstall).
-
Scripts Ansible/Playbooks validés.
-
Images VM (qcow2) prêtes à déployer.
-
Documentation PDF/Markdown (générée automatiquement).
-
🛠️ Exemple de workflow Forgejo Actions
👉 Ce pipeline simple : build un paquet Debian .deb
à partir d’un dépôt source et le stocke comme artefact.
name: Build Debian Package
on:
push:
branches: [ main ]
jobs:
build:
runs-on: [self-hosted, linux, podman]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup build deps
run: |
sudo apt update
sudo apt install -y build-essential devscripts debhelper
- name: Build package
run: |
dpkg-buildpackage -us -uc -b
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: deb-package
path: ../*.deb
Résultat :
-
Ă€ chaque push, un
.deb
est produit. -
Tu peux ensuite chaîner ça avec un job “Publish ISO” qui prend ce paquet et reconstruit une ISO Debian avec tes outils intégrés.
🔗 Liens directs avec ta semence numérique
-
Reproductibilité : tout build doit pouvoir se refaire à l’identique, sans Internet (donc runners doivent avoir accès à ton miroir APT interne / apt-cacher-ng).
-
Pipeline final : dépôt → build des paquets + images → test automatisé dans une VM Proxmox → génération de l’ISO bootable → publication dans un répertoire Ceph distribué.
-
Durabilité : tu peux garder plusieurs versions des ISO générées dans Ceph, avec logs et checksums associés.
👉 Je peux te proposer un pipeline CI/CD complet pour ta semence numérique, étape par étape :
-
Build paquets Debian nécessaires.
-
Générer une image ISO/USB autoinstall.
-
Tester l’image dans une VM Proxmox (CI automatisée).
-
Publier l’artefact final (ISO + hash).
voilà un pipeline CI/CD Forgejo Actions “de bout en bout” pour ta semence numérique — 100% auto-hébergeable, reproductible, et sans Internet (en s’appuyant sur ton miroir/apt-cacher-ng interne).
0) Pré-requis (une fois)
-
Runners : au moins 2
-
builder-debian
(rootless Podman, accès APT interne) -
lab-proxmox
(accès au réseau mgmt PVE,curl
+jq
)
-
-
Secrets Forgejo (org ou repo → Settings → Secrets)
-
APT_MIRROR_URL
(ex:http://soron.chezlepro.ca:3142/debian
) -
PROXMOX_API_URL
(ex:https://asgard:8006/api2/json
) -
PROXMOX_API_TOKEN_ID
(ex:gitlab-ci@pve!runner
) -
PROXMOX_API_TOKEN_SECRET
-
(optionnel)
GPG_KEY_ID
,GPG_PRIVATE_KEY
,GPG_PASSPHRASE
si tu signes tes paquets/ISO
-
-
Ceph / dépôt artefacts internes
-
Un chemin NFS/CephFS, ex:
/mnt/ceph/semence/builds
monté sur le runnerlab-proxmox
.
-
-
Arborescence du repo
semence-numerique/
debian/ # sources des .deb internes (un sous-dossier par paquet)
image/ # config live-build / preseed / scripts post-install
live-build/
preseed.cfg
hooks/
tests/
proxmox/
test-qemu.sh # tests “smoke” à exécuter dans la VM
.forgejo/
workflows/
1) Build des paquets Debian (.deb)
.forgejo/workflows/01-build-debs.yml
name: 01 - Build Debian packages
on:
push:
branches: [ main ]
paths:
- 'debian/**'
workflow_dispatch:
jobs:
build:
runs-on: [self-hosted, linux, podman, builder-debian]
env:
DEBIAN_FRONTEND: noninteractive
APT_MIRROR_URL: ${{ secrets.APT_MIRROR_URL }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Configure APT to use internal mirror
run: |
echo "Acquire::http::Proxy \"${APT_MIRROR_URL}\";" | sudo tee /etc/apt/apt.conf.d/01proxy
sudo apt-get update
- name: Install build deps
run: |
sudo apt-get install -y --no-install-recommends \
build-essential devscripts debhelper equivs lintian git ca-certificates
- name: Build all packages
working-directory: ./debian
run: |
set -e
mkdir -p ../_artifacts/debs
for PKG in */; do
cd "$PKG"
sudo mk-build-deps -i -r -t "apt-get -y --no-install-recommends" || true
dpkg-buildpackage -us -uc -b
cd ..
done
mv ../*.deb ../_artifacts/debs/ || true
- name: (Optional) Sign .deb with GPG
if: ${{ secrets.GPG_PRIVATE_KEY != '' }}
run: |
echo "${{ secrets.GPG_PRIVATE_KEY }}" | base64 -d > /tmp/private.key
gpg --batch --import /tmp/private.key
for f in ./_artifacts/debs/*.deb; do
echo "${{ secrets.GPG_PASSPHRASE }}" | \
dpkg-sig --gpg "${{ secrets.GPG_KEY_ID }}" --sign builder "$f"
done
- name: Upload artifacts (deb)
uses: actions/upload-artifact@v4
with:
name: debs
path: _artifacts/debs/
2) Construction de l’ISO autoinstall (live-build)
.forgejo/workflows/02-build-iso.yml
name: 02 - Build ISO (live-build)
on:
workflow_dispatch:
push:
branches: [ main ]
paths:
- 'image/**'
- '.forgejo/workflows/01-build-debs.yml'
jobs:
iso:
runs-on: [self-hosted, linux, podman, builder-debian]
env:
APT_MIRROR_URL: ${{ secrets.APT_MIRROR_URL }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Download deb artifacts
uses: actions/download-artifact@v4
with:
name: debs
path: ./_artifacts/debs
- name: Install live-build toolchain
run: |
echo "Acquire::http::Proxy \"${APT_MIRROR_URL}\";" | sudo tee /etc/apt/apt.conf.d/01proxy
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
live-build xorriso isolinux squashfs-tools genisoimage ca-certificates
- name: Prepare live-build config (offline-friendly)
working-directory: ./image/live-build
run: |
set -e
mkdir -p config/includes.chroot/opt/semence
cp -v ../../_artifacts/debs/*.deb config/includes.chroot/opt/semence/ || true
# Copier preseed et hooks
cp -v ../preseed.cfg config/includes.installer/preseed.cfg
rsync -a ../hooks/ config/hooks/ || true
# Mirror interne
echo "${APT_MIRROR_URL}" > config/archives/mirror
# Exemple: paquet local auto-installé via hook chroot
cat > config/hooks/010-local-debs.chroot <<'EOF'
#!/bin/sh
set -e
dpkg -i /opt/semence/*.deb || apt-get -f install -y
EOF
chmod +x config/hooks/010-local-debs.chroot
- name: Build ISO
working-directory: ./image/live-build
run: |
sudo lb clean
sudo lb config \
--mode debian \
--distribution bookworm \
--archive-areas "main contrib non-free non-free-firmware" \
--apt-secure false \
--parent-mirror-bootstrap "${APT_MIRROR_URL}" \
--parent-mirror-chroot "${APT_MIRROR_URL}" \
--mirror-bootstrap "${APT_MIRROR_URL}" \
--mirror-chroot "${APT_MIRROR_URL}"
sudo lb build
- name: Collect ISO
run: |
mkdir -p _artifacts/iso
mv image/live-build/live-image-amd64.hybrid.iso _artifacts/iso/semence-debian-amd64.iso
- name: Upload ISO
uses: actions/upload-artifact@v4
with:
name: iso
path: _artifacts/iso/semence-debian-amd64.iso
Tu peux remplacer
live-build
par FAI, debian-cd, ou un pipeline preseed + late-command selon tes préférences. Le point clé : tout pointe vers ton miroir APT interne.
3) Test automatisé sur Proxmox (création VM, boot, smoke tests)
.forgejo/workflows/03-test-proxmox.yml
name: 03 - Test ISO on Proxmox
on:
workflow_dispatch:
workflow_run:
workflows: ["02 - Build ISO (live-build)"]
types: [completed]
jobs:
test:
runs-on: [self-hosted, linux, lab-proxmox]
env:
PROXMOX_API_URL: ${{ secrets.PROXMOX_API_URL }}
PROXMOX_API_TOKEN_ID: ${{ secrets.PROXMOX_API_TOKEN_ID }}
PROXMOX_API_TOKEN_SECRET: ${{ secrets.PROXMOX_API_TOKEN_SECRET }}
VMID: 6201
NODE: asgard
STORAGE: CephNVMe
BRIDGE: vmbr0
ISO_STORAGE: cephFS
ISO_NAME: semence-debian-amd64.iso
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Download ISO artifact
uses: actions/download-artifact@v4
with:
name: iso
path: ./_artifacts/iso
- name: Upload ISO to Proxmox storage
run: |
# Exemple via ssh/scp si le runner a accès au storage monté côté PVE
# Sinon, utiliser pvesh/curl upload selon ta config.
scp ./_artifacts/iso/${ISO_NAME} root@${NODE}:/var/lib/vz/template/iso/${ISO_NAME} || true
- name: Create VM
run: |
set -e
ssh root@${NODE} "qm stop ${VMID} || true; qm destroy ${VMID} || true"
ssh root@${NODE} "qm create ${VMID} --name semence-ci --memory 4096 --cores 2 --net0 virtio,bridge=${BRIDGE}"
ssh root@${NODE} "qm set ${VMID} --scsihw virtio-scsi-single --scsi0 ${STORAGE}:32"
ssh root@${NODE} "qm set ${VMID} --ide2 ${ISO_STORAGE}:iso/${ISO_NAME},media=cdrom"
ssh root@${NODE} "qm set ${VMID} --boot order=ide2; qm start ${VMID}"
- name: Wait for installer to finish (timeout 20m)
run: |
# À adapter: soit on scrute la console, soit on attend un SSH up,
# soit on utilise un hook post-install qui touche un endpoint.
sleep 600
- name: Run smoke tests (ssh into VM)
run: |
# Exemple: test-qemu.sh pourrait vérifier des services de base
echo "TODO: Implement your connectivity check (qemu-guest-agent, cloud-init, etc.)"
- name: Cleanup
if: always()
run: |
ssh root@${NODE} "qm stop ${VMID} || true; qm destroy ${VMID} || true"
Tu peux raffiner : utiliser Proxmox Cloud-Init pour injecter un user/clé et exécuter tes
tests/proxmox/test-qemu.sh
. Si tu préfères l’API REST PVE : remplace lesssh qm ...
par descurl
signés avecPROXMOX_API_TOKEN_*
.
4) Publication interne (CephFS + checksums)
.forgejo/workflows/04-publish.yml
name: 04 - Publish ISO to Ceph
on:
workflow_dispatch:
workflow_run:
workflows: ["03 - Test ISO on Proxmox"]
types: [completed]
jobs:
publish:
runs-on: [self-hosted, linux, lab-proxmox]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Download ISO artifact
uses: actions/download-artifact@v4
with:
name: iso
path: ./_artifacts/iso
- name: Publish to CephFS
run: |
set -e
mkdir -p /mnt/ceph/semence/builds
cp -v ./_artifacts/iso/semence-debian-amd64.iso /mnt/ceph/semence/builds/
(cd /mnt/ceph/semence/builds && sha256sum semence-debian-amd64.iso > semence-debian-amd64.sha256)
- name: (Optional) Sign checksum
if: ${{ secrets.GPG_PRIVATE_KEY != '' }}
run: |
echo "${{ secrets.GPG_PRIVATE_KEY }}" | base64 -d > /tmp/private.key
gpg --batch --import /tmp/private.key
cd /mnt/ceph/semence/builds
echo "${{ secrets.GPG_PASSPHRASE }}" | \
gpg --batch --yes --pinentry-mode loopback --passphrase-fd 0 \
--local-user "${{ secrets.GPG_KEY_ID }}" \
--output semence-debian-amd64.sha256.sig \
--sign semence-debian-amd64.sha256
Bonnes pratiques (spécifiques à ta semence numérique)
-
Offline first : tout pointe vers
APT_MIRROR_URL
(ton apt-cacher-ng / miroir local). -
Reproductibilité : épingle les versions (tag Forgejo Runner, versions live-build, paquets).
-
Séparation des responsabilités : runners dédiés (build vs lab) + labels stricts.
-
Sécurité : secrets stockés côté Forgejo, runners “publics” sans accès Proxmox.
-
Traçabilité : artefacts versionnés (ISO +
.sha256
+.sig
) sur Ceph, nommés avec date/commit si tu veux :semence-debian-amd64-{{ short_sha }}.iso
.
Une bonne manière d'attirer l'attention de vos lecteurs est de raconter une histoire.
Tout ce que vous considérez écrire peut être raconté comme une histoire.