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

  1. Forgejo (VM/Proxmox)

    • Git central, issues, PR, wiki.

    • Stockage Ceph (repos + artefacts si tu veux).

  2. Forgejo Actions Runner(s)

    • VM(s) dĂ©diĂ©es, rootless Podman.

    • LabelisĂ©es selon rĂ´le (ex. builder-debian, test-proxmox, publish-iso).

  3. 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 :

  1. Build paquets Debian nécessaires.

  2. Générer une image ISO/USB autoinstall.

  3. Tester l’image dans une VM Proxmox (CI automatisée).

  4. 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 runner lab-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 les ssh qm ... par des curl signés avec PROXMOX_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.