L'auto-hébergement

Posted on mar. 11 avril 2023 in hobby

Petite note, je fais cet article pour plusieurs raisons :

  • partager une de mes passions et un des trucs qui fait que les gens me regarde avec des yeux ronds :-D
  • suite à un repas entre amis, on m'a demandé conseil pour débuter dans la pratique de l'auto-hébergement. Alors pour en faire profiter un maximum de monde, j'ai couché tout ça par écrit
  • promouvoir à ma très petite échelle la pratique

/!\ Attention, ce blogpost est touffu et très décousu. Il n'est en rien un tuto (je ne suis pas à 2-3 approximations près), mais plutôt des pensées écrites au fil de l'eau avec un semblant d'organisation. Si ça vous a donné envie de vous lancer, partagez-le-moi, ça fera toujours plaisir. Et si vous avez des questions, contactez-moi :-)

Aspect politique et philosophique

Je vais commencer ce blogpost par présenter un peu la vision politique et philosophique qu'a pris l'auto-hébergement pour moi. Au départ, c'était surtout pour "mettre les mains dans le cambouis", m'amuser à installer un serveur web par-ci ou un serveur git par-là. Et au fur et à mesure la pratique technique s'est également accompagniée d'une revendication politique. Détaillons un peu ça.

L'auto-hébergement, self-hosting en anglais, consiste en l'hébergement des services informatiques dont on a besoin (ou envie) par soi-même. On pourrait rajouter d'autres éléments, mais ça excluerait de fait autant de tentatives pourtant louable : serveurs en propre, par exemple. Pour un professionnel, c'est héberger son site web institutionnel sur sa propre infrastructure, ainsi que tous les outils utilisés par les employés. Pour un particulier, ça démarre généralement avec un PC installé dans la DMZ de la box ou sur un dédié ou un VPS chez un fournisseur.

L'idée derrière cette pratique, c'est de (re-)prendre le controle sur les services informatiques que l'on consomme, et d'être le plus autonome sur son propre environnement technologique. Au niveau étatique, c'est une composante importante de la "souveraineté technologique". En creux, on trouve l'envie de se soustraire aux controles exercés ou exerçable par les grandes entreprises de la tech et d'éventuels gouvernements présents ou futurs, et par là-même la réaffirmation du droit à la vie privée et son application la plus strict et personnelle. C'est particulièrement mon cas. On peut aller jusqu'à y trouver pour certains un acte de résistance contre la centralisation d'Internet.

Pour moi, cet aspect d'être maître de mes outils et de mes données est le plus important. Je ne veux pas que les photos de mes vacances familiales soient stockées sur des serveurs qui ne m'appartiennent pas et qui pourraient être exploitées. Mes photos de vacances sont mes souvenirs à moi. Je ne veux pas que quelqu'un se les approprie. On parle également de mon carnet d'adresse perso, de mes agendas, et ça va jusqu'au code que je produis pour mes hobbys ou mes habitudes de lecture de journaux/blog/BD/manga/comics/romans/etc...

Oui, les journaux/blog/BD/etc... que je lis ne regardent pas d'autres personnes (ou entreprises, ou états). Tous autant qu'ils sont, ils sont le reflet de mes opinions, revendications, incertitudes, humeurs, interrogations (et des changements dans celles-ci) et je veux que personne ne puisse les utiliser.

Avant de passer à la technique pure et dure, je vais ajouter que c'est aussi une manière d'apprendre de nouvelles choses et de ne pas rester rouiller sur mes acquis. Je suis obliger de constamment me mettre à jour pour toujours avoir des services à jour. C'est également un laboratoire à ciel ouvert et ça forge aussi une certaine expertise (qui s'est déjà fait poutrer son serveur parce qu'il ne l'avait pas sécurisé comme il faut ? C'est bibi :-D)

Aspect matériel

Ok, maintenant qu'on a abordé l'auto-hébergement sous son jour politique, passons au concret : comment fait-on ? En premier il va falloir un serveur. Une machine sur laquelle on va installer les services que l'on désire.

