Héberger un site dans un container
L’objectif est d’auto héberger un site web sur un VPS, dans un container Docker.
Prérequis
- Un VPS auquel on peut accéder en SSH avec les droits root.
- Un nom de domaine sur lequel on peut modifier le DNS.
Etape 1 : Installer Docker
Docker sera la couche de virtualisation qui permettra de lancer des containers.
Pour l’installer :
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
Etapes 2 : Portainer
Modification du DNS
Chez notre registrar, on fait met en place une entrée DNS de type A
pour un sous-domaine portainer
.
Exemple : portainer.mon-domaine.fr
Gestion de la redirection
- Sur notre VPS, on ajoute une configuration Apache pour notre sous domaine
portainer.mon-domaine.fr
dans/etc/apache2/sites-available
en y ajoutant un fichiermon-domaine_fr.conf
.
- Avec
certbot
, on se crée une signature « Let’s Encrypt » pour le site HTTPs. Un nouveau fichier/etc/apache2/sites-available/mon-domaine_fr-le-ssl.conf
est censé être créé. - On modifier le fichier
/etc/apache2/sites-available/mon-domaine_fr-le-ssl.conf
afin de gérer la redirection du sous domaineportainer
vers le container Docker :
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName portainer.mon-domaine.fr
ServerAlias portainer.mon-domaine.fr
SSLEngine on
SSLProxyEngine on
ProxyPreserveHost On
ProxyPass / https://127.0.0.1:9443/
ProxyPassReverse / https://127.0.0.1:9443/
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
SSLCertificateFile /etc/letsencrypt/live/portainer.mon-domaine.fr/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/portainer.mon-domaine.fr/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>
- On s’assure que la configuration est active :
sudo a2ensite mon-domaine_fr-le-ssl.conf
sudo systemctl restart apache2
A partir de là, le fait d’aller sur le site https://portainer.mon-domaine.fr
permettra d’accéder à notre container Portainer.
- On récupère les fichiers
/etc/letsencrypt/live/portainer.mon-domaine.fr/fullchain.pem
et/etc/letsencrypt/live/portainer.mon-domaine.fr/privkey.pem
dont on aura besoin par la suite.
Installation de Portainer
Pour se faciliter la gestion des containers Docker par la suite, on va installer Portainer (CE : Community Edition). Cette interface nous permettra de voir la liste des containers actifs et nous permettra de suivre leurs usages à distance.
- On crée un volume sur lequel les données de Portainer seront stockées :
docker volume create portainer_data
- On télécharge et installe l’instance du serveur Portainer.
Attention, contrairement à la documentation officielle, nous précisons ici que le port 9443 sur lequel l’interface sera exposée ne sera disponible que par 127.0.0.1, afin que l’interface ne soit pas accessible depuis son adresse IP publique.
docker run -d -p 8000:8000 -p 127.0.0.1:9443:9443 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:latest
Configuration de Portainer
- On se connecte à
https://portainer.mon-domaine.fr
. - On crée un mot de passe pour l’utilisateur « admin ». Attention, la création du mot de passe n’est disponible que pendant quelques minutes après le démarrage du container.
- Dans
Settings
>SSL certificate
, on renseigne les fichiersfullchain.pem
etprivkey.pem
afin de ne pas avoir d’erreur de certificat.
Etape 3 : Nouveau site
Structure et container
- On crée un répertoire
www/mon_site
qui aura la structure suivante :
www/
└── mon_site/
├── .env
├── docker-compose.yml
├── Dockerfile
└── src/
└── index.php
- Le fichier
.env
contiendra toutes les variables d’environnements dont on aura besoin. Par exemple :
PORT=8080
DB_LOGIN=Mon identifiant
PORT
sera le port sur lequel l’instance Docker tournera.DB_LOGIN
sera une variable d’environnement sur le serveur.
- Le fichier
Dockerfile
aura le contenu suivant :
FROM php:8.2-apache as base
afin de lui dire que l’image de base est un container qui contient PHP 8.2 et Apache.
- Le fichier
docker-compose.yml
aura le contenu suivant :
version: "3.9"
services:
php:
container_name: mon_site_php
image: php
restart: always
build:
context: .
dockerfile: Dockerfile
target: base
volumes:
- ./src:/var/www/html
environment:
- DB_LOGIN=${DB_LOGIN}
ports:
- "127.0.0.1:${PORT}:80"
L’élément volume
permet de faire le mapping sur le répertoire src
local vers /var/www/html
distant.
L’élément environment
permet de créer des variables d’environnements sur l’environnement distant.
L’élément ports
permet de dire que le port local pointe sur le port 80
distant.
- Le fichier
index.php
contient par exemple :
<?php
echo "Hello " . getenv("DB_LOGIN") . "!";
?>
- En se mettant dans le répertoire
mon_site
on démarre le container.
sudo docker compose up --build
- On vérifie dans Portainer que l’image est bien disponible et tourne correctement.
Redirection Apache
- On crée un un fichier
/etc/apache2/sites-available/mon-site.conf
:
<VirtualHost *:80>
ServerName www.mon-domaine.fr
ServerAlias www.mon-domaine.fr
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:8080/
ProxyPassReverse / http://127.0.0.1:8080/
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
- On ajoute le site :
sudo a2ensite mon-site.conf
sudo systemctl restart apache2
- On crée un certificat HTTPs avec
certbot
. Cela va créer un fichier/etc/apache2/sites-available/mon-site-le-ssl.conf
qui contiendra la configuration qui va bien.