Aller au contenu
Et si j'hébergeais mon blog sur une infrastructure européenne

Et si j'hébergeais mon blog sur une infrastructure européenne

17 avril 2026

Lorna Ladril sur Unsplash

Quand j’ai décidé d’ouvrir ce blog, je ne voulais pas gérer une infrastructure complexe surtout pour un simple blog. En suivant ma philisophie KISS (Keep it simple and stupid), j’avais opté pour un CMS qui ne nécessite pas une base de données comme wordpress. Un générateur de site statique facilement customizable à l’aide de plugins développés par la communauté est amplement suffisant et permet d’avoir de meilleures performances. C’est pour cela que j’avais opté pour Hugo.

Un des avantages que j’ai vu est la facilité d’écriture de mes articles : de simples fichiers au format markdown, et pour la publication de l’article, une simple commande hugo le transforme en document html autoportant.

Initialement, j’avais mis le contenu de mon blog sur un repository GitHub comme je l’aurai fait naturellement. Et côté hébergement, j’avais choisi un hébergement statique sur CleverCloud (Merci à Zwindler et Julien Wittouck pour l’inspiration).

Alors pourquoi tout changer ?

Tout simplement, avec ma prise de poste à Teralab, les questions de souveraineté me tiennent de plus en plus à coeur. Et l’actualité géopolitique de ces derniers mois me donnent plutôt raison.

J’ai donc migré vers Codeberg, une forge Git européenne, open source, gérée par une association allemande à but non lucratif. Et pour l’hébergement, j’ai choisi d’utiliser BunnyCDN, un CDN slovène dont le modèle économique ne repose pas sur la revente de données. Ce billet raconte pourquoi — et dans les coulisses, comment.

Pourquoi changer pour Codeberg ?

J’utilise GitHub depuis de nombreuses années aussi bien pour y stocker des dépôts publics comme privés, contribuer à des projets et aussi y déployer ce blog. Certes, cette plateforme est extraordinaire aussi bien pour l’exposition publique qu’elle apporte mais j’aimerai dépendre de moins en moins de services américains qui sont soumis au Cloud Act. Et travaillant pour une entreprise qui prône la souveraineté européenne, le dilemme devenait de plus en plus présent.

Et le déclic fut lorsque j’ai lu un message de Philippe Charrière qui venait de basculer sur Codeberg pour ses projets personnels.

Codeberg comme alternative européenne

Codeberg est une instance publique de Forgejo, un fork communautaire de Gitea. Derrière, une association à but non lucratif basée à Berlin, dont les finances sont publiques et le financement repose sur les dons.

Ce qui m’a convaincu :

La compatibilité. Forgejo Actions reprend la syntaxe des GitHub Actions. La migration d’un workflow existant se résume souvent à changer quelques URLs et adapter les runners. L’adaptation est vraiment facile pour quelqu’un qui est habitué aux Github Actions.

L’ancrage européen. Les serveurs sont en Allemagne, sous droit européen, RGPD natif. Pour un blog personnel, c’est un critère que j’aurais dû appliquer depuis le début.

La sobriété. Codeberg n’essaie pas d’être GitHub. Pas de Copilot, pas de marketplace tentaculaire, pas de réseau social intégré. Juste une forge Git bien faite.

Une association à but non lucratif: Codeberg n’a pas pour but d’exploiter commercialement nos données. Et l’adhésion est ridiculement basse (48€ / an). Certes, l’hébergement est gratuit mais il faut soutenir cette initiative en adhérant ou en faisant des dons.

Ce qu’on perd en revanche : la visibilité. GitHub concentre des millions de développeurs. Codeberg est bien plus confidentiel. Pour un projet open source qui veut des contributeurs, c’est un vrai sujet. Pour mon blog personnel, c’est négligeable.

Et la migration est très facile, il suffit d’indiquer l’url de son dépôt GitHub et Codeberg s’occupe de tout. De plus, l’interface utilisateur ressemble à GitHub, ce qui permet de ne pas être trop dépaysé.

