Introduction

Vous avez un VPS qui prend la poussière ? Plusieurs projets perso qui mériteraient d’être hébergés proprement ? Dans cet article, je vais vous montrer comment transformer votre VPS en une plateforme d’hébergement moderne, sécurisée et automatisée.

L’objectif : déployer facilement plusieurs sites web avec des certificats SSL automatiques, le tout orchestré par Traefik et Infomaniak.

À la fin de ce tutoriel, vous pourrez :

  • 🚀 Déployer un nouveau site en quelques minutes
  • 🔒 Obtenir automatiquement des certificats SSL/TLS
  • 🌐 Gérer vos DNS automatiquement
  • 🔄 Rediriger HTTP vers HTTPS
  • 📊 Accéder à un dashboard de monitoring

Pourquoi cette stack ?

Traefik : le reverse proxy moderne

Traefik est un reverse proxy et load balancer conçu pour l’ère des conteneurs.

Contrairement à Nginx ou Apache, Traefik :

  • Se configure automatiquement via Docker labels
  • Gère les certificats SSL via Let’s Encrypt
  • Offre un dashboard de monitoring intégré
  • Supporte le hot-reload sans redémarrage

En plus, c’est un Lyonnais 😅, passé par Zenika, Emile Vauge, qui l’a créé 🚀

Infomaniak : Hébergeur suisse

Infomaniak est un hébergeur suisse qui offre :

  • DNS ultra-rapides avec une API REST complète
  • Hébergement respectueux de la vie privée (RGPD compliant)
  • Infrastructure 100% renouvelable en Suisse
  • Support francophone réactif
  • Validation DNS Challenge pour les certificats wildcard
  • Prix compétitifs pour les domaines .fr, .com, .ch

Pourquoi Infomaniak plutôt que CloudFlare ?

Si vous cherchez un fournisseur européen, respectueux de vos données, avec un excellent support en français, Infomaniak est un choix idéal.
Par ailleurs, c’est mon fournisseur de DNS ; donc c’était aussi ce choix qui m’a conduit à ça 😎

ACME & Let’s Encrypt : SSL gratuit et automatique

Le protocole ACME (Automatic Certificate Management Environment) permet d’obtenir des certificats SSL gratuitement via Let’s Encrypt. Le DNS Challenge valide que vous possédez le domaine via un enregistrement TXT temporaire.

Prérequis

Avant de commencer, vous aurez besoin de :

  • ✅ Un VPS Ubuntu 22.04+ (ou Debian)
  • ✅ Un nom de domaine géré chez Infomaniak
  • ✅ Docker et Docker Compose installés
  • ✅ Un token API Infomaniak
  • ✅ Accès SSH root ou sudo à votre VPS

Budget estimé

  • VPS : 5-10€/mois (OVH, Hetzner, Contabo, ou Infomaniak)
  • Domaine : 9-15€/an chez Infomaniak
  • API Infomaniak : Gratuit
  • Let’s Encrypt : Gratuit

Total : ~10€/mois pour héberger autant de sites que vous voulez ! 🎉

Architecture de la solution

Voici comment les différents composants interagissent :

Internet

Infomaniak DNS (exemple.fr → IP_VPS)

VPS (Ports 80/443)

Traefik (Reverse Proxy)

┌────────────┬────────────┬────────────┐
│   Site 1   │   Site 2   │   Site 3   │
│   (www)    │   (blog)   │   (app)    │
└────────────┴────────────┴────────────┘
     Docker      Docker      Docker
   Container   Container   Container

Flux de certificat SSL :

  1. Traefik détecte un nouveau service Docker
  2. Traefik demande un certificat à Let’s Encrypt
  3. Let’s Encrypt demande une validation DNS
  4. Traefik crée automatiquement un enregistrement TXT via l’API Infomaniak
  5. Let’s Encrypt valide et délivre le certificat
  6. Traefik supprime l’enregistrement TXT temporaire

Tout cela se passe automatiquement ! 🎯

Étape 1 : Configuration Infomaniak

1.1 - Enregistrer ou transférer votre domaine chez Infomaniak

