L’auteur a choisi United Nations Foundation pour recevoir un don dans le cadre du programme Write for Donations.
La version WordPress originale de ce tutoriel a été rédigée par Kathleen Juell.
Drupal est un système de gestion de contenu (CMS) écrit en PHP et distribué sous la licence publique générale GNU open-source. Drupal est utilisé à travers le monde par les particuliers et les organisations pour qui souhaitent propulser des sites gouvernementaux, des blogs personnels, des entreprises, etc. Ce qui rend Drupal unique par rapport aux autres frameworks CMS, c’est sa communauté croissante et son ensemble de fonctionnalités qui comprend notamment ses processus sécurisés, ses performances fiables, sa modularité et sa flexibilité d’adaptation.
Drupal nécessite l’installation de la pile LAMP (Linux, Apache, MySQL et PHP) ou LEMP (Linux, Nginx, MySQL et PHP). Cependant l’installation de chacun des composants est fastidieuse. Pour simplifier le processus d’installation de Drupal, nous pouvons utiliser des outils comme Docker et Docker Compose. Au cours de ce tutoriel, nous utiliserons des images Docker dans le cadre de l’installation des composants individuels dans les conteneurs Docker. En utilisant Docker Compose, nous pouvons définir et gérer plusieurs conteneurs de la base de données, l’application et la mise en réseau / communication entre eux.
Au cours de ce tutoriel, nous installerons Drupal à l’aide de Docker Compose afin de pouvoir profiter de la conteneurisation et déployer notre site Web Drupal sur des serveurs. Nous exécuterons les conteneurs d’une base de données MySQL, un serveur Web Nginx et Drupal. Nous sécuriserons également notre installation en obtenant des certificats TLS/SSL avec Let’s Encrypt pour le domaine que nous voulons associer à notre site. Enfin, nous configurerons un cron job pour renouveler nos certificats afin que notre domaine reste sécurisé.
Pour suivre ce tutoriel, nous aurons besoin de :
sudo
et un pare-feu actif. Pour savoir comment les configurer, veuillez consulter le présent Guide de configuration initiale du serveur.your_domain
. Vous pouvez en obtenir un gratuitement sur Freenom ou utiliser le registre de domaine de votre choix.your_domain
pointant sur l’adresse IP publique de votre serveur.www.your_domain
pointant sur l’adresse IP publique de votre serveur.Avant d’exécuter des conteneurs, nous devons définir la configuration de notre serveur Web Nginx. Notre fichier de configuration comprendra des blocs de localisation spécifiques à Drupal, ainsi qu’un bloc de localisation qui permettra de diriger les demandes de vérification de Let’s Encrypt vers le client Certbot et de renouveler les certificats automatiquement.
Tout d’abord, créons un répertoire de projet pour la configuration de notre Drupal que nous appellerons drupal
:
- mkdir drupal
Allez dans le répertoire nouvellement créé :
- cd drupal
Maintenant, nous pouvons créer un répertoire pour notre fichier de configuration :
- mkdir nginx-conf
Ouvrez le fichier avec nano ou votre éditeur de texte favori :
- nano nginx-conf/nginx.conf
Dans ce fichier, nous allons ajouter un bloc de serveur avec des directives pour le nom de notre serveur et la racine du document, ainsi que des blocs de localisation pour diriger la demande de certificats, le traitement PHP et les demandes d’actifs statiques du client Certbot.
Ajoutez le code suivant dans le fichier. Veillez à bien remplacer your_domain
par votre nom de domaine :
server {
listen 80;
listen [::]:80;
server_name your_domain www.your_domain;
index index.php index.html index.htm;
root /var/www/html;
location ~ /.well-known/acme-challenge {
allow all;
root /var/www/html;
}
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
rewrite ^/core/authorize.php/core/authorize.php(.*)$ /core/authorize.php$1;
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass drupal:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
location ~ /\.ht {
deny all;
}
location = /favicon.ico {
log_not_found off; access_log off;
}
location = /robots.txt {
log_not_found off; access_log off; allow all;
}
location ~* \.(css|gif|ico|jpeg|jpg|js|png)$ {
expires max;
log_not_found off;
}
}
Le bloc de serveur contient les informations suivantes :
Directives :
listen
: indique à Nginx d’écouter le port 80
, ce qui nous permettra d’utiliser le webroot plugin de Certbot pour nos demandes de certificat. Notez que nous n’incluons pas encore le port 443
- nous mettrons à jour notre configuration pour inclure SSL une fois que nous aurons réussi à obtenir nos certificats.
server_name
: permet de définir notre nom de serveur et le bloc de serveur qui doit être utilisé pour les requêtes à notre serveur. Veillez à bien remplacer your_domain
dans cette ligne avec votre propre nom de domaine.
index
: permet de définir les fichiers qui serviront d’index lors du traitement des requêtes vers notre serveur. Ici, nous avons modifié l’ordre de priorité par défaut, en plaçant index.php
devant index.html
afin que Nginx priorise les fichiers appelés index.php
lorsque cela est possible.
root
: permet de nommer le répertoire racine des demandes à notre serveur. Ce répertoire, /var/www/html
, est créé comme point de montage lorsque les instructions de notre Drupal Dockerfile procèdent à la construction. Ces instructions Dockerfile garantissent également à ce que les fichiers de la version Drupal soient bien remontés vers ce volume.
rewrite
: si l’expression régulière spécifiée (^/core/authorize.php/core/authorize.php(.*)$
) correspond à un URI de requête, l’URI est modifié comme spécifié dans la chaîne de remplacement (/core/authorize.php$1
).
Blocs de localisation :
location ~ /.well-known/acme-challenge
: ce bloc de localisation traitera les demandes du répertoire .well-known
, dans lequel Certbot placera un fichier temporaire pour valider que le DNS de notre domaine se résout sur notre serveur. Une fois cette configuration en place, le webroot plugin de Certbot nous permettra d’obtenir des certificats pour notre domaine.
location/
: dans ce bloc de localisation, nous utiliserons une directive try_files
pour rechercher les fichiers qui correspondent aux requêtes d’URI individuelles. Au lieu que l’état par défaut 404 Not Found
ne nous soit renvoyé, nous passerons au contrôle du fichier index.php
de Drupal avec les arguments de la requête.
location ~ \.php$
: ce bloc de localisation gérera le traitement PHP et enverra ces requêtes par procuration à notre conteneur drupal. Étant donné que notre image Drupal Docker sera basée sur l’image php:fpm
, nous inclurons également des options de configuration spécifiques au protocole FastCGI dans ce bloc. Nginx nécessite un processeur PHP indépendant pour les requêtes PHP : dans notre cas, ces requêtes seront traitées par le processeur php-fpm
inclus avec l’image php:fpm
. En outre, ce bloc de localisation contient des directives, des variables et des options spécifiques à FastCGI qui, par procuration, renverront les requêtes vers l’application Drupal exécutée dans notre conteneur Drupal, configureront l’index favori de l’URI de requête analysée et analyseront les requêtes d’URI.
location ~ /\.ht
: ce bloc traitera les fichiers .htaccess
car Nginx ne les présentera pas. La directive deny_all
veille à ce que les fichiers .htaccess
ne soient jamais présentés aux utilisateurs.
location = /favicon.ico, location = /robots.txt
: ces blocs veillent à que les requêtes adressées à /favicon.ico
et /robots.txt
ne soient pas enregistrées.
location ~* \.(css|gif|ico|jpeg|jpg|js|png)$
: ce bloc désactive la journalisation des requêtes d’actifs statiques et veillent à ce que ces actifs soient strictement mis en cache, car leur présentation est généralement coûteuse.
Pour plus d’informations sur le proxy FastCGI, consultez Présentation et implémentation du proxy FastCGI dans Nginx. Pour plus d’informations sur le serveur et les blocs de localisation, consultez Comprendre le serveur Nginx et les algorithmes de sélection des blocs de localisation.
Enregistrez et fermez le fichier lorsque vous avez terminé de le modifier.
Une fois Nginx configuré, vous pouvez commencer à créer des variables d’environnement afin de les transmettre à vos conteneurs d’application et de base de données au moment de l’exécution.
Notre application Drupal nécessite une base de données (MySQL, PostgresQL, etc.) dans laquelle elle pourra sauvegarder les informations liées au site. Au moment de l’exécution, le conteneur Drupal devra avoir accès à certain nombre de variables d’environnement afin d’accéder au conteneur de la base de données (MySQL). Ces variables contiennent des informations sensibles comme les informations d’identification de la base de données. Nous ne pouvons donc pas les exposer directement dans le fichier Docker Compose, le fichier principal qui contient les informations sur la façon dont nos conteneurs s’exécuteront.
Comme toujours, il est vivement recommandé de configurer les valeurs sensibles dans le fichier .env
et de restreindre sa circulation. Ainsi ces valeurs ne pourront être copiées dans nos référentiels de projet et être exposées publiquement.
Dans le répertoire principal du projet, ~/drupal
, créez un fichier que vous nommerez .env
, puis ouvrez-le :
- nano .env
Ajoutez les variables suivantes au fichier .env
et remplacez les sections en surbrillance par les données d’identification que vous souhaitez utiliser :
MYSQL_ROOT_PASSWORD=root_password
MYSQL_DATABASE=drupal
MYSQL_USER=drupal_database_user
MYSQL_PASSWORD=drupal_database_password
Le mot de passe du compte administratif racine MySQL a maintenant été ajouté, ainsi que notre nom d’utilisateur et le mot de passe préférés pour notre base de données d’application.
Notre fichier .env
contient des informations sensibles. Il est donc toujours recommandé de l’inclure dans les fichiers .gitignore
et .dockerignore
d’un projet afin qu’il ne soit pas ajouté à nos référentiels Git et à nos images Docker.
Si vous envisagez de travailler avec Git pour le contrôle de version, initialisez votre répertoire de travail actuel en tant que référentiel avec git init
:
- git init
Ouvrez le fichier .gitignore
:
- nano .gitignore
Ajoutez ce qui suit :
.env
Enregistrez et quittez le fichier.
De même, ouvrez le fichier .dockerignore
:
- nano .dockerignore
Ajoutez ensuite ce qui suit :
.env
.git
Enregistrez et quittez le fichier.
Maintenant que nous avons pris des mesures pour protéger nos données d’identification en tant que variables d’environnement, passons à la prochaine étape de configuration de nos services dans un fichier docker-compose.yml
.
Docker Compose est un outil qui permet de définir et d’exécuter des applications Docker multi-conteneurs. Nous devons définir un fichier YAML
pour configurer les services de notre application. Dans Docker Compose, un service est un conteneur en cours d’exécution et Compose nous permet de lier ces services avec des volumes et des réseaux partagés.
Nous allons créer différents conteneurs pour notre application, notre base de données et notre serveur Web Drupal. Parallèlement, nous allons également créer un conteneur pour exécuter Certbot et ainsi obtenir des certificats pour notre serveur web.
Créez un fichier docker-compose.yml
:
- nano docker-compose.yml
Ajoutez le code suivant afin de définir la version du fichier Compose et le service de base de données mysql
:
version: "3"
services:
mysql:
image: mysql:8.0
container_name: mysql
command: --default-authentication-plugin=mysql_native_password
restart: unless-stopped
env_file: .env
volumes:
- db-data:/var/lib/mysql
networks:
- internal
Parcourons ces étapes une par une ainsi que toutes les options de configuration du service mysql
:
image
: indique l’image qui sera utilisée / extraite pour créer le conteneur. Il est recommandé de toujours utiliser l’image avec la balise de version adaptée, à l’exclusion de la dernière
balise pour éviter tout conflit à venir. Pour plus d’informations sur les meilleures pratiques pour Dockerfile, consultez la documentation de Docker.
container_name
: permet de définir le nom du conteneur.
command
: permet d’ignorer la commande par défaut (instruction CMD) qui se trouve dans l’image. MySQL a pris en charge différents plugins d’authentification, mais mysql_native_password
est la méthode traditionnelle à utiliser pour procéder à l’authentification. Puisque PHP, et donc Drupal, ne prennent pas en charge la nouvelle authentification MySQL, nous devons définir --default-authentication-plugin=mysql_native_password
qui servira de mécanisme d’authentification par défaut.
restart
: permet de définir la politique de redémarrage du conteneur. La politique unless-stopped
permet de redémarrer un conteneur, à moins qu’il ne soit arrêté manuellement.
env_file
: permet d’ajouter les variables d’environnement à partir d’un fichier. Dans notre cas, les variables d’environnement seront lues à partir du fichier .env
défini à l’étape précédente.
volumes
: permet de faire remonter les chemins d’hôtes ou les volumes nommés, spécifiés comme sous-options vers un service. Nous allons faire remonter un volume nommé db-data
dans le répertoire /var/lib/mysql
sur le conteneur, où MySQL par défaut écrira ses fichiers de données.
networks
: permet de définir le réseau interne
auquel se joint notre service d’application. Nous allons définir les réseaux à la fin du fichier.
Maintenant que notre définition de service mysql
a été établie, nous allons ajouter la définition du service d’application drupal
à la fin du fichier :
...
drupal:
image: drupal:8.7.8-fpm-alpine
container_name: drupal
depends_on:
- mysql
restart: unless-stopped
networks:
- internal
- external
volumes:
- drupal-data:/var/www/html
Dans cette définition de service, nous allons nommer notre conteneur et établir une politique de redémarrage, comme nous l’avons fait avec le service mysql
. Nous allons également ajouter quelques options spécifiques à ce conteneur :
image
: ici, nous utilisons l’image 8.7.8-fpm-alpine
de Drupal. Cette image dispose du processeur php-fpm
dont notre serveur web Nginx a besoin pour gérer le traitement PHP. De plus, nous utilisons l’image alpine
, dérivée du projet Alpine Linux, qui réduira la taille de l’image dans son ensemble et qui est recommandée dans les meilleures pratiques Dockerfile. Drupal contient plusieurs versions d’images que vous devrez donc vérifier sur Dockerhub.
depends_on
: permet d’exprimer la dépendance entre les services. En définissant le service mysql
comme la dépendance de notre conteneur drupal
, nous aurons la garantie que notre conteneur drupal
sera créé après le conteneur mysql
et permettra à notre application de démarrer en douceur.
networks
: ici, nous avons ajouté ce conteneur au réseau externe
ainsi que sur le réseau interne
. Nous aurons ainsi la garantie que notre service mysql
ne sera accessible qu’à partir du conteneur drupal
via le réseau interne
, tout en veillant à ce que ce conteneur reste accessible aux autres conteneurs via le réseau externe
.
volumes
: nous faisons remonter un volume nommé drupal-data
au point de montage /var/www/html
créé par l’image de Drupal. En utilisant un volume ainsi nommé, nous pourront partager notre code d’application avec d’autres conteneurs.
Ensuite, une fois le service drupal
définit, ajoutons la définition du service Nginx :
...
webserver:
image: nginx:1.17.4-alpine
container_name: webserver
depends_on:
- drupal
restart: unless-stopped
ports:
- 80:80
volumes:
- drupal-data:/var/www/html
- ./nginx-conf:/etc/nginx/conf.d
- certbot-etc:/etc/letsencrypt
networks:
- external
Encore une fois, nous allons nommer notre conteneur et le rendre dépendant du conteneur Drupal dans l’ordre de démarrage. Nous allons également utiliser une image alpine, l’image 1.17.4-alpine
de Nginx.
Cette définition de service contient également les options suivantes :
ports
: expose le port 80
pour permettre l’activation des options de configuration que nous avons définies dans notre fichier nginx.conf
à l’étape 1.
volumes
: ici, nous allons définir le volume et le chemin d’hôte nommés :
drupal-data:/var/www/html
: permet de faire remonter notre code d’application Drupal dans le répertoire /var/www/html
que nous allons configurer comme la racine dans notre bloc serveur Nginx.
./nginx-conf:/etc/nginx/conf.d
: permet de faire remonter le répertoire de configuration de Nginx sur l’hôte dans le répertoire pertinent du conteneur, en veillant à ce que toutes les modifications apportées aux fichiers de l’hôte soient reflétées dans le conteneur.
certbot-etc:/etc/letsencrypt
: permet de faire remonter les certificats et les clés Let’s Encrypt de notre domaine dans le répertoire qui convient du conteneur.
networks
: nous avons défini le réseau externe
uniquement pour permettre la communication entre ce conteneur et le conteneur drupal
et non pas avec le conteneur mysql
.
Enfin, nous allons ajouter notre dernière définition de service pour le service certbot
. Veillez à bien remplacer sammy@your_domain
et your_domain
par votre courriel et votre nom de domaine :
...
certbot:
depends_on:
- webserver
image: certbot/certbot
container_name: certbot
volumes:
- certbot-etc:/etc/letsencrypt
- drupal-data:/var/www/html
command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --staging -d your_domain -d www.your_domain
Cette définition indique à Compose d’extraire l’image certbot/certbot
de Docker Hub. Elle utilise également les volumes nommés pour partager les ressources avec le conteneur Nginx, y compris les certificats de domaine et la clé dans certbot-etc
, ainsi que le code d’application dans drupal-data
.
Nous avons également utilisé depend_on
pour avoir la garantie que le conteneur certbot
sera démarré après l’exécution du service webserver
.
Nous n’avons spécifié aucun réseau
ici car ce conteneur ne communiquera avec aucun service sur le réseau. Cela permet uniquement d’ajouter les certificats de domaine et la clé, que nous avons fait remonter à l’aide des volumes nommés.
Nous avons également inclus l’option command
qui spécifie une sous-commande à exécuter avec la commande certbot
par défaut du conteneur. Le client Certbot prend en charge des plugins afin de pouvoir obtenir et installer des certificats. Nous allons utiliser le plugin webroot
pour obtenir un certificat en incluant certonly
et --webroot
sur la ligne de commande. Pour en savoir plus sur le plugin et les commandes supplémentaires, consultez la documentation officielle de Certbot.
Après avoir défini le service certbot
, vous pouvez ajouter les définitions du réseau et du volume :
...
networks:
external:
driver: bridge
internal:
driver: bridge
volumes:
drupal-data:
db-data:
certbot-etc:
La clé des réseaux
de niveau supérieur nous permet de spécifier les réseaux à créer. Se trouvant sur le même hôte de démon Docker, les réseaux
permettent la communication entre les services / conteneurs sur tous les ports. Nous avons défini deux réseaux, interne
et externe
, pour sécuriser la communication des services webserver
, drupal
et mysql
.
La clé volumes
permet de définir les volumes drupal-data
, db-data
, et certbot-etc
. Lorsque Docker crée des volumes, le contenu du volume est stocké dans un répertoire sur le système de fichiers hôte, /var/lib/docker/volumes/
, qui est géré par Docker. On peut ensuite faire remonter le contenu de chaque volume à partir de ce répertoire dans tout conteneur qui utilise le volume en question. De cette façon, il est possible de partager le code et les données entre les conteneurs.
Le fichier docker-compose.yml
terminé ressemblera à ceci :
version: "3"
services:
mysql:
image: mysql:8.0
container_name: mysql
command: --default-authentication-plugin=mysql_native_password
restart: unless-stopped
env_file: .env
volumes:
- db-data:/var/lib/mysql
networks:
- internal
drupal:
image: drupal:8.7.8-fpm-alpine
container_name: drupal
depends_on:
- mysql
restart: unless-stopped
networks:
- internal
- external
volumes:
- drupal-data:/var/www/html
webserver:
image: nginx:1.17.4-alpine
container_name: webserver
depends_on:
- drupal
restart: unless-stopped
ports:
- 80:80
volumes:
- drupal-data:/var/www/html
- ./nginx-conf:/etc/nginx/conf.d
- certbot-etc:/etc/letsencrypt
networks:
- external
certbot:
depends_on:
- webserver
image: certbot/certbot
container_name: certbot
volumes:
- certbot-etc:/etc/letsencrypt
- drupal-data:/var/www/html
command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --staging -d your_domain -d www.your_domain
networks:
external:
driver: bridge
internal:
driver: bridge
volumes:
drupal-data:
db-data:
certbot-etc:
Nous avons fini de définir nos services. Maintenant, nous pouvons procéder au démarrage du conteneur et tester nos requêtes de certificat.
Nous pouvons démarrer nos conteneurs avec la commande docker-compose up
, qui créera et exécutera nos conteneurs dans l’ordre que nous avons spécifié. Si nos requêtes de domaine aboutissent, l’état de sortie dans notre résultat sera correct et les certificats adaptés seront remontés dans le dossier /etc/letsencrypt/live
dans le conteneur du serveur Web.
Pour exécuter les conteneurs en arrière-plan, utilisez la commande docker-compose up
avec l’indicateur -d
:
- docker-compose up -d
Vous obtiendrez un résultat similaire confirmant que vos services ont bien été créés :
Output...
Creating mysql ... done
Creating drupal ... done
Creating webserver ... done
Creating certbot ... done
Vérifiez l’état des services en utilisant la commande docker-compose ps
:
- docker-compose ps
Nous verrons les services mysql
, drupal
et webserver
apparaître avec un State
de Up
, tandis que certbot
apparaîtra avec le message d’état 0
:
Output Name Command State Ports
--------------------------------------------------------------------------
certbot certbot certonly --webroot ... Exit 0
drupal docker-php-entrypoint php-fpm Up 9000/tcp
mysql docker-entrypoint.sh --def ... Up 3306/tcp, 33060/tcp
webserver nginx -g daemon off; Up 0.0.0.0:80->80/tcp
Si la colonne State
des services mysql
, drupal
, ou Webserver
indique un tout autre statut que Up
ou si le conteneur cerbot
indique un état de sortie autre que 0
, veillez à bien vérifier les journaux de service avec la commande docker-compose logs
:
- docker-compose logs service_name
Nous pouvons maintenant vérifier si nos certificats ont bien été remontés sur le conteneur webserver
à l’aide de la commande docker-compose exec
:
- docker-compose exec webserver ls -la /etc/letsencrypt/live
Cela donnera le résultat suivant :
Outputtotal 16
drwx------ 3 root root 4096 Oct 5 09:15 .
drwxr-xr-x 9 root root 4096 Oct 5 09:15 ..
-rw-r--r-- 1 root root 740 Oct 5 09:15 README
drwxr-xr-x 2 root root 4096 Oct 5 09:15 your_domain
Maintenant que tout fonctionne correctement, nous pouvons modifier notre définition de service certbot
pour supprimer l’indicateur --staging
.
Ouvrez le fichier docker-compose.yml
, accédez à la définition du service certbot
et remplacez l’indicateur --staging
dans l’option de commande par l’indicateur --force-renewal
, qui indiquera à Certbot que vous souhaitez demander un nouveau certificat avec les mêmes domaines que ceux d’un certificat existant. La définition certbot
mise à jour ressemblera à ceci :
...
certbot:
depends_on:
- webserver
image: certbot/certbot
container_name: certbot
volumes:
- certbot-etc:/etc/letsencrypt
- drupal-data:/var/www/html
command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --force-renewal -d your_domain -d www.your_domain
...
Nous devons ré-exécuter docker-compose up
pour recréer le conteneur certbot
. Nous allons également inclure l’option --no-deps
pour indiquer à Compose qu’il peut démarrer le service webserver
, puisqu’il est déjà en cours d’exécution :
- docker-compose up --force-recreate --no-deps certbot
Nous verrons un résultat indiquant que notre requête de certificat est probante :
OutputRecreating certbot ... done
Attaching to certbot
certbot | Saving debug log to /var/log/letsencrypt/letsencrypt.log
certbot | Plugins selected: Authenticator webroot, Installer None
certbot | Renewing an existing certificate
certbot | Performing the following challenges:
certbot | http-01 challenge for your_domain
certbot | http-01 challenge for www.your_domain
certbot | Using the webroot path /var/www/html for all unmatched domains.
certbot | Waiting for verification...
certbot | Cleaning up challenges
certbot | IMPORTANT NOTES:
certbot | - Congratulations! Your certificate and chain have been saved at:
certbot | /etc/letsencrypt/live/your_domain/fullchain.pem
certbot | Your key file has been saved at:
certbot | /etc/letsencrypt/live/your_domain/privkey.pem
certbot | Your cert will expire on 2020-01-03. To obtain a new or tweaked
certbot | version of this certificate in the future, simply run certbot
certbot | again. To non-interactively renew *all* of your certificates, run
certbot | "certbot renew"
certbot | - Your account credentials have been saved in your Certbot
certbot | configuration directory at /etc/letsencrypt. You should make a
certbot | secure backup of this folder now. This configuration directory will
certbot | also contain certificates and private keys obtained by Certbot so
certbot | making regular backups of this folder is ideal.
certbot | - If you like Certbot, please consider supporting our work by:
certbot |
certbot | Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
certbot | Donating to EFF: https://eff.org/donate-le
certbot |
certbot exited with code 0
Maintenant que nous avons réussi à générer nos certificats, nous pouvons mettre à jour notre configuration Nginx pour inclure SSL.
Après avoir installé les certificats SSL dans Nginx, nous devrons rediriger toutes les requêtes HTTP vers HTTPS. Nous devrons également spécifier notre certificat SSL ainsi que les emplacements clés et ajouter des paramètres de sécurité et des en-têtes.
Puisque vous allez recréer le service webserver
pour inclure ces ajouts, vous pouvez l’arrêter maintenant :
- docker-compose stop webserver
Cela donnera le résultat suivant :
OutputStopping webserver ... done
Ensuite, nous allons supprimer le fichier de configuration Nginx que nous avons créé précédemment :
- rm nginx-conf/nginx.conf
Ouvrez une autre version du fichier :
- nano nginx-conf/nginx.conf
Ajoutez le code suivant au fichier pour rediriger HTTP vers HTTPS et pour ajouter les identifiants, les protocoles et les en-têtes de sécurité SSL. N’oubliez pas de remplacer your_domain
par votre domaine :
server {
listen 80;
listen [::]:80;
server_name your_domain www.your_domain;
location ~ /.well-known/acme-challenge {
allow all;
root /var/www/html;
}
location / {
rewrite ^ https://$host$request_uri? permanent;
}
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name your_domain www.your_domain;
index index.php index.html index.htm;
root /var/www/html;
server_tokens off;
ssl_certificate /etc/letsencrypt/live/your_domain/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your_domain/privkey.pem;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
rewrite ^/core/authorize.php/core/authorize.php(.*)$ /core/authorize.php$1;
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass drupal:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
location ~ /\.ht {
deny all;
}
location = /favicon.ico {
log_not_found off; access_log off;
}
location = /robots.txt {
log_not_found off; access_log off; allow all;
}
location ~* \.(css|gif|ico|jpeg|jpg|js|png)$ {
expires max;
log_not_found off;
}
}
Le bloc serveur HTTP spécifie le plugin webroot pour les demandes de renouvellement Certbot vers le répertoire .well-known/acme-challenge
. Il comprend également une directive rewrite
qui dirige les requêtes HTTP envoyées au répertoire racine vers HTTPS.
Le bloc serveur HTTPS active ssl
et http2
. Pour en savoir plus sur la façon dont HTTP/2 agit sur les protocoles HTTP et les avantages que cela peut avoir pour les performances du site Web, veuillez consulter l’introduction à Comment configurer Nginx avec la prise en charge HTTP/2 sur Ubuntu 18.04.
Ces blocs activent SSL, car nous avons inclus notre certificat SSL et nos emplacements clés ainsi que les en-têtes recommandés. Ces en-têtes nous permettront d’obtenir une note A sur les sites de test du serveur SSL Labs et Security Headers.
Nos directives root
et index
se trouvent également dans ce bloc, tout comme le reste des blocs de localisation spécifiques à Drupal abordés à l’étape 1.
Enregistrez et fermez le fichier de configuration Nginx mis à jour.
Avant de recréer le conteneur webserver
, nous devrons ajouter un mappage de port 443
à notre définition de service webserver
car nous avons activé les certificats SSL.
Ouvrez le fichier docker-compose.yml
:
- nano docker-compose.yml
Apportez les modifications suivantes dans la définition du service webserver
:
...
webserver:
image: nginx:1.17.4-alpine
container_name: webserver
depends_on:
- drupal
restart: unless-stopped
ports:
- 80:80
- 443:443
volumes:
- drupal-data:/var/www/html
- ./nginx-conf:/etc/nginx/conf.d
- certbot-etc:/etc/letsencrypt
networks:
- external
...
Une fois les certificats SSL activés, notre docker-compose.yml
ressemblera à ceci :
version: "3"
services:
mysql:
image: mysql:8.0
container_name: mysql
command: --default-authentication-plugin=mysql_native_password
restart: unless-stopped
env_file: .env
volumes:
- db-data:/var/lib/mysql
networks:
- internal
drupal:
image: drupal:8.7.8-fpm-alpine
container_name: drupal
depends_on:
- mysql
restart: unless-stopped
networks:
- internal
- external
volumes:
- drupal-data:/var/www/html
webserver:
image: nginx:1.17.4-alpine
container_name: webserver
depends_on:
- drupal
restart: unless-stopped
ports:
- 80:80
- 443:443
volumes:
- drupal-data:/var/www/html
- ./nginx-conf:/etc/nginx/conf.d
- certbot-etc:/etc/letsencrypt
networks:
- external
certbot:
depends_on:
- webserver
image: certbot/certbot
container_name: certbot
volumes:
- certbot-etc:/etc/letsencrypt
- drupal-data:/var/www/html
command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --force-renewal -d your_domain -d www.your_domain
networks:
external:
driver: bridge
internal:
driver: bridge
volumes:
drupal-data:
db-data:
certbot-etc:
Enregistrez et fermez le fichier. Recréons le service webserver
avec notre configuration mise à jour :
- docker-compose up -d --force-recreate --no-deps webserver
Cela donnera le résultat suivant :
OutputRecreating webserver ... done
Vérifiez les services avec docker-compose ps
:
- docker-compose ps
Nous verrons les services mysql
, drupal
et webserver
avec l’état Up
tandis que certbot
sera fermé avec un message d’état 0
:
Output Name Command State Ports
--------------------------------------------------------------------------
certbot certbot certonly --webroot ... Exit 0
drupal docker-php-entrypoint php-fpm Up 9000/tcp
mysql docker-entrypoint.sh --def ... Up 3306/tcp, 33060/tcp
webserver nginx -g daemon off; Up 0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
Maintenant, tous nos services fonctionnent et nous sommes prêts à passer à l’installation de Drupal via l’interface Web.
Terminons l’installation via l’interface Web de Drupal.
Dans un navigateur Web, accédez au domaine du serveur. N’oubliez pas de remplacer your_domain
ici par votre nom de domaine :
https://your_domain
Sélectionnez la langue que vous souhaitez utiliser :
Cliquez sur Save and continue. Nous atterrirons sur la page Installation profile. Drupal est composé de plusieurs profils, alors sélectionnez le profil Standard et cliquez sur Save and continue.
Une fois le profil sélectionné, nous allons passer à la page Database configuration. Sélectionnez le type de base de données MySQL, MariaDB, Percona Server or equivalent. Ensuite, saisissez les valeurs Database name, username et password avec les valeurs correspondantes de MYSQL_DATABASE
, MYSQL_USER
et MYSQL_PASSWORD
respectivement définies dans le fichier .env
à l’étape 2. Cliquez sur Advanced Options et configurez la valeur Host sur le nom du conteneur de service mysql
. Cliquez sur Save and continue.
Une fois la base de données configurée, l’installation des modules et des thèmes par défaut de Drupal commencera :
Une fois le site installé, nous atterrirons sur la page de configuration du site Drupal pour configurer le nom du site, l’e-mail, le nom d’utilisateur, le mot de passe et les paramètres régionaux. Complétez les informations et cliquez sur Save and continue :
Après avoir cliqué sur Save and continue, nous pouvons voir la page Welcome to Drupal, qui montre que notre site Drupal est opérationnel.
Maintenant que notre installation de Drupal est terminée, nous devons nous assurer que nos certificats SSL se renouvelleront automatiquement.
Les certificats Let’s Encrypt sont valables pendant 90 jours. Nous devons donc mettre en place un processus de renouvellement automatisé afin qu’ils ne puissent devenir caducs. Pour ce faire, vous pouvez créer une tâche avec l’utilitaire de planification cron
. Dans ce cas, nous allons créer une tâche cron
qui exécutera périodiquement un script qui permettra de renouveler nos certificats et de recharger notre configuration Nginx.
Créons le fichier ssl_renew.sh
pour renouveler nos certificats :
- nano ssl_renew.sh
Ajoutez le code suivant. N’oubliez pas de remplacer le nom du répertoire par votre propre non-root user :
#!/bin/bash
cd /home/sammy/drupal/
/usr/local/bin/docker-compose -f docker-compose.yml run certbot renew --dry-run && \
/usr/local/bin/docker-compose -f docker-compose.yml kill -s SIGHUP webserver
Ce script se transforme en répertoire de projet ~/drupal
et exécute les commandes docker-compose
suivantes.
docker-compose run
: permet de démarrer un conteneur certbot
et de supprimer la command
fournie dans notre définition de service certbot
. Au lieu d’utiliser la sous-commande certonly
, nous utilisons ici la sous-commande renew
, qui renouvellera les certificats qui sont sur le point d’expirer. Dans cet exemple, nous avons inclus l’option --dry-run
pour tester notre script.
docker-compose kill
: permet d’envoyer un signal SIGHUP
au conteneur webserver
pour recharger la configuration Nginx.
Fermez le fichier et rendez-le exécutable en exécutant la commande suivante :
- sudo chmod +x ssl_renew.sh
Ensuite, ouvrez le fichier crontab root
pour exécuter le script de renouvellement à un intervalle spécifié :
- sudo crontab -e
Si vous éditez ce fichier pour la première fois, vous sevrez invité à choisir un éditeur de texte pour ouvrir le fichier :
Outputno crontab for root - using an empty one
Select an editor. To change later, run 'select-editor'.
1. /bin/nano
2. /usr/bin/vim.basic
3. /usr/bin/vim.tiny
4. /bin/ed
Choose 1-4 [1]:
...
À la fin du fichier, ajoutez la ligne suivante, en remplaçant sammy
par votre nom d’utilisateur :
...
*/5 * * * * /home/sammy/drupal/ssl_renew.sh >> /var/log/cron.log 2>&1
L’intervalle de la tâche sera ainsi configurée à toutes les cinq minutes, afin que nous puissions tester si notre requête de renouvellement a bien fonctionné comme prévu. Nous avons également créé un fichier journal, cron.log
, pour enregistrer les résultats pertinents de la tâche.
Après cinq minutes, utilisez la commande tail
pour vérifier cron.log
et voir si la demande de renouvellement s’est bien exécutée ou pas :
- tail -f /var/log/cron.log
Vous verrez un résultat confirmant que qu’un renouvellement a bien été exécuté :
Output** DRY RUN: simulating 'certbot renew' close to cert expiry
** (The test certificates below have not been saved.)
Congratulations, all renewals succeeded. The following certs have been renewed:
/etc/letsencrypt/live/your_domain/fullchain.pem (success)
** DRY RUN: simulating 'certbot renew' close to cert expiry
** (The test certificates above have not been saved.)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Appuyez sur CTRL+C
pour quitter le processus de tail
.
Nous pouvons maintenant modifier le fichier crontab pour que le script soit exécuté tous les 2 jours de la semaine à 2 heures du matin. Remplacez la dernière ligne de la crontab par :
...
* 2 * * 2 /home/sammy/drupal/ssl_renew.sh >> /var/log/cron.log 2>&1
Quittez et enregistrez le fichier.
Supprimons maintenant l’option --dry-run
du script ssl_renew.sh
. Tout d’abord, ouvrez-le :
- nano ssl_renew.sh
Ensuite, remplacez le contenu par ce qui suit :
#!/bin/bash
cd /home/sammy/drupal/
/usr/local/bin/docker-compose -f docker-compose.yml run certbot renew && \
/usr/local/bin/docker-compose -f docker-compose.yml kill -s SIGHUP webserver
Notre tâche cron
se chargera désormais de l’expiration de nos certificats SSL en les renouvelant au moment voulu.
Dans ce didacticiel, nous avons utilisé Docker Compose pour créer une installation Drupal avec un serveur Web Nginx. Dans le cadre de ce processus, nous avons obtenu des certificats TLS SSL pour le domaine que nous voulions associer à notre site Drupal, et nous avons créé une tâche cron pour renouveler ces certificats au besoin.
Si vous souhaitez en savoir plus sur Docker, consultez notre page thématique consacrée à Docker.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!