Le plus facile, c'est d'utiliser un vieux PC qu'on n'utilise plus et qui prend la poussière dans un coin. On installe Linux dessus, et hop, ça fait un serveur. Ou bien le Raspberry Pi dont on ne sait pas quoi faire. C'est comme ça qu'à titre perso j'ai commencé : quand j'étais étudiant, mes parents ont remplacé le PC famillial par un nouveau, j'ai récupéré l'ancien et j'ai y installé un Debian 3.

Si on ne dispose pas d'une machine libre, on peut se tourner vers la location d'une VM ou d'un serveur dédié. On trouve des VPS et des dédiés par cher (4-6€/mois) qui sont parfaits pour débuter. Voire même de manière pérenne.

Si vous voulez vraiment investir et ne savez pas quoi acheter, le champs des possibles est trop grand pour que je puisse vous conseiller comme ça. Si vous n'avez de workload prévu, tournez-vous vers des mini-PC (j'adore ce form-factor) et dites-vous que plus le CPU est récent, moins il consommera d'électricité. A titre personnel, j'ai acheté un mini-PC sur une base d'intel celeron J4125 à ~150€ il y a bientôt 2 ans. En terme de puissance, c'est laaaaargement suffisant pour le workload familial. J'ai juste augmenté sa RAM à 16Go, son disque à 2To de HDD et 120Go de SSD et il me fera au moins 5 ans, voire 7-8 si je n'ai pas de grosse surprise.

Si vous avez besoin d'un gros stockage, le sujet est pour une autre fois ;-)

Aspect logiciel

L'OS

Maintenant que l'on a un matériel, il faut savoir quoi installer dessus. Si vous louez un VPS ou un dédié, vous avez le choix entre plusieurs linux (qui voudrait faire de l'hébergement avec autre chose, franchement <Troll Inside :-D>), prenez celui avec lequel vous êtes le plus à l'aise. Sinon, un ubuntu ou un debian fera très bien l'affaire.

Si vous êtes sur un hardware que vous maîtrisez, vous avez également la possibilité de partir sur de la virtualisation. ESXi, Proxmox sont les plus connus et recommandé. C'est aussi une manière de se faire une architecture n-tiers, ou de se faire une/des VM "propre" qui hébergera les services à demeure et une/des VM "bac à sable" pour les expérimentations et qui pourront être trashées/recréées autant que l'on veut.

Pour des débutants, le mieux, à mon avis, c'est de partir sur un Debian le plus simple possible, sans VM, sans fioritures, le plus classique et pour lequel on pourra trouver le plus facilement de l'aide en ligne.

Comment installer les services

La manière de gérer les services que l'on installe sur les serveurs est importante. Parce qu'elle doit être le reflet de l'organisation que l'on a ou souhaite.

On peut le faire en mode "roots" : apt get install. C'est parfait si l'on sait que l'on aura qu'un seul service d'installé ou que l'ensemble des services ne vont pas se marcher sur les pieds.
On peut le faire en mode "docker à la main" : à chaque fois on se logue en SSH sur le serveur et on pratique la cli docker (docker pull, docker run, etc)
On peut le faire avec docker-compose : on commence à organiser ses installations avec un/des fichiers docker-compose.
On peut le faire avec ansible/puppet/salt : là, c'est le début de la professionnalisation
On peut le faire avec un k8s ou k3s : on est pas là pour lancer une start-up, passez votre chemin :-D

