Auto Hébergement
À l'aube du XXIe siècle il fallait des compétences et des outils techniques pour avoir un espace personnel en ligne. Cela s'est rapidement simplifié au milieu de la première décennie où il suffisait de s'inscrire sur divers sites pour publier ses billets en ligne.
Le tout s'est rapidement centralisé autour de quelques services de micro publications tel que Facebook et Twitter ou de publications de billets comme Wordpress.
Depuis les années 2000, je suis passé par l'hébergement de Free pour mon blog et mon équipe de jeu, par la suite je suis passé par divers acteurs comme OVH, Ikoula, Digital Oceans et AWS.
Désormais, je souhaite tenter l'auto hébergement. Le principe est simple, utiliser sa connexion internet et son propre matériel pour rendre disponible des services de son réseau local au monde extérieur. Si il a toujours été possible de le faire, les connexions non pro et sans fibre étaient un peu frêle en débit montant pour se permettre de proposer plusieurs services.
J'avais sur mon ex-serveur une liste de services dont je ne me servais que trop peu... ou qui demandaient tellement de maintenance par rapport à mon utilisation quotidienne que je me suis résolu à les abandonner.
Adieu Matrix, Peertube, Mastodon et NextCloud, je vous retrouverai peut être un jour. J'ai gardé le plus important: mon Blog Ghost, dont vous lisez les lignes, et mon gitlab. Les pages statiques, je les héberge sur Vercel (la gratuité et la simplicité me satisfont).
Traefik routier
Sur le serveur Ikoula, j'avais tout de centralisé sur une unique machine, Docker écoutait aux ports 80 et 443 et laissait le conteneur NGINX de l'image nginx-proxy
rediriger vers les conteneurs qui étaient sur le même réseau; seul le port 222 était redirigé vers gitlab sans l'aide de NGINX. Un autre conteneur gérait le SSL avec Let's Encrypt afin d'avoir le chiffrage entre les internautes et les services.
À l'heure actuelle, les internautes toquent à ma Freebox qui redirige tout le trafic 80, 443 et 222 vers un raspberrypi qui route tout ça vers le conteneur Traefik. Ce dernier agit en tant que Load Balancer, tout comme NGINX précédemment, il fait suivre les données à ghost et git suivant ce qui est tapé dans la barre de navigation des internautes.
J'ai séparé la charge entre deux serveurs physiques (le Raspberry Pi et l'ordinateur portable) afin de ne pas avoir le Pi qui souffre de trop.
Fichier de composition Docker:
services:
traefik:
image: "traefik"
command:
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- --entrypoints.gitssh.address=:222
- --providers.docker
- --providers.docker.exposedByDefault=false
- --providers.file.filename=/etc/traefik/services.toml
- --providers.file.directory=/config
- --api
- --certificatesresolvers.le-ssl.acme.email=${TRAEFIK_SSLEMAIL}
- --certificatesresolvers.le-ssl.acme.storage=/acme.json
- --certificatesresolvers.le-ssl.acme.tlschallenge=true
- --log.level=DEBUG
ports:
- "80:80"
- "443:443"
- "222:222"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "./private/acme.json:/acme.json"
- "./config/:/config/"
labels:
- "traefik.enable=true"
# Dashboard
- "traefik.http.routers.traefik.rule=Host(`dashboard.${PRIMARY_DOMAIN}`)"
- "traefik.http.routers.traefik.service=api@internal"
- "traefik.http.routers.traefik.tls=true"
- "traefik.http.routers.traefik.tls.certresolver=le-ssl"
- "traefik.http.routers.traefik.entrypoints=websecure"
- "traefik.http.routers.traefik.middlewares=authtraefik"
- "traefik.http.middlewares.authtraefik.basicauth.users=${TRAEFIK_PASSWORD}"
# global redirect to https
- "traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)"
- "traefik.http.routers.http-catchall.entrypoints=web"
- "traefik.http.routers.http-catchall.middlewares=redirect-to-https"
# middleware redirect
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
restart: unless-stopped
networks:
- traefik
networks:
traefik:
external: true
Le .env vierge de tout mot de passe:
TRAEFIK_PASSWORD=user:$$d23$$DSJKL$$20d9$KEySMaSH920$$2 # à générer avec htpasswd
TRAEFIK_SSLEMAIL=bonjour@gmail.com # email
PRIMARY_DOMAIN=our-domain.com # domaine
- Let's Encrypt est utilisé pour obtenir les certificats SSL.
- Un dashboard est disponible.
TRAEFIK_PASSWORD
doit être généré via htpasswd et il faut doubler les caractères$
.- Traefik peut détecter les conteneurs mais la fonctionnalité n'est pas activé ici, cela provoquait des problèmes dans certaines situations.
Le fichier de configuration yaml de Traefik pour gitlab:
http:
routers:
to-gitlab:
rule: "Host(`git.rei.ms`)"
service: gitlab
entrypoints: websecure
tls:
certResolver: "le-ssl"
to-reglab:
rule: "Host(`reg.rei.ms`)"
service: gitlab
entrypoints: websecure
tls:
certResolver: "le-ssl"
services:
gitlab:
loadBalancer:
servers:
- url: http://XXX.XXX.XXX.XXX
tcp:
routers:
to-gitssh:
service: gitssh
entrypoints: gitssh
rule: HostSNI(`*`)
services:
gitssh:
loadBalancer:
servers:
- address: XXX.XXX.XXX.XXX:222
Blog Ghost
Je déteste wordpress. C'est une usine infernale où l'interface est devenue très compliquée pour rien. Je souhaite me concentrer sur le contenu quand j'écris, pas sur des milliers d'options qui pètent. Mon choix s'est porté sur Ghost pour gérer la publication de mes billets, et je suis très satisfait.
Ma configuration ghost est la suivante:
services:
db:
image: mysql:8
volumes:
- db_data:/var/lib/mysql
restart: always
command: --mysql-native-password=ON
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
networks:
- db
ghost:
depends_on:
- db
image: ghost:latest
restart: always
volumes:
- ./content:/var/lib/ghost/content
environment:
database__client: mysql
database__connection__host: db
database__connection__user: ${MYSQL_USER}
database__connection__password: ${MYSQL_PASSWORD}
database__connection__database: ${MYSQL_DATABASE}
url: https://${GHOST_URL}
mail__transport: $mail__transport
mail__options__service: $mail__options__service
mail__options__host: $mail__options__host
mail__options__port: $mail__options__port
mail__options__secure: $mail__options__secure
mail__options__auth__user: $mail__options__auth__user
mail__options__auth__pass: $mail__options__auth__pass
mail__from: $mail__from
labels:
traefik.enable: "true"
traefik.http.routers.ghost.rule: "Host(`${GHOST_URL}`)"
traefik.docker.network: "traefik"
traefik.http.routers.ghost.entrypoints: "websecure"
traefik.http.routers.ghost.service: ghost
#traefik.http.routers.ghost.tls.certresolver: "default"
traefik.http.routers.ghost.tls.certresolver: "le-ssl"
traefik.http.services.ghost.loadbalancer.server.port: "2368"
networks:
- traefik
- db
volumes:
db_data:
ghost_data:
networks:
traefik:
external: true
db:
un .env se trouve à la racine avec les variables d'environnements. Notez "labels" qui permet de communiquer avec Traefik et de faire rediriger l'url vers ce conteneur.
Gestionnaire de dépôt git Gitlab
Cette partie se trouve sur la machine qui héberge Gitlab. La configuration de traefik diffère légèrement. Cette machine a également Docker avec un conteneur Traefik qui écoute sur les ports 80 et 443.
Le compose de Traefik ressemble à ça:
services:
traefik:
image: "traefik"
command:
- --entrypoints.web.address=:80
- --entrypoints.dashboard.address=:8080
- --entrypoints.websecure.address=:443
- --api
ports:
- "80:80"
- "8080:8080"
- "443:443"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "./traefik.yml:/traefik.yml:ro"
restart: unless-stopped
networks:
- traefik
networks:
traefik:
external: true
Le fichier de configuration traefik.yml ainsi:
entrypoints:
http:
address: ":80"
traefik:
address: ":8080"
api:
dashboard: true
insecure: true
debug: true
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
network: traefik
watch: true
allowEmptyServices: true
exposedByDefault: true
Pour ce qui est du compose gitlab, j'invite à aller sur la documentation officielle, néanmoins je vais partager les étiquettes (labels) du compose qui sont propres à Traefik:
labels:
- "traefik.enable=true"
- "traefik.http.routers.gitlab.service=gitlab-service"
- "traefik.http.routers.gitlab.entrypoints=http"
- "traefik.http.routers.gitlab.rule=Host(`git.rei.ms`) || Host(`reg.rei.ms`)"
- "traefik.http.services.gitlab-service.loadbalancer.server.port=80"
On voit que le conteneur récupère deux hosts, l'un pour les dépôts git et l'autre le gestionnaire d'images docker.
Discussion