Pourquoi changer CleverCloud pour Bunny.net ?

Je cherchais à mettre en place un CDN devant mon blog afin d’accélérer les performances ainsi que protéger le site contre le DDOS. J’aurai pu opter pour Cloudflare qui propose un “free tier” assez important mais je cherchais une alternative européenne.

Un ancien collègue m’a suggéré Bunny.net. BunnyCDN est une entreprise slovène, fondée en 2012, dont le modèle économique est simple : vous payez pour ce que vous consommez (bande passante et stockage), pas en données personnelles. Pour un blog statique avec un trafic modeste, le coût est dérisoire.

Et en plus de proposer un Content Delivery Network assez dense, ils proposent de nombreux services dont un espace de stockage, un DNS, et même du computing@edge (exécution de conteneurs, et même une base de données relationnelle).

En parallèle de l’hébergement de mon blog, je cherchais aussi une solution pour l’hébergement du site du club d’escrime artistique où je pratique mon activité préférée. En calculant les coûts d’hébergement pour ce site statique, je me suis rendu compte que la solution BunnyCDN espace de stockage + CDN était plus avantageuse : Moins d'1€ par mois pour l’hébergement.

Même si j’apprécie énormément les services de CleverCloud, la simplicité et le coût avantageux de BunnyCDN m’a fait basculer sur cette solution. Et c’est un premier test pour préparer l’hébergement du site du club.

La stack technique retenue

Après migration, voici sur quoi repose le blog :

ComposantAvantAprès
Forge GitGitHubCodeberg (Forgejo)
CI/CDGitHub ActionsForgejo Actions
GénérateurHugo + thème HextraHugo + thème Hextra (inchangé)
HébergementCleverCloudBunnyCDN Storage + CDN

Bilan après migration

La migration de ce blog sur la nouvelle stack m’a pris une demi-journée de travail pour migrer le code, écrire un pipeline forgejo et l’hébergement sur BunnyCDN.

Depuis la mise en production, le quotidien n’a pas fondamentalement changé — et c’est exactement ce que je voulais. J’écris, je commite, je pousse. Le pipeline tourne, le blog se met à jour automatiquement.

Ce qui a changé pour moi :

Je publie depuis une forge que je contrôle davantage. Le pipeline est entièrement dans mon dépôt, lisible, modifiable. La réactivité de Forgejo Actions m’a agréablement surpris — les builds sont rapides, les logs clairs. Et la migration depuis les Github Actions est facilité du fait que la syntaxe des Forgejo Actions s’en rapproche énormément.

Il y a aussi quelque chose de plus difficile à quantifier : une cohérence enfin retrouvée. Écrire sur la souveraineté numérique depuis une infrastructure qui l’incarne, c’est plus confortable que l’inverse.

Ce qui n’a pas changé pour les lecteurs :

Absolument rien. Le blog est toujours disponible à la même URL. BunnyCDN dispose d’un réseau de points de présence mondial — la latence est meilleure qu’à mon hébergement initial. Le tableau de bord est simple, les coûts transparents : quelques centimes par mois, sans mauvaise surprise.

À qui recommander cette migration ?

À toute personne qui gère un site statique et qui a envie de reprendre le contrôle sans passer des semaines à tout reconstruire. Ce n’est pas une migration pour les blogs à fort trafic ou les équipes qui ont besoin de l’écosystème GitHub. C’est une migration pour ceux qui, comme moi, ont réalisé que leurs choix techniques ne reflétaient plus leurs convictions.

Des axes d’amélioration

J’ai vu que BunnyCDN propose un provider Teraform. C’est d’ailleurs un des seuls fournisseurs CDN européen qui en propose un. Et avec leur stockage objet, ce sera simple et efficace de stocker le state pour la mise en prod.

En regardant mon dashboard de BunnyCDN, je constate que le HIT rate est assez bas. De ce fait, l’avantage d’un CDN n’est pas réellement utilisé. Il faut que je rajoute les headers concernant le cache control pour l’améliorer.

Bref, encore un peu de boulot mais c’est une affaire d’optimisation qui sera transparente pour l’utilisateur.


