Files
vps-docs/hestiacp/chapitres/11-docker.md
Zana 2e18724685 Ajout du guide PDF HestiaCP réutilisable (HestiaCP 1.10.4)
- 14 chapitres + annexe en Markdown (chapitres/), 99 étapes
- Générateur WeasyPrint (build/build.py) : PDF générique ou
  personnalisé via --vars fichier.conf
- PDF générique + PDF personnalisé srv1.skglobalinstitute.com
- Commandes v-* vérifiées contre le code source HestiaCP 1.10.4
- 03-bis-hestiacp.md pointe vers le nouveau guide

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018J2PsVQ28oW4xEkWJpcU9G
2026-09-10 20:01:59 +02:00

7.7 KiB
Raw Blame History

Docker et applications en conteneurs

Docker fait tourner des applications prêtes à l'emploi : Portainer, Uptime Kuma, Gitea, Vaultwarden… Chaque conteneur écoute uniquement sur 127.0.0.1, et Nginx de HestiaCP le publie sur un sous-domaine avec un certificat Let's Encrypt.

[!DANGER] Docker contourne le pare-feu Un port publié par Docker (-p 9000:9000) passe avant le pare-feu de HestiaCP et devient accessible depuis Internet. Publiez toujours sur 127.0.0.1: ; la configuration ci-dessous l'impose par défaut.

Installer Docker (dépôt officiel)

Ces commandes viennent de la documentation officielle de Docker pour Ubuntu :

sudo apt update
sudo apt install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF

sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

[!CHECK] sudo docker run --rm hello-world affiche Hello from Docker!, et docker compose version affiche une version 2.x ou plus.

Configurer Docker : localhost et rotation des journaux

Ce fichier fait publier les ports sur 127.0.0.1 par défaut, et limite la taille des journaux des conteneurs, qui peuvent sinon remplir le disque :

sudo tee /etc/docker/daemon.json > /dev/null << 'EOF'
{
  "ip": "127.0.0.1",
  "log-driver": "json-file",
  "log-opts": { "max-size": "10m", "max-file": "3" }
}
EOF
sudo systemctl restart docker
sudo systemctl enable docker containerd

Autorisez votre utilisateur à utiliser Docker sans sudo, puis déconnectez-vous et reconnectez-vous :

sudo usermod -aG docker {{USER}}

Warning

Le groupe docker donne des droits équivalents à root. Ne l'accordez qu'à {{USER}}, jamais à {{CLIENT}}.

[!NOTE] Pare-feu HestiaCP et Docker v-update-firewall ne touche pas aux règles de Docker. En revanche, sudo systemctl restart hestia-iptables recharge un ancien instantané des règles : lancez sudo systemctl restart docker juste après.

Créer le générateur de modèles de proxy

HestiaCP publie un site à l'aide de modèles Nginx. Ce petit script crée un modèle proxy-<port> qui redirige un domaine vers 127.0.0.1:<port>. Il gère le HTTPS forcé, HSTS, Let's Encrypt et les WebSockets.

D'abord, la variable Nginx nécessaire aux WebSockets :

sudo tee /etc/nginx/conf.d/websocket-map.conf > /dev/null << 'EOF'
map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}
EOF
sudo nginx -t && sudo systemctl reload nginx

Puis le générateur :

sudo tee /usr/local/sbin/hestia-proxy-tpl > /dev/null << 'SCRIPT'
#!/bin/bash
# Usage : hestia-proxy-tpl PORT  -> crée le modèle proxy Nginx "proxy-PORT"
set -euo pipefail
PORT="${1:?Usage : hestia-proxy-tpl PORT}"
[[ "$PORT" =~ ^[0-9]{2,5}$ ]] || { echo "Port invalide : $PORT"; exit 1; }
DIR=/usr/local/hestia/data/templates/web/nginx
NAME="proxy-$PORT"

LOCATION='
	location / {
		proxy_pass         http://127.0.0.1:__PORT__;
		proxy_http_version 1.1;
		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;
		proxy_set_header   X-Forwarded-Host  $host;
		proxy_set_header   Upgrade           $http_upgrade;
		proxy_set_header   Connection        $connection_upgrade;
		proxy_read_timeout 3600s;
		proxy_send_timeout 3600s;
		client_max_body_size 512m;
	}

	location /error/ {
		alias %home%/%user%/web/%domain%/document_errors/;
	}
'