Si ce n’est pas déjà fait :

  1. Créez un compte sur Infomaniak
  2. Achetez un nouveau domaine ou transférez-en un existant
  3. Pour un transfert, vous aurez besoin du code de transfert (Auth Code) de votre registrar actuel
  4. Attendez la validation du transfert (généralement quelques heures à 5 jours)

1.2 - Créer un token API

C’est crucial pour le DNS Challenge !

  1. Connectez-vous à votre Manager Infomaniak
  2. Allez dans OutilsAPI & WebhooksTokens API
  3. Cliquez sur Créer un token API
  4. Configuration recommandée :
    Nom du token : traefik-acme-dns
    Portée : Gestion des domaines
    Permissions :
    - DNS:READ
    - DNS:WRITE
  5. Important : Copiez le token généré immédiatement, vous ne pourrez plus le voir !

Le token ressemble à : abc123def456ghi789jkl...

⚠️ Sécurité : Ce token donne accès à vos DNS. Ne le partagez jamais et ne le commitez pas sur Git !

1.3 - Récupérer l’ID de votre domaine

Vous aurez besoin de l’ID interne de votre domaine pour certaines opérations API.

Méthode simple (via API) :

# Installer jq pour parser le JSON
apt install -y jq

# Récupérer l'ID du domaine (remplacez VOTRE_TOKEN)
curl -H "Authorization: Bearer VOTRE_TOKEN" \
  "https://api.infomaniak.com/1/product?service_name=domain" | jq

# Cherchez votre domaine dans le résultat et notez son "id"

Notez l’ID de votre domaine, vous en aurez besoin plus tard.

1.4 - Configurer les enregistrements DNS de base

Dans le Manager Infomaniak, allez dans DomainesVotre domaineGérer la zone DNS

Créez ces enregistrements :

Type   Nom                      Cible                TTL
A      @                        IP_DE_VOTRE_VPS      3600
A      www                      IP_DE_VOTRE_VPS      3600
A      blog                     IP_DE_VOTRE_VPS      3600
A      news                     IP_DE_VOTRE_VPS      3600
A      traefik                  IP_DE_VOTRE_VPS      3600

Alternative : Wildcard

Si vous prévoyez beaucoup de sous-domaines :

Type   Nom     Cible                TTL
A      @       IP_DE_VOTRE_VPS      3600
A      *       IP_DE_VOTRE_VPS      3600

Note : Les enregistrements _acme-challenge.* seront créés automatiquement par Traefik via l’API, ne les créez pas manuellement.

Comment ça marche ? 👇

Le DNS Challenge permet à Let’s Encrypt de vérifier que vous contrôlez un nom de domaine sans exposer le port 80.
Traefik génère un enregistrement DNS TXT temporaire (ex: _acme-challenge.votre-domaine.fr) via l’API de votre fournisseur DNS (comme Infomaniak), que Let’s Encrypt valide avant de délivrer le certificat.
Une fois la validation réussie, l’enregistrement est automatiquement supprimé — sécurisé, propre et totalement automatisé.

Étape 2 : Préparation du VPS

2.1 - Sécuriser le VPS (rapidement)

# Se connecter en SSH
ssh root@IP_DE_VOTRE_VPS

# Mettre à jour le système
apt update && apt upgrade -y

# Installer les essentiels
apt install -y curl git ufw

# Configurer le firewall
ufw default deny incoming
ufw default allow outgoing
ufw allow ssh
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable

# Vérifier le firewall
ufw status

2.2 - Installer Docker et Docker Compose

# Installer Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh

# Vérifier l'installation
docker --version
docker compose version

# Démarrer Docker au boot
systemctl enable docker
systemctl start docker

2.3 - Créer l’arborescence

# Créer la structure de dossiers
mkdir -p /opt/traefik
mkdir -p /opt/sites/{www,blog,app}

# Se placer dans le dossier Traefik
cd /opt/traefik

Étape 3 : Configuration de Traefik

3.1 - Créer le réseau Docker

Les conteneurs communiqueront via ce réseau :

docker network create traefik-public

3.2 - Fichier de configuration Traefik

Créez /opt/traefik/traefik.yml :

# Configuration globale
global:
  checkNewVersion: true
  sendAnonymousUsage: false

# API et Dashboard
api:
  dashboard: true
  insecure: false  # Accès uniquement via HTTPS

