Aller au contenu
Cheat Sheet
Docker

Héberger plusieurs sites dans des containers Docker

L’objectif est d’auto héberger plusieurs sites web sur un VPS, chacun dans leur container Docker, avec un Nginx Reverse Proxy lui même dans un Docker.

Nous allons voir comment héberger plusieurs sites web avec Docker. Notre architecture finale ressemblera à ça :

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.

Outils recommandés

  • lazydocker : un outil qui permet de monitorer Docker (les images, les networks, les containers en cours, …) et de faire des actions dessus de manière plus intuitive.
    https://github.com/jesseduffield/lazydocker
  • midnightcommander : un outil qui permet facilement de gérer ses fichier et qui a la particularité de pouvoir se connecter en SSH à un autre serveur. Pratique pour migrer des serveurs.
    https://doc.ubuntu-fr.org/midnight_commander

Etape 1 : Installer Docker / Docker compose

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

On créer un réseau spécifique qui servira à regrouper plusieurs images dans le même sous-réseau.

docker network create --subnet=172.18.0.0/16 webserver_network

Etapes 2 : Nging-reverse-proxy

Modification du DNS

Chez notre registrar, on fait met en place une entrée DNS de type A pour un domaine ou un sous-domaine qui pointe vers l’IP de notre serveur.
Par exemple cheatsheet.fr.

Image Docker Nginx

Notre reverse proxy Nginx aura besoin d’enregistrer des informations. Pour éviter qu’elles soient perdues entre chaque redémarrage, on va faire en sorte qu’elles soient stockées sur notre machine.

Dans un répertoire nginx-proxy-manager, on va créer un répertoire data et un répertoire letsencrypt qui seront liés au volume de l’image Docker.

Afin de lancer notre image Docker avec l’utilisateur www-data du groupe www-data, on va créer un fichier .env qui contiendra l’identifiant de l’utilisateur et du groupe qu’on souhaitera utiliser dans la configuration :

PUID=33
PGID=33

Généralement, l’utilisateur www-data est l’identifiant 33. Pour s’en assurer, on peut taper la commande :

less /etc/passwd

On crée un fichier docker-compose.yml avec le contenu suivant :

version: '3.8'
services:
  app:
    container_name: nginx-proxy-manager
    image: 'jc21/nginx-proxy-manager:latest'
    restart: unless-stopped
    ports:
      - '80:80' # Public HTTP Port
      - '443:443' # Public HTTPS Port
      - '81:81' # Admin Web Port
 
    environment:
      PUID: ${PUID}
      PGID: ${PGID}

      # Uncomment this if you want to change the location of
      # the SQLite DB file within the container
      # DB_SQLITE_FILE: "/data/database.sqlite"

      # Uncomment this if IPv6 is not enabled on your host
      # DISABLE_IPV6: 'true'

    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt

networks:
  default:
    name: webserver_network
    external: true

Explications :

container_name: nginx-proxy-manager : le nom qu’on souhaite donner au conteneur, pour le retrouver plus facilement.

image: 'jc21/nginx-proxy-manager:latest' : l’image Docker sur laquelle on va se baser. https://github.com/NginxProxyManager/nginx-proxy-manager

restart: unless-stopped : si l’image s’arrête, il faut qu’elle redémarre automatiquement, sauf si on l’a arrêtée volontairement.

ports:: on fait un mapping des ports 80 (http), 443 (https) et 81 (interface web de gestion de Nginx).

environment: on déclare les 2 variables d’environnement qui servent à déterminer l’utilisateur et le groupe.

DB_SQLITE_FILE: "/data/database.sqlite" : nom du fichier dans lequel on enregistre la base de données qui stocke la configuration de Nginx.

DISABLE_IPV6: 'true' : à définir lorsque notre serveur ne gère pas l’IPv6.

volumes: : on fait pointer le répertoire local ./data vers le répertoire /data du container, et le répertoire local ./letsencrypt vers le répertoire /etc/letsencrypt du container.

networks: : permet de dire que par défaut on utilise le réseau webserver_network qui est un réseau externe (celui créé plus haut).

On devrait avoir la structure suivante :

Workspaces/
└── nginx-proxy-manager/
├── .env
├── data/
├── docker-compose.yml
├── letsencrypt/

Démarrage du serveur

On démarre le serveur avec la commande :

docker compose up -d --build

Configuration du reverse-proxy

On peut accéder à l’interface de Nginx par son IP et le port 81.

Etape 3 : Nouveau site

Structure et container

  • On crée un répertoire Workspaces/mon_site qui aura la structure suivante :
Workspaces/
└── 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
    #depends_on:
    #  - db
    build:
      context: .
      dockerfile: Dockerfile
      target: base
    volumes:
      - ./src:/var/www/html
    environment:
      - DB_LOGIN=${DB_LOGIN}
    ports:
      - "127.0.0.1:${PORT}:80"
    networks:
      - webserver_network
      - internal_network

networks:
  webserver_network:
    name: webserver_network
    external: true
  internal_network:
    name: mysite_network
    driver: bridge

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.
L’élément networks permet de lier l’image à un réseau interne et un réseau externe.

Ajouter une base de données