Les coulisses — Pour ceux qui veulent reproduire

Info

Cette section est technique. Si vous êtes là pour les raisons, vous pouvez vous arrêter ici.

La structure du workflow Forgejo Actions

Vous trouverez mon blog sur Codeberg : a-lencre-rouillee

Le fichier de déploiement est découpé en deux jobs : build (génération Hugo) et deploy (envoi sur BunnyCDN). Cette séparation permet de rejouer uniquement le déploiement en cas d’échec réseau, sans relancer tout le build.

name: Deploy to BunnyCDN

on:
  push:
    branches:
      - main
  workflow_dispatch:

env:
  HUGO_BASE_URL: https://david.drugeon-hamon.bzh
  HUGO_VERSION: 0.150.0
  GO_VERSION: 1.26.2
  BUNNY_API_BASE: https://api.bunny.net

jobs:
  build:
    runs-on: codeberg-tiny
    steps:
      - name: Clone repository
        uses: actions/checkout@v4
        with:
          submodules: recursive
          fetch-depth: 0
          shallow-submodules: true

      - name: Install Go
        run: |
          curl -fsSL "https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz" -o go.tar.gz
          tar -C /usr/local -xzf go.tar.gz
          rm go.tar.gz
          echo "/usr/local/go/bin" >> $GITHUB_PATH

      - name: Install Hugo
        run: |
          curl -fsSL "https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.tar.gz" \
            -o hugo.tar.gz
          tar -xzf hugo.tar.gz hugo
          mv hugo /usr/local/bin/
          rm hugo.tar.gz

      - name: Generate static files
        env:
          HUGO_ENV: production
        run: |
          hugo \
            --gc \
            --minify \
            --baseURL "${{ env.HUGO_BASE_URL }}" \
            --destination cdn

      - name: Upload generated files
        uses: actions/upload-artifact@v3
        with:
          name: cdn-content
          path: cdn/

  deploy:
    needs: [build]
    runs-on: codeberg-tiny
    steps:
      - name: Install lftp
        run: |
          apt-get update
          apt-get install -y lftp

      - name: Restore artifact
        uses: actions/download-artifact@v3
        with:
          name: cdn-content
          path: cdn/

      - name: Deploy to Bunny Storage
        env:
          BUNNY_STORAGE_ZONE: ${{ secrets.BUNNY_STORAGE_ZONE }}
          BUNNY_FTP_PASSWORD: ${{ secrets.BUNNY_FTP_PASSWORD }}
        run: |
          BUNNY_FTP_HOST="storage.bunnycdn.com"
          lftp -e "
            set ssl:verify-certificate no;
            set ftp:ssl-allow yes;
            set cmd:fail-exit no;
            open ftp://${BUNNY_STORAGE_ZONE}:${BUNNY_FTP_PASSWORD}@${BUNNY_FTP_HOST};
            mirror --reverse --verbose --parallel=10 cdn/ ./;
            quit
          "

Hugo modules : pourquoi Go est nécessaire

Le thème Hextra est intégré comme Hugo module (via go.mod) plutôt que comme git submodule. C’est le mode recommandé par le thème — il permet des mises à jour propres avec versioning sémantique. En contrepartie, Hugo a besoin de Go installé dans l’environnement de build pour télécharger les dépendances au premier lancement.

# go.mod
module github.com/ddrugeon/a-lencre-rouillee

go 1.23

require github.com/imfing/hextra v0.12.0 // indirect

Déploiement sur Bunny

Initialement, j’étais parti pour utiliser RClone pour faciliter la synchronisation comme je le ferai avec un bucket S3. Malheureusement, Bunny ne propose pas encore d’API compatible S3 même si une bêta privée est en cours.

Bunny propose une API ou un accès FTP pour la partie stockage. La solution de contournement que j’ai utilisée dans mon pipeline : [lftp](https://doc.ubuntu-fr.org/lftp). L’accès en FTP se fait alors avec le format {zone}:{api_key}@{region}.storage.bunnycdn.com.