Ajouter un nouveau service
Guide pas-a-pas pour déployer un nouveau service Docker avec un sous-domaine custom et HTTPS automatique. Pour l'opération inverse, voir Retirer un service.
Prerequis
- Le service tourne en Docker
- Tu veux y acceder via
monservice.home.gabin-simond.fren HTTPS - Traefik et AdGuard Home sont déjà en place
Vue d'ensemble du flow
Étape 1 — Ajouter le service dans docker-compose.yml
Ajouter le service dans /mnt/ssd/config/docker/docker-compose.yml :
monservice:
image: image/monservice:latest@sha256:<digest> # epingle, voir plus bas
container_name: monservice
restart: unless-stopped
# ports: # Pas besoin d'exposer le port si uniquement via Traefik
# - "8080:8080"
volumes:
- monservice-data:/data # Adapter selon le service
networks:
- proxy # IMPORTANT : doit etre sur le reseau proxy
labels:
traefik.enable: "true"
traefik.http.routers.monservice.rule: Host(`monservice.home.gabin-simond.fr`)
traefik.http.routers.monservice.entrypoints: websecure
traefik.http.routers.monservice.tls: "true"
traefik.http.routers.monservice.tls.certresolver: letencrypt
traefik.http.routers.monservice.tls.domains[0].main: "*.home.gabin-simond.fr"
traefik.http.routers.monservice.tls.domains[0].sans: home.gabin-simond.fr
traefik.http.routers.monservice.middlewares: crowdsec@file,authelia@docker,security-headers@file
traefik.http.services.monservice.loadbalancer.server.port: "8080" # port INTERNE
middlewares n'est pas optionnelleSans elle, le service est joignable sans authentification par quiconque atteint Traefik. Les trois middlewares vont toujours ensemble :
| Middleware | Ce qu'il fait |
|---|---|
crowdsec@file | refuse les IP bannies avant tout le reste |
authelia@docker | ForwardAuth : pas de session valide, pas de backend |
security-headers@file | HSTS, X-Frame-Options, etc. |
La seule raison légitime de s'en passer est que l'application consomme Authelia en OIDC — un ForwardAuth casserait alors son flux, comme pour Forgejo et Outline. Dans ce cas c'est un client OIDC qu'il faut déclarer, pas une absence de protection.
- Le service doit être sur le réseau
proxypour que Traefik le voie - Le
server.portest le port interne du container, pas le port exposé - Pas besoin de
ports:si l'acces se fait uniquement via Traefik - Remplacer
monservicepartout par le vrai nom du service - Le certresolver s'écrit bien
letencrypt, sans les— c'est le nom déclaré danstraefik.yml, pas une faute de frappe à corriger - Épingler l'image par digest : les 22 images du compose le sont. Relever le digest
avec
docker image inspect <image> --format '{{index .RepoDigests 0}}' - Si le conteneur doit résoudre
*.home.gabin-simond.fr(typiquement pour parler à Authelia en OIDC), lui ajouterdns: 192.168.1.28
Si le service a besoin d'un volume, l'ajouter dans la section volumes: en bas du compose :
volumes:
monservice-data:
Étape 2 — DNS rewrite dans AdGuard Home
Pour que monservice.home.gabin-simond.fr pointe vers le RPi sans passer par Internet, il faut un DNS rewrite dans AdGuard.
Option A — Wildcard (recommandé)
Si tu as déjà un wildcard *.home.gabin-simond.fr, rien a faire. Tous les sous-domaines pointent déjà vers le RPi.
Option B — Rewrite spécifique
Dans AdGuard Home → Filtres → Reecritures DNS → ajouter :
| Domaine | Réponse |
|---|---|
monservice.home.gabin-simond.fr | 192.168.1.28 |
Ou dans la config (user_rules dans AdGuardHome.yaml) :
||monservice.home.gabin-simond.fr^$dnsrewrite=192.168.1.28,client=192.168.1.0/24
||monservice.home.gabin-simond.fr^$dnsrewrite=100.97.239.90,client=100.64.0.0/10
AdGuard tourne en network_mode: host et voit les vraies IPs clients. LAN recoit l'IP locale, Tailscale recoit l'IP Tailscale. Voir Comment fonctionne le DNS pour le détail.
Étape 3 — Déployer
cd /mnt/ssd/config/docker
docker compose up -d monservice
docker/, pas à la racine du dépôt/mnt/ssd/config/docker-compose.yml n'existe pas. Un docker compose lancé depuis
/mnt/ssd/config ne trouve aucun fichier.
Et vérifier que les secrets sont descellés avant de démarrer : .env est un lien vers
/run/homelab/.env, sur tmpfs. Après un redémarrage sans descellement, les conteneurs
partent sans leurs variables — en silence.
Étape 4 — Vérifier
- DNS — le domaine resout vers le RPi :
nslookup monservice.home.gabin-simond.fr 127.0.0.1
- HTTPS — le certificat est valide :
curl -I https://monservice.home.gabin-simond.fr
-
Traefik dashboard — le router apparaît sur
https://traefik.home.gabin-simond.fr. Pas surhttp://IP:8080: le port 8080 n'est pas publié sur l'hôte, il ne sert qu'au healthcheck interne du conteneur. -
L'authentification mord bien — sans session, on doit être redirigé, pas servi :
curl -s -o /dev/null -w '%{http_code}\n' https://monservice.home.gabin-simond.fr
# 302 -> Authelia a pris la main. 200 -> le service est EXPOSE, la ligne middlewares manque.
Le certificat Let's Encrypt peut prendre 30 secondes a être généré la première fois (DNS challenge Cloudflare). Si tu vois une erreur TLS, attends un peu et reessaie.
Checklist rapide
- Service ajoute dans
docker/docker-compose.yml, image epinglee par digest - Les trois middlewares sur le router (
crowdsec,authelia,security-headers) - Service sur le réseau
proxy - DNS rewrite dans AdGuard (ou wildcard déjà en place)
-
docker compose up -d - Test DNS (
nslookup) - Test HTTPS (
curlou navigateur) - Test que l'auth mord :
curl -o /dev/null -w '%{http_code}'doit rendre 302 - Commit le compose modifie dans
homelab-config