# Points d'entrée (ports)
entryPoints:
  web:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https
          permanent: true
  
  websecure:
    address: ":443"
    http:
      tls:
        certResolver: infomaniak

# Providers
providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false  # Sécurité : opt-in uniquement
    network: traefik-public
    watch: true

# Certificats SSL via Let's Encrypt
certificatesResolvers:
  infomaniak:
    acme:
      email: votre-email@exemple.fr
      storage: /acme.json
      caServer: "https://acme-v02.api.letsencrypt.org/directory"
      # Pour tester, utilisez le staging :
      # caServer: "https://acme-staging-v02.api.letsencrypt.org/directory"
      dnsChallenge:
        provider: infomaniak
        delayBeforeCheck: 30
        resolvers:
          - "1.1.1.1:53"
          - "1.0.0.1:53"

# Logs
log:
  level: INFO
  format: common

accessLog:
  format: common

3.3 - Variables d’environnement

Créez /opt/traefik/.env :

# Infomaniak API
INFOMANIAK_ACCESS_TOKEN=votre_token_api_infomaniak

# Dashboard Auth (généré avec: htpasswd -nb admin votre_password)
TRAEFIK_DASHBOARD_AUTH=admin:$$apr1$$xyz...

# Domaine principal
DOMAIN=exemple.fr

Générer le hash du mot de passe :

# Installer htpasswd
apt install -y apache2-utils

# Générer le hash (remplacez admin et password)
htpasswd -nb admin votre_password

# Copiez le résultat dans .env en doublant les $
# Exemple : admin:$apr1$xyz... devient admin:$$apr1$$xyz...

3.4 - Docker Compose pour Traefik

Créez /opt/traefik/docker-compose.yml :

version: '3.8'

networks:
  traefik-public:
    external: true

services:
  traefik:
    image: traefik:v3.2
    container_name: traefik
    restart: unless-stopped
    security_opt:
      - no-new-privileges:true
    networks:
      - traefik-public
    ports:
      - "80:80"
      - "443:443"
    environment:
      - INFOMANIAK_ACCESS_TOKEN=${INFOMANIAK_ACCESS_TOKEN}
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./traefik.yml:/traefik.yml:ro
      - ./acme.json:/acme.json
    labels:
      # Activer Traefik pour lui-même
      - "traefik.enable=true"
      
      # Dashboard
      - "traefik.http.routers.dashboard.rule=Host(`traefik.${DOMAIN}`)"
      - "traefik.http.routers.dashboard.service=api@internal"
      - "traefik.http.routers.dashboard.entrypoints=websecure"
      - "traefik.http.routers.dashboard.tls.certresolver=infomaniak"
      
      # Authentification Basic Auth
      - "traefik.http.routers.dashboard.middlewares=auth"
      - "traefik.http.middlewares.auth.basicauth.users=${TRAEFIK_DASHBOARD_AUTH}"

3.5 - Préparer le fichier de certificats

# Créer le fichier acme.json avec les bonnes permissions
touch acme.json
chmod 600 acme.json

# IMPORTANT : les permissions doivent être strictement 600
ls -la acme.json
# -rw------- 1 root root 0 Jan 18 10:00 acme.json

3.6 - Lancer Traefik

cd /opt/traefik

# Vérifier la configuration
docker compose config

# Lancer Traefik
docker compose up -d

# Suivre les logs
docker compose logs -f

Vous devriez voir Traefik démarrer et demander un certificat pour traefik.exemple.fr.

Vérification :

# État des conteneurs
docker ps

# Logs détaillés
docker compose logs traefik | grep -i acme
docker compose logs traefik | grep -i certificate

# Vérifier acme.json (doit contenir des certificats)
cat acme.json | jq

Accédez au dashboard : https://traefik.exemple.fr (utilisez votre login/password)

Étape 4 : Déployer vos sites

Maintenant que Traefik fonctionne, déployer un nouveau site est ultra-simple !

Créez /opt/sites/www/docker-compose.yml :

version: '3.8'

networks:
  traefik-public:
    external: true

