Dernière étape pour ma livraison en production. Je vais vouloir que mon domaine hello.chocteau.dev pointe vers mon site et soit sécurisé en SSL. Pour commencer, je vais modifier ma zone DNS chez mon fournisseur de nom de domaine.
Et maintenant, je vais configurer traefik pour gérer mes domaines. Vous allez voir, c'est pas très compliqué.
Je vais créer sur mon serveur un répertoire traefik dans lequel je vais mettre le fichier docker-compose.yaml suivant :
version: "3.8"
services:
traefik:
# Plutôt que d'installer traefik sur mon serveur, je vais utiliser son image docker. Plus simple !
image: traefik:v2.0
# Les ports exposés sont 80 et 443 ( https )
ports:
- "80:80"
- "443:443"
volumes:
# Au niveau des montages de volume, traefik a besoin d'avoir accès au docker de la machine hôte
- /var/run/docker.sock:/var/run/docker.sock
# On lui ajoute également son fichier de configuration
- ./traefik.toml:/etc/traefik/traefik.toml
# Dans le fichier acme.json, il stockera les certificats générés avec let's encrypt
- ./acme.json:/acme.json
# En cas de problème... redémarre !
restart: always
networks:
# On ajoute le réseau demo_docker afin que traefik puisse voir les conteneurs de mon réseau
- demo_docker
networks:
demo_docker:
external: true
Ensuite, on va venir créer le fichier acme.json dans mon répertoire traefik et on va lui donner les droits 600
❯ touch acme.json
❯ chmod 600 acme.json
Concernant ma configuration de traefik, ça donne ça. [certificatesResolvers.sample.acme] me permettra de solliciter automatiquement la demande de certificat ssl auprès de let's encrypt.
# traefik.toml
[http.middlewares]
[http.middlewares.redirect.redirectscheme]
scheme = "https"
[providers.docker]
endpoint = "unix:///var/run/docker.sock"
watch = true
[entryPoints]
[entryPoints.web]
address = ":80"
[entryPoints.web-secure]
address = ":443"
[certificatesResolvers.sample.acme]
email = "votremail@mail.com"
storage = "acme.json"
caServer = "https://acme-v01.api.letsencrypt.org/directory"
[certificatesResolvers.sample.acme.httpChallenge]
entryPoint = "web"
Une fois que j'ai fait cela, je dois modifier le docker-compose-prod.yaml en rajoutant pour chacun de mes services une nouvelle clé "labels".
# docker-compose-prod.yaml
version: '3.8'
services:
app:
image: ${CONTAINER_REGISTRY}/app
restart: always
networks:
- demo_docker
environment:
- DB_DSN
- DB_USER
- DB_PASSWORD
labels:
- "traefik.enable=false"
nginx:
image: ${CONTAINER_REGISTRY}/nginx
restart: always
networks:
- demo_docker
depends_on:
- app
labels:
- traefik.http.routers.hello.rule=Host(`hello.chocteau.dev`)
- traefik.http.routers.hello.entrypoints=web
- traefik.http.routers.hello.middlewares=redirect@file
- traefik.http.routers.hello_ssl.rule=Host(`hello.chocteau.dev`)
- traefik.http.routers.hello_ssl.entrypoints=web-secure
- traefik.http.routers.hello_ssl.tls=true
- traefik.http.routers.hello_ssl.tls.certresolver=sample
networks:
demo_docker:
external:
name: demo_docker
Comme vous pouvez le constater, on n'expose plus le port 8080 pour le service nginx. A la place, on a définie des règles dans une clé labels.
Maintenant, on va redéployer notre application
❯ docker-compose --env-file .env.prod -f docker-compose-prod.yaml up -d --force-recreate
Puis, on démarre traefik ! Depuis notre serveur, on se rend simplement dans le répertoire traefik, puis on lance la commande docker-compose up -d
Et après, victoire ! Mon Hello World a son nom de domaine et en plus, il est sécurisé en SSL 🎉🎉
Je n'ai pas abordé dans ce post la notion de firewall, mais il est bien évident qu'en l'état actuel mon VPS n'est pas sécurisé pour être utilisé en prod. Il sera important de limiter les flux entrants aux ports 22, 80 et 443. Fail2ban peut être également très utile surtout si vous avez des users qui peuvent se connecter en SSH avec un mot de passe. Peut être un sujet pour un autre article.
J'espère que si vous n'étiez pas familier avec cette outil, cette série d'articles sur Docker vous a été utile. N'hésitez pas à me partager dans les commentaires vos trucs et astuces que je n'ai pas abordé 💬