Les conteneurs Docker ne gèrent généralement pas SSL eux-mêmes — un reverse proxy en amont termine TLS et transmet le trafic déchiffré au conteneur. Ce guide couvre les trois approches les plus courantes.
Approche 1 : Reverse proxy Nginx avec certificat manuel
L’approche la plus simple pour les petits déploiements. Obtenez un certificat depuis GetHTTPS et montez-le dans un conteneur Nginx.
docker-compose.yml
services:
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
- ./certs/fullchain.pem:/etc/ssl/fullchain.pem:ro
- ./certs/privkey.pem:/etc/ssl/privkey.pem:ro
depends_on:
- app
app:
image: your-app:latest
expose:
- "3000"
nginx.conf
server {
listen 443 ssl http2;
server_name yourdomain.com;
ssl_certificate /etc/ssl/fullchain.pem;
ssl_certificate_key /etc/ssl/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
location / {
proxy_pass http://app:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
server {
listen 80;
server_name yourdomain.com;
return 301 https://$host$request_uri;
}
Pour renouveler : Remplacez les fichiers dans ./certs/ par les nouveaux de GetHTTPS, puis docker compose exec nginx nginx -s reload.
Approche 2 : Traefik avec Let’s Encrypt automatique
Traefik est un reverse proxy conçu pour les conteneurs. Il peut automatiquement obtenir et renouveler les certificats Let’s Encrypt.
docker-compose.yml
services:
traefik:
image: traefik:v3.0
command:
- "--providers.docker=true"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.letsencrypt.acme.email=you@example.com"
- "--certificatesresolvers.letsencrypt.acme.storage=/acme/acme.json"
- "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- traefik-acme:/acme
app:
image: your-app:latest
labels:
- "traefik.http.routers.app.rule=Host(`yourdomain.com`)"
- "traefik.http.routers.app.tls.certresolver=letsencrypt"
- "traefik.http.services.app.loadbalancer.server.port=3000"
volumes:
traefik-acme:
Traefik gère tout : émission du certificat, renouvellement et terminaison HTTPS. Aucune gestion manuelle de certificat nécessaire.
Approche 3 : Caddy (HTTPS sans configuration)
Caddy obtient et renouvelle automatiquement les certificats Let’s Encrypt sans aucune configuration.
docker-compose.yml
services:
caddy:
image: caddy:2
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy-data:/data
depends_on:
- app
app:
image: your-app:latest
expose:
- "3000"
volumes:
caddy-data:
Caddyfile
yourdomain.com {
reverse_proxy app:3000
}
C’est toute la configuration. Caddy obtient un certificat Let’s Encrypt et le renouvelle automatiquement.
Quelle approche choisir ?
| Nginx + cert. manuel | Traefik | Caddy | |
|---|---|---|---|
| Configuration | Moyenne (config + fichiers de cert.) | Moyenne (labels) | Minimale |
| Renouvellement auto | ❌ (manuel) | ✅ | ✅ |
| Flexibilité | Élevée | Élevée | Moyenne |
| Courbe d’apprentissage | Faible (familier) | Moyenne | Faible |
| Idéal pour | Petits déploiements, contrôle total | Conteneurs dynamiques, microservices | Sites simples, config minimale |
Renouveler les certificats dans Docker
Approche 1 (Nginx + manuel) :
# Remplacer les fichiers de certificat dans votre répertoire local ./certs/
cp new-fullchain.pem ./certs/fullchain.pem
cp new-privkey.pem ./certs/privkey.pem
# Recharger Nginx dans le conteneur (pas de redémarrage nécessaire)
docker compose exec nginx nginx -s reload
Approche 2 (Traefik) & 3 (Caddy) :
Automatique — ils gèrent le renouvellement en interne. Les certificats sont stockés dans des volumes Docker (traefik-acme ou caddy-data) et persistent entre les redémarrages de conteneurs.
Docker Swarm : utiliser les secrets
Pour les déploiements Docker Swarm, utilisez des Docker secrets au lieu de monter les fichiers de certificat en bind mount :
# Créer des secrets à partir de vos fichiers de certificat
docker secret create ssl_cert fullchain.pem
docker secret create ssl_key privkey.pem
# Dans docker-compose.yml (mode deploy)
services:
nginx:
image: nginx:alpine
secrets:
- ssl_cert
- ssl_key
configs:
- source: nginx_conf
target: /etc/nginx/conf.d/default.conf
secrets:
ssl_cert:
external: true
ssl_key:
external: true
Les secrets sont montés dans /run/secrets/ssl_cert et /run/secrets/ssl_key à l’intérieur du conteneur — chiffrés au repos et en transit.
Erreurs courantes
Intégrer les certificats dans les images Docker
# ❌ NE JAMAIS faire ceci
COPY fullchain.pem /etc/ssl/fullchain.pem
COPY privkey.pem /etc/ssl/privkey.pem
Les certificats expirent tous les 90 jours. Les intégrer dans l’image signifie reconstruire et redéployer tous les 60 jours. Montez toujours les certificats comme volumes ou secrets.
Oublier d’exposer le port 80
Le port 80 est nécessaire pour :
- La redirection HTTP → HTTPS
- Le challenge HTTP-01 de Let’s Encrypt (pour le renouvellement automatique avec Traefik/Caddy)
ports:
- "80:80" # Ne pas oublier
- "443:443"
Ne pas persister les données ACME
Traefik et Caddy stockent leurs certificats Let’s Encrypt et clés de compte dans des volumes. Sans persistance, ils redemandent des certificats à chaque redémarrage de conteneur — et atteindront les limites de débit :
volumes:
traefik-acme: # DOIT être un volume nommé, pas anonyme
caddy-data:
Questions fréquemment posées
Mon conteneur d’application peut-il gérer SSL directement ?
C’est possible, mais ce n’est pas recommandé. Le modèle reverse proxy (terminer TLS à l’entrée, transmettre du HTTP en interne) est standard car : l’application n’a pas besoin de connaître les certificats, le renouvellement ne nécessite pas de redémarrage de l’application, et la configuration TLS est centralisée.
Comment gérer SSL pour plusieurs conteneurs ?
Avec Traefik ou Caddy, ajoutez des labels/configurations pour chaque service — ils obtiendront automatiquement des certificats séparés. Avec Nginx, ajoutez plusieurs blocs server dans la configuration.
Dois-je utiliser GetHTTPS ou l’ACME intégré de Traefik ?
Utilisez l’ACME intégré de Traefik/Caddy en production — il gère le renouvellement automatiquement. Utilisez GetHTTPS quand vous avez besoin d’un certificat pour l’approche reverse proxy Nginx (Approche 1) ou pour les environnements où le conteneur n’a pas d’accès internet direct pour les challenges ACME.
Comment monter les certificats de manière sécurisée dans Docker ?
Montez en lecture seule (:ro), utilisez des Docker secrets pour la clé privée en mode Swarm, et assurez-vous que seul le conteneur reverse proxy a accès aux fichiers de certificat. N’intégrez jamais de certificats dans une image Docker — ils expireront et vous devriez reconstruire.
Puis-je utiliser les certificats GetHTTPS avec Kubernetes ?
Oui. Créez un secret TLS Kubernetes à partir de vos fichiers de certificat GetHTTPS :
kubectl create secret tls my-tls-cert --cert=fullchain.pem --key=privkey.pem
Puis référencez-le dans votre ressource Ingress. Pour un renouvellement automatisé dans Kubernetes, envisagez cert-manager avec un ClusterIssuer Let’s Encrypt.