services:
  www:
    image: nginx:alpine
    container_name: www
    restart: unless-stopped
    networks:
      - traefik-public
    volumes:
      - ./html:/usr/share/nginx/html:ro
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.www.rule=Host(`www.exemple.fr`) || Host(`exemple.fr`)"
      - "traefik.http.routers.www.entrypoints=websecure"
      - "traefik.http.routers.www.tls.certresolver=infomaniak"
      - "traefik.http.services.www.loadbalancer.server.port=80"

Créez du contenu HTML :

mkdir -p /opt/sites/www/html
echo "<h1>Mon site perso</h1>" > /opt/sites/www/html/index.html

Lancez le site :

cd /opt/sites/www
docker compose up -d

Accédez à https://www.exemple.fr → Certificat SSL automatique ! ✅

Étape 5 : Middlewares utiles

Traefik permet d’ajouter des middlewares pour enrichir vos routes.

Redirection www → non-www

labels:
  - "traefik.http.middlewares.redirect-www.redirectregex.regex=^https://www\\.(.*)"
  - "traefik.http.middlewares.redirect-www.redirectregex.replacement=https://$${1}"
  - "traefik.http.middlewares.redirect-www.redirectregex.permanent=true"
  - "traefik.http.routers.www.middlewares=redirect-www"

Headers de sécurité

labels:
  - "traefik.http.middlewares.security-headers.headers.stsSeconds=31536000"
  - "traefik.http.middlewares.security-headers.headers.stsIncludeSubdomains=true"
  - "traefik.http.middlewares.security-headers.headers.stsPreload=true"
  - "traefik.http.middlewares.security-headers.headers.contentTypeNosniff=true"
  - "traefik.http.middlewares.security-headers.headers.browserXssFilter=true"
  - "traefik.http.routers.www.middlewares=security-headers"

Rate limiting

labels:
  - "traefik.http.middlewares.rate-limit.ratelimit.average=100"
  - "traefik.http.middlewares.rate-limit.ratelimit.burst=50"
  - "traefik.http.routers.api.middlewares=rate-limit"

Compression GZIP

labels:
  - "traefik.http.middlewares.gzip.compress=true"
  - "traefik.http.routers.www.middlewares=gzip"

Étape 6 : Monitoring et maintenance

Vérifier l’état des certificats

# Voir les certificats dans acme.json
cat /opt/traefik/acme.json | jq '.infomaniak.Certificates[] | {domain: .domain, notAfter: .certificate}'

# Logs des renouvellements
docker compose -f /opt/traefik/docker-compose.yml logs | grep -i renew

Let’s Encrypt délivre des certificats valides 90 jours. Traefik les renouvelle automatiquement à 30 jours de l’expiration.

Script de backup

Créez /root/backup-traefik.sh :

#!/bin/bash
BACKUP_DIR="/root/backups"
DATE=$(date +%Y%m%d_%H%M%S)

mkdir -p $BACKUP_DIR

# Backup de la config Traefik
tar -czf $BACKUP_DIR/traefik-$DATE.tar.gz \
    /opt/traefik/traefik.yml \
    /opt/traefik/docker-compose.yml \
    /opt/traefik/.env \
    /opt/traefik/acme.json

# Garder seulement les 7 derniers backups
find $BACKUP_DIR -name "traefik-*.tar.gz" -mtime +7 -delete

echo "Backup terminé : traefik-$DATE.tar.gz"

Automatisez avec cron :

chmod +x /root/backup-traefik.sh
crontab -e

# Ajouter cette ligne (backup tous les jours à 3h du matin)
0 3 * * * /root/backup-traefik.sh >> /var/log/traefik-backup.log 2>&1

Monitoring avec Prometheus (optionnel)

Ajoutez à traefik.yml :

metrics:
  prometheus:
    addEntryPointsLabels: true
    addServicesLabels: true
    entryPoint: metrics

entryPoints:
  metrics:
    address: ":8082"

Et exposez les métriques :

labels:
  - "traefik.http.routers.metrics.rule=Host(`metrics.exemple.fr`)"
  - "traefik.http.routers.metrics.service=prometheus@internal"
  - "traefik.http.routers.metrics.entrypoints=websecure"
  - "traefik.http.routers.metrics.middlewares=auth"

Étape 7 : Sécurité avancée

Durcissement système

# Désactiver root SSH
sed -i 's/#PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
systemctl restart sshd