A titre personnel, j'utilise ansible, profession oblige. Mais à mon avis, un/des docker-compose seront parfait pour des débutants et des moins-débutants. Je vais ajouter également qu'à titre perso, je suis utilisateur de docker sur mon infra perso (notez que j'insiste sur le "perso". Et aussi, podman à la place de docker sur le dernier serveur en date, pour expérimenter un peu). Ainsi l'installation de mes services est pilotée par ansible, et les services eux-même tournent sur les serveurs dans des containeurs. C'est ce qui me semble le plus propre à l'échelle hobby/serveur familial, aujourd'hui.

Quels services installer

A ce niveau-là, ce que vous voulez !

Littéralement des milliers de possibilités s'offrent à vous.

Je vais juste vous indiquer ce que j'auto-héberge, sur mon mini-PC :

  • Nextcloud, pour la synchronisation des fichiers, photos, contacts, agenda, notes, recettes de cuisine et messagerie familiale
  • Funkwhale, pour écouter ma musique où et quand je veux
  • Gitea, un serveur git ultra-léger, mais aussi très complet
  • PiHole, qui fait la résolution DNS dans la maison, ainsi qu'un premier niveau de blocage de pub et trackers
  • Kresus, pour la gestion des finances familiales
  • Searx, le meta-moteur de recherche
  • Calibre-web, pour faciliter la gestion et la distribution de nos livres électroniques (pour nos téléphones, tablettes et liseuse)
  • FreshRSS, chouette lecteur de flux RSS, pour ma veille techno et non-techno
  • Mes mails, avec une très jolie webUI, même si ça devient de plus en plus compliqué avec les années (cf Framasoft)
  • le site web de mon beau-frère
  • la webapp que j'ai codé pour lire mes mangas/comics
  • mon blog, avec Pelican
  • le future blog de mon épouse
  • Info-medoc, un petit projet perso d'il y a quelques années
  • Plusieurs autres projets perso, futurs ou anciens

On y va ?

Sur le serveur avec docker

Forcément, je ne pourrais pas être exhaustif, alors voilà le postulat de départ :

  • Vous disposez d'une machine debian minimaliste fraichement installée et à jour sur laquelle vous vous connectez en SSH
  • Vous avez choisi l'option de facilité en déployant vos services avec Docker + docker-compose
  • Vous êtes sur une machine avec une IP publique (chez un hébergeur ou si le serveur est chez vous, il doit y avoir un paramétrage dans votre box pour placer votre serveur dans la DMZ. Et hop, c'est tout pareil ensuite).
  • Il y aura moins de 10 personnes qui utiliserons votre service. Je pars sur une installation type familiale, plus d'utilisateurs pourrait nécessité une configuration différente.

Commençons par installer docker (doc officielle) :

sudo apt-get remove docker docker-engine docker.io containerd runc # On enlève ce qui pourrait gêner
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg # On installe les dépendances nécessaire à l'usage du dépôt de package docker
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg # On installe la clé GPG de docker qui va signer les packages
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo \
  "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
  "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null # On configure le dépôt officiel de docker

sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin # Installation à proprement parler de docker

Premier service hébergé

Pour aller au plus simple, je vais partir sur l'installation d'un Nextcloud avec docker-compose. On va d'ailleur fortement s'inspirer de la documentation officielle. Mettez ce qui suit dans un fichier docker-compose.yml :

version: '3'

volumes:
  nextcloud:

services:
  nextcloud:
    image: nextcloud
    restart: always
    ports:
      - 8080:80
    volumes:
      - nextcloud:/var/www/html
    environment:
      SQLITE_DATABASE: nextcloud.sqlite3

Puis lancez votre docker-compose :

docker-compose up -d

Bravo, vous pouvez vous rendre sur l'URL http://<IP_DE_VOTRE_SERVEUR>:8080 et vous devriez pouvoir complétez l'installation de votre nextcloud.

Facile, non ?

Reverse-proxy et HTTPS

Suposons maintenant que vous vouliez pouvoir accéder à votre serveur nextcloud avec un nom de domaine et sur le "bon" port. Il faut que vous achetiez/louiez un nom de domaine chez votre registrar préféré et que vous le fassiez pointer (enregistrement A pour l'IPv4 et AAAA pour l'IPv6) vers l'adresse IP publique de votre serveur (ou box). Un fois cela fait, on va rajouter le reverse-proxy traefik qui va s'occuper du certificat pour vous. Comme toujours, on va s'appuyer sur la doc officielle.

En premier lieu, arrêtez votre premier service (docker-compose down), puis modifiez le fichier docker-compose.yml comme suit :

version: '3'

volumes:
  nextcloud:
  letsencrypt:

services:
  rproxy:
    image: traefik
    command:
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.myresolver.acme.httpchallenge=true"
      - "--certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web"
      - "--certificatesresolvers.myresolver.acme.email=<VOTRE_ADRESSE@EMAIL.com>"
      - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - "letsencrypt:/letsencrypt"
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
  nextcloud:
    image: nextcloud
    restart: always
    volumes:
      - nextcloud:/var/www/html
    environment:
      SQLITE_DATABASE: nextcloud.sqlite3
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.nextcloud.rule=Host(`moncloudprive.mondomaine.example.com`)"
      - "traefik.http.routers.nextcloud.entrypoints=websecure"
      - "traefik.http.routers.nextcloud.tls.certresolver=myresolver"

On relance le docker-compose :

docker-compose up -d

Et maintenant, rendez-vous sur https://moncloudprive.mondomaine.example.com. Vous devriez voir votre service nextcloud.

Un serveur git ?

Pour l'exercice, rajoutons un serveur git qui va nous permettre de stocker notre fichier docker-compose.yml comme il faut. Après avoir arrêté nos services avec docker-compose down, modifions le fichier comme suit :

version: '3'

volumes:
  nextcloud:
  letsencrypt:
  gitea:

services:
  traefik:
    image: traefik
    restart: always
    command:
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.myresolver.acme.httpchallenge=true"
      - "--certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web"
      - "--certificatesresolvers.myresolver.acme.email=<VOTRE_ADRESSE@EMAIL.com>"
      - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - "letsencrypt:/letsencrypt"
      - "/var/run/docker.sock:/var/run/docker.sock:ro"


  nextcloud:
    image: nextcloud
    restart: always
    volumes:
      - nextcloud:/var/www/html
    environment:
      SQLITE_DATABASE: nextcloud.sqlite3
    expose:
      - "80"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.nextcloud.rule=Host(`moncloudprive.mondomaine.example.com`)"
      - "traefik.http.routers.nextcloud.entrypoints=websecure"
      - "traefik.http.routers.nextcloud.tls.certresolver=myresolver"


  gitea:
    image: gitea/gitea
    restart: always
    volume:
      - "{{ app_data_dir }}/gitea:/data"
    ports:
      - "222:22"
    expose:
      - "3000"
    env:
      RUN_MODE: prod
      SSH_DOMAIN: monserveurgit.mondomaine.example.com
      SSH_PORT: 222
      SSH_LISTEN_PORT: 22
      INSTALL_LOCK: "true"
      SECRET_KEY: "MaCleSuperPrivee"
      PROTOCOL: https
      DOMAIN: monserveurgit.mondomaine.com
      ROOT_URL: "https://monserveurgit.mondomaine.example.com/"
      ENABLE_GZIP: "true"
      DISABLE_REGISTRATION: "true"
      OFFLINE_MODE: "true"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.gitea.rule=Host(`monserveurgit.mondomaine.example.com`)"
      - "traefik.http.routers.gitea.tls=true"
      - "traefik.http.routers.gitea.entrypoints=websecure"
      - "traefik.http.routers.gitea.tls.certresolver= myresolver"

On commence à avoir l'habitude, maintenant : on relance les services avec docker-compose up -d. Vous devriez toujours avoir votre nextcloud sur https://moncloudprive.mondomaine.example.com et en plus votre serveur git sur https://monserveurgit.mondomaine.example.com.

Le reste ne dépend plus que de vous !

Note de fin

Attention, le présent blogpost ne parle pas du tout de la sécurisation du serveur, des services, ni des données stockées. Si vous vous lancez dans l'auto-hébergement sérieusement, il faut vous renseigner sur ces sujets (peut-être une idée pour un prochain blogpost, tien). Si vous ne voulez pas voir vos serveurs devenir des mineurs de cryptocoin sans votre aval ou des bots au sein d'un réseau de piratage, ni vous le voir "confisqué" par un crypto-locker, ou vos données volées, il faut que vous creusiez sérieusement ces sujets.