Pour utiliser une base de données de type MySQL, on peut rajouter dans docker-compose.yml :

  db:
    container_name: database_db
    image: mysql:8.3
    restart: unless-stopped
    user: "${UID}:${GID}"
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
    #healthcheck:
    #  test: mysqladmin ping -h 127.0.0.1 -u $$MYSQL_USER --password=$$MYSQL_PASSWORD
    #  interval: 5s
    #  timeout: 10s
    #  retries: 10
    #  start_period: 5s
    volumes:
      - ./db_data:/var/lib/mysql
    networks:
        - internal_network

Pour utiliser une base de donnée de type PosgreSQL, on peut rajouter dans docker-compose.yml :

  db:
    container_name: mydatabase_db
    image: postgres
    restart: unless-stopped
    # set shared memory limit when using docker-compose
    shm_size: 128mb
    user: "${UID}:${GID}"
    environment:
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: ${POSTGRES_DB}
      POSTGRES_USER: ${POSTGRES_USER}
    #healthcheck:
    #  test: [ "CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}" ]
    #  interval: 5s
    #  timeout: 10s
    #  retries: 10
    #  start_period: 5s
    volumes:
      - ./db_data:/var/lib/postgresql/data
    networks:
      - internal_network

Pour utiliser une base de données de type MariaDB, on peut rajouter dans docker-compose.yml :

  db:
    container_name: database_db
    image: mariadb:latest
    restart: unless-stopped
    environment:
      PUID: ${UID}
      PGID: ${GID}
      MARIADB_ROOT_PASSWORD: ${MARIADB_ROOT_PASSWORD}
      MARIADB_DATABASE: ${MARIADB_DATABASE}
      MARIADB_USER: ${MARIADB_USER}
      MARIADB_PASSWORD: ${MARIADB_PASSWORD}
    volumes:
      - ./db_data:/var/lib/mysql
    networks:
      - internal_network

Ajouter une interface d’administration pour la base de données

Si on veut un PHPMyAdmin :

  phpmyadmin:
    container_name: famille-parfaite_myadmin
    depends_on:
      - db
    image: phpmyadmin:latest
    ports:
      - 8080:80
    restart: unless-stopped
    environment:
      PMA_HOST: db
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      UPLOAD_LIMIT: 1024M
      MAX_EXECUTION_TIME: 10800
    networks:
      - internal_network

Si on veut un Adminer :

  adminer:
    image: adminer
    restart: unless-stopped
    environment:
      ADMINER_DEFAULT_SERVER: db
    depends_on:
      - db
    ports:
      - 8080:8080
    networks:
      - internal_network

Contenu du site

  • 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

Etape 4 : Redirections Nginx-reverse-proxy

Maintenant que les sites sont opérationnels, il faut faire en sorte que le nom de domaine redirige sur la bonne instance Docker.
Pour cela, on s’authentifie sur l’instance Nginx-reverse-proxy en y accédant par son IP et le port 81.
Par exemple : http://123.45.67.89:81

A la première connexion, il faut renseigner une adresse email et un mot de passe fort.

Ensuite, il faut ajouter un « host ». Comme on ne connait pas forcément l’IP de notre container Docker dans le réseau « websote_network », on peut utiliser à la place le « hostname » que l’on a défini dans le fichier docker-compose.yml.

Il est possible de générer un certificat SSL avec Let’sEncrypt dans l’onglet « SSL ».

Fichiers d’exemple

Voici les archives complètes de Nginx et des exemples de sites :

nginx-reverse-proxyTélécharger
apache_php_postgresql_adminerTélécharger
apache_php_mysql_phpmyadminTélécharger
apache_php_mariadbTélécharger
Utiliser PHPMailer et OAuth2, sans utiliser Composer
Comment vérifier que mon client Torrent est bien derrière mon VPN ?
apache docker nginx server web

Articles similaires

ModuleNotFoundError: No module named ‘apt_pkg’
Docker prend trop de place…
Héberger un site dans un…
[Linux] Réparer une installation en…
Commandes Docker de base
Publier un site Flask sur…
[Debian] Mettre à jour vers…
[Synology] Installer IPKG sur DS214
Récupérer un MP3 depuis YouTube
[Linux] Rediriger vers un fichier…

Catégories

  • Android
  • Calibre
  • Docker
  • Excel
  • Git
  • Google Sheet
  • Knime
  • Linux
  • Logiciels
  • Matériel
  • Non classé
  • Notepad++
  • PHP
  • Power BI
  • Programmation
  • Python
  • Qlik
  • Service
  • Synology
  • Visual Studio Code
  • VSCode
  • Windows
  • Word
  • WordPress

Étiquettes

adb android apache audio calibre convertion css debian docker drivers excel fichiers firefox flask google grep html kobo linux manette markdown mp3 notepad++ office php pip portable privoxy python qlik qliksense qlikview realtek selenium synology tor venv vim virtualenv vscode web windows wordpress xargs youtube

Tags

adb android apache audio calibre convertion css debian docker drivers excel fichiers firefox flask google grep html kobo linux manette markdown mp3 notepad++ office php pip portable privoxy python qlik qliksense qlikview realtek selenium synology tor venv vim virtualenv vscode web windows wordpress xargs youtube
Thème par Colorlib Propulsé par WordPress