# Installer fail2ban
apt install -y fail2ban

# Configuration fail2ban pour SSH
cat > /etc/fail2ban/jail.local <<EOF
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
EOF

systemctl restart fail2ban

Protection DDoS et sécurité réseau

Au niveau d’Infomaniak :

  • Activez la protection anti-DDoS disponible dans votre panneau de gestion
  • Configurez des filtres IP si nécessaire dans la zone DNS

Au niveau du VPS :

  • Utilisez fail2ban pour bloquer les tentatives de brute-force
  • Configurez UFW pour limiter l’accès aux ports essentiels
  • Envisagez d’utiliser CloudFlare en frontal pour la protection DDoS avancée (compatible avec Infomaniak DNS)

Isolation réseau

Utilisez des réseaux Docker séparés pour isoler les services :

networks:
  traefik-public:
    external: true
  app-internal:
    internal: true  # Pas d'accès Internet

Troubleshooting

Certificat non généré

Symptômes : Erreur SSL dans le navigateur

Solutions :

# 1. Vérifier les logs ACME
docker compose -f /opt/traefik/docker-compose.yml logs traefik | grep -i acme

# 2. Vérifier le token Infomaniak
docker compose -f /opt/traefik/docker-compose.yml exec traefik env | grep INFOMANIAK

# 3. Tester manuellement le DNS Challenge
dig +short TXT _acme-challenge.exemple.fr

# 4. Vider acme.json et réessayer
cd /opt/traefik
docker compose down
rm acme.json
touch acme.json
chmod 600 acme.json
docker compose up -d

Rate limiting Let’s Encrypt

Let’s Encrypt limite à 50 certificats par domaine par semaine.

Solution : Utilisez le serveur de staging pendant les tests :

certificatesResolvers:
  cloudflare:
    acme:
      caServer: "https://acme-staging-v02.api.letsencrypt.org/directory"

Service non accessible

# Vérifier que le conteneur est sur le bon réseau
docker inspect nom_conteneur | grep -A 10 Networks

# Vérifier les labels Traefik
docker inspect nom_conteneur | grep -A 20 Labels

# Vérifier les routes Traefik
curl http://localhost:8080/api/http/routers

# Tester le service directement
docker exec -it nom_conteneur wget -O- http://localhost:port

Aller plus loin

Certificat wildcard

Pour *.exemple.fr :

entryPoints:
  websecure:
    http:
      tls:
        certResolver: infomaniak
        domains:
          - main: exemple.fr
            sans:
              - "*.exemple.fr"

Haute disponibilité

  • Utilisez plusieurs serveurs avec un load balancer
  • Partagez acme.json via un volume network (NFS, GlusterFS)
  • Utilisez un cluster Docker Swarm ou Kubernetes

CI/CD automatique

Intégrez avec GitLab CI / GitHub Actions :

# .gitlab-ci.yml
deploy:
  stage: deploy
  script:
    - ssh user@vps "cd /opt/sites/app && git pull && docker compose up -d --build"
  only:
    - main

Conclusion

Félicitations ! 🎉 Vous avez maintenant une infrastructure moderne pour héberger tous vos projets perso :

✅ SSL/TLS automatique avec Let’s Encrypt
✅ Gestion DNS via CloudFlare
✅ Déploiement simplifié avec Docker
✅ Reverse proxy intelligent avec Traefik
✅ Sécurité renforcée
✅ Monitoring intégré

Coût total : ~10€/mois pour une infinité de sites !

Ce que vous avez appris

  • Configurer Traefik comme reverse proxy
  • Automatiser les certificats SSL avec ACME
  • Utiliser le DNS Challenge de CloudFlare
  • Déployer des applications conteneurisées
  • Sécuriser un VPS de production

Prochaines étapes

  1. Automatisez vos backups (sites + bases de données)
  2. Mettez en place un monitoring (Prometheus + Grafana)
  3. Optimisez les performances (cache, CDN CloudFlare)
  4. Ajoutez du CI/CD pour déployer automatiquement

Ressources

🤖 IA 🤖

Cette article, le premier de la série, a été rédigé en grande majorité avec l’IA Claude et Euria puis modifier par mes soins.
L’image de cet article a été générée par Gemini Nano Banana.