cat > "$DIR/$NAME.tpl" << EOF
# Modèle généré par hestia-proxy-tpl : proxy vers 127.0.0.1:__PORT__
server {
	listen      %ip%:%proxy_port%;
	server_name %domain_idn% %alias_idn%;
	access_log  /var/log/%web_system%/domains/%domain%.log combined;
	error_log   /var/log/%web_system%/domains/%domain%.error.log error;

	include %home%/%user%/conf/web/%domain%/nginx.forcessl.conf*;
$LOCATION
	include %home%/%user%/conf/web/%domain%/nginx.conf_*;
}
EOF

cat > "$DIR/$NAME.stpl" << EOF
# Modèle généré par hestia-proxy-tpl : proxy vers 127.0.0.1:__PORT__
server {
	listen      %ip%:%proxy_ssl_port% ssl;
	server_name %domain_idn% %alias_idn%;
	access_log  /var/log/%web_system%/domains/%domain%.log combined;
	error_log   /var/log/%web_system%/domains/%domain%.error.log error;

	ssl_certificate     %ssl_pem%;
	ssl_certificate_key %ssl_key%;

	if (\$anti_replay = 307) { return 307 https://\$host\$request_uri; }
	if (\$anti_replay = 425) { return 425; }

	include %home%/%user%/conf/web/%domain%/nginx.hsts.conf*;
$LOCATION
	include %home%/%user%/conf/web/%domain%/nginx.ssl.conf_*;
}
EOF

sed -i "s/__PORT__/$PORT/g" "$DIR/$NAME.tpl" "$DIR/$NAME.stpl"
chmod 644 "$DIR/$NAME.tpl" "$DIR/$NAME.stpl"
echo "Modèle $NAME créé."
SCRIPT
sudo chmod 750 /usr/local/sbin/hestia-proxy-tpl

Note

Les modèles portent des noms personnels (proxy-9000…) : les mises à jour de HestiaCP ne les écrasent pas. Ne modifiez jamais les modèles default.

Publier une application : la méthode

Pour chaque application, le même schéma en 5 commandes. Exemple : un conteneur sur le port PORT, publié sur appli.{{DOMAINE}}.

sudo hestia-proxy-tpl PORT
sudo v-add-dns-record {{CLIENT}} {{DOMAINE}} appli A {{IP}}
sudo v-add-web-domain {{CLIENT}} appli.{{DOMAINE}}
sudo v-change-web-domain-proxy-tpl {{CLIENT}} appli.{{DOMAINE}} proxy-PORT
sudo v-add-letsencrypt-domain {{CLIENT}} appli.{{DOMAINE}}
sudo v-add-web-domain-ssl-force {{CLIENT}} appli.{{DOMAINE}}

Installer Portainer (gestion de Docker)

Portainer est une interface web pour gérer vos conteneurs. On utilise son port HTTP 9000, uniquement sur localhost, derrière le proxy HTTPS :

docker volume create portainer_data
docker run -d --name portainer --restart=always \
  -p 127.0.0.1:9000:9000 \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v portainer_data:/data \
  portainer/portainer-ce:lts

Publiez-le sur portainer.{{DOMAINE}} :

sudo hestia-proxy-tpl 9000
sudo v-add-dns-record {{CLIENT}} {{DOMAINE}} portainer A {{IP}}
sudo v-add-web-domain {{CLIENT}} portainer.{{DOMAINE}}
sudo v-change-web-domain-proxy-tpl {{CLIENT}} portainer.{{DOMAINE}} proxy-9000
sudo v-add-letsencrypt-domain {{CLIENT}} portainer.{{DOMAINE}}
sudo v-add-web-domain-ssl-force {{CLIENT}} portainer.{{DOMAINE}}

[!WARNING] Créez le compte tout de suite Ouvrez https://portainer.{{DOMAINE}} dans les 5 minutes et créez le compte administrateur avec un mot de passe fort. Passé ce délai, Portainer se verrouille par sécurité : relancez-le avec docker restart portainer.

[!CHECK] ss -tlnp | grep 9000 montre 127.0.0.1:9000 (et non 0.0.0.0:9000), et https://portainer.{{DOMAINE}} affiche Portainer avec un cadenas valide.

Utiliser Docker Compose pour les autres applications

Pour une application décrite par un compose.yaml, placez-la dans /opt/<appli>/ et publiez toujours ses ports sur 127.0.0.1 :

services:
  appli:
    image: editeur/appli:version
    restart: unless-stopped
    ports:
      - "127.0.0.1:8080:8080"
    volumes:
      - ./data:/data
cd /opt/appli && docker compose up -d

Suivez ensuite la méthode ci-dessus avec le port 8080.

[!TIP] Mettre à jour un conteneur Avec Compose : docker compose pull && docker compose up -d. Portainer propose aussi un bouton Recreate › Pull latest image.