Portainer - administration des conteneurs Docker
Portainer CE est une application gratuite et open source destinée à simplifier l’administration des conteneurs Docker et des environnements basés sur des micro-services. Cette solution d’administration accessible à partir d’un navigateur Web se veut à la fois pratique et conviviale. Au-delà de la présentation de cette solution, cet article explique comment installer Portainer et comment l’utiliser pour administrer ses conteneurs Docker
- Administration via interface Web
- Gestion de plusieurs environnements (Docker Standalone, Docker Swarm, Kubernetes, etc.)
- Déploiement d’applications via des stacks Docker Compose et des modèles
- Gestion complète des conteneurs Docker : containers, images, volumes, networks, etc.
- Visualisation précise de l’état des ressources : CPU, RAM, stockage, statuts des conteneurs
- Actions quotidiennes sur les conteneurs : démarrer, arrêter, redémarrer, logs, etc.
- Éditeur de fichiers Docker Compose intégré
- Gestion des utilisateurs, des groupes et des équipes
- Gestion des registres d’images, avec l’intégration native du Docker Hub
Portainer central
docker-compose
docker-compose.yml (Portainer central) — utilise vos certificats et expose uniquement HTTPS 9443 via nginx reverse proxy (Portainer écoute en interne sur 9443) :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
version: "3.8"
services:
portainer:
image: portainer/portainer-ce:latest
container_name: portainer
command: -H unix:///var/run/docker.sock
volumes:
- portainer_data:/data
- /var/run/docker.sock:/var/run/docker.sock
restart: always
nginx:
image: nginx:stable
container_name: portainer_nginx
ports:
- "443:443"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d:ro
- /etc/ssl/private/portainer.home.arpa.crt:/etc/ssl/certs/portainer.crt:ro
- /etc/ssl/private/portainer.home.arpa.key:/etc/ssl/private/portainer.key:ro
depends_on:
- portainer
restart: always
volumes:
portainer_data:
Lancez votre stack
1
docker compose up -d
Proxy nginx
nginx site config (/etc/nginx/conf.d/portainer.home.arpa.conf)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
server {
listen 443 ssl;
server_name portainer.home.arpa;
ssl_certificate /etc/ssl/certs/portainer.crt;
ssl_certificate_key /etc/ssl/private/portainer.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://portainer:9443;
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_http_version 1.1;
proxy_set_header Connection "";
proxy_read_timeout 90;
}
}
Recharger nginx
1
sudo systemctl reload nginx
Connexion
Ouvrir l’UI https://portainer.home.arpa, créez l’admin et mot de passe.

Authentification OAuth
Settings –> Authentication: OAuth
Authelia - Configuration client portainer
Générer un client_secret via la commande suivante :
1
2
3
authelia crypto hash generate pbkdf2 --variant sha512 --random --random.length 72 --random.charset rfc3986
La commande précédente renvoie 2 lignes
1
2
3
4
5
Random Password: -G3xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Digest: $pbkdf2-sha512xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
⚠️ Veuillez noter le mot de passe en clair (
Random Password) ainsi que le hachage $pbkdf2 (Digest) du mot de passe pour une utilisation ultérieure.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
clients:
- client_id: 'portainer'
client_name: 'Portainer'
client_secret: '$pbkdf2-sha512$310000$c8p78n7pUMln0jzvd4aK4Q$JNRBzwAo0ek5qKn50cFzzvE9RXV88h1wJn5KGiHrD0YKtZaR/nCb2CJPOsKaPK0hjf.9yHxzQGZziziccp6Yng' # The digest of 'insecure_secret'.
public: false
authorization_policy: 'two_factor'
require_pkce: false
pkce_challenge_method: ''
redirect_uris:
- 'https://portainer.home.arpa'
scopes:
- 'openid'
- 'profile'
- 'groups'
- 'email'
response_types:
- 'code'
grant_types:
- 'authorization_code'
access_token_signed_response_alg: 'none'
userinfo_signed_response_alg: 'none'
token_endpoint_auth_method: 'client_secret_post'
Portainer - OAuth
Pour configurer Portainer pour utiliser Authelia en tant que fournisseur OpenID Connect 1.0, utilisez les instructions suivantes:
Settings –> Authentication –> Authentication Method: OAuth
- Provider:
Custom - Automatic User Provision: Enable if you want users to automatically be created in Portainer.
- Client ID:
portainer - Client Secret:
insecure_secret - Authorization URL:
https://auth.rnmkcy.eu/api/oidc/authorization - Access Token URL:
https://auth.rnmkcy.eu/api/oidc/token - Resource URL:
https://auth.rnmkcy.eu/api/oidc/userinfo - Redirect URL:
https://portainer.home.arpa - User Identifier:
preferred_username - Scopes:
openid profile groups email - Auth Style:
In Params
Créer un utilisateur qui est reconnu par Authelia OIDC (pour info les utilisateurs Authelia sont gérés par un serveur LLDAP)

Connexion via OAuth
Déploiement des agents portainer
Manuellement
Si vous avez plusieurs machines qui servent à héberger vos conteneurs, sachez qu’il est possible de contrôler Docker sur celles-ci depuis une interface unique, sans avoir besoin de déployer Portainer sur chacune.
Il faudra bien entendu déployer un composant sur chaque machine, mais uniquement un conteneur Portainer Agent, plus léger.
Voici la commande à utiliser pour lancer cet agent :
1
docker run -d -p 9001:9001 --name portainer_agent --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v /var/lib/docker/volumes:/var/lib/docker/volumes portainer/agent
Ou avec une stack docker compose :
1
2
3
4
5
6
7
8
9
10
11
12
services:
portainer-agent:
container_name: portainer_agent
image: portainer/agent
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /var/lib/docker/volumes:/var/lib/docker/volumes
labels:
- com.centurylinklabs.watchtower.enable=true
ports:
- 9001:9001
restart: always
Auto via script
script prêt à l’emploi qui lit votre fichier CSV (format NAME;USER,IP,PORT;SSH_KEY), déploie le Portainer Agent sur chaque hôte en utilisant la clé SSH correspondante, et vérifie l’état. Le script gère clés différentes par hôte et ports personnalisés.
Création fichier hosts.csv avec une ligne par hôte
cwwk;yick,192.168.0.205,55205;$HOME/.ssh/yick-ed25519
alpine02;rad,192.168.0.222,55222;$HOME/.ssh/pvm-alpine02
alpine03;alpi,192.168.0.223,55223;$HOME/.ssh/pvm-alpine03
le script fonctionne pour Debian et Alpine dans la majorité des cas, mais quelques ajustements/ vérifications sont nécessaires car les images et environnements peuvent différer. Résumé des points à couvrir et version adaptée du script qui gère Debian/Alpine (teste la présence de docker, utilise sudo si nécessaire, installe Docker Engine si absent — optionnel).
Choses à vérifier/adapter par hôte
- Présence de Docker (docker CLI & daemon). Si absent, le script peut proposer d’installer Docker (diffère Debian vs Alpine).
- Si l’utilisateur SSH nécessite sudo pour exécuter docker, exécuter docker via sudo (et s’assurer que sudo n’exige pas de mot de passe).
- Sur Alpine, le binaire docker peut être fourni par package docker (apk add docker) et le service docker doit être démarré (service docker start) — parfois l’install diffère.
- Présence de firewall/ports (9001 exposé localement). Le script publie 9001:9001 sur l’hôte, ce qui est standard.
- Permissions du socket /var/run/docker.sock (l’utilisateur doit pouvoir l’utiliser ou utiliser sudo).
Script amélioré (gère Debian/Alpine, vérifie docker, option d’install, support sudo)
- Sauvegardez en
deploy_agents_flexible.shet rendez exécutable.
Script deploy_agents_flexible.sh (placez à côté de hosts.csv, rendez exécutable)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#!/usr/bin/env bash
set -euo pipefail
HOSTS_FILE="${1:-hosts.csv}"
AGENT_IMAGE="${AGENT_IMAGE:-portainer/agent:latest}"
TMPDIR="${TMPDIR:-/tmp}"
SSH_OPTS="-o StrictHostKeyChecking=accept-new -o BatchMode=yes -o ConnectTimeout=10"
INSTALL_IF_MISSING="${INSTALL_IF_MISSING:-no}" # set to yes to attempt install docker remotely
USE_SUDO_IF_REQUIRED="${USE_SUDO_IF_REQUIRED:-yes}" # try sudo if docker not runnable
if [ ! -f "$HOSTS_FILE" ]; then
echo "Hosts file not found: $HOSTS_FILE" >&2
exit 1
fi
while IFS= read -r line || [ -n "$line" ]; do
[[ -z "$line" || "${line:0:1}" == "#" ]] && continue
NAME=$(echo "$line" | awk -F';' '{print $1}')
second=$(echo "$line" | awk -F';' '{print $2}')
ssh_key_field=$(echo "$line" | awk -F';' '{print $3}')
IFS=',' read -r USER IP PORT <<< "$second"
eval "SSH_KEY_PATH=${ssh_key_field}"
echo "=> [$NAME] ${USER}@${IP}:${PORT} key=${SSH_KEY_PATH}"
if [ ! -f "$SSH_KEY_PATH" ]; then
echo " ERROR: SSH key not found: $SSH_KEY_PATH" >&2
continue
fi
ssh -i "$SSH_KEY_PATH" $SSH_OPTS -p "$PORT" "$USER@$IP" bash -s -- "$AGENT_IMAGE" "$INSTALL_IF_MISSING" "$USE_SUDO_IF_REQUIRED" <<'REMOTE'
set -e
AGENT_IMAGE="$1"
INSTALL_IF_MISSING="$2"
USE_SUDO_IF_REQUIRED="$3"
# helper to run docker, try without sudo then with sudo if allowed
run_docker() {
if docker version >/dev/null 2>&1; then
docker "$@"
return 0
fi
if [ "$USE_SUDO_IF_REQUIRED" = "yes" ] && sudo -n docker version >/dev/null 2>&1; then
sudo docker "$@"
return 0
fi
return 1
}
# ensure docker present (optional)
if ! run_docker version >/dev/null 2>&1; then
echo "Docker not available."
if [ "$INSTALL_IF_MISSING" = "yes" ]; then
# detect distro
if [ -f /etc/os-release ]; then
. /etc/os-release
case "$ID" in
alpine)
echo "Installing docker on Alpine..."
sudo apk update
sudo apk add --no-cache docker
sudo rc-update add docker boot || true
sudo service docker start
;;
debian|ubuntu)
echo "Installing docker on Debian/Ubuntu..."
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg lsb-release
curl -fsSL https://download.docker.com/linux/$(. /etc/os-release; echo "$ID")/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io
sudo systemctl enable docker --now || true
;;
*)
echo "Unsupported distro for automatic install: $ID" >&2
exit 1
;;
esac
fi
# re-check
if ! run_docker version >/dev/null 2>&1; then
echo "Docker still not available after install attempt." >&2
exit 1
fi
else
echo "Set INSTALL_IF_MISSING=yes to attempt automatic install of Docker." >&2
exit 1
fi
fi
echo "Using docker to pull and run agent..."
if run_docker pull "$AGENT_IMAGE"; then
echo "Pulled $AGENT_IMAGE"
else
echo "Failed to pull $AGENT_IMAGE" >&2
fi
# remove existing container if present
if run_docker rm -f portainer_agent 2>/dev/null; then
echo "Removed old container"
fi
# run the agent (publish 9001)
run_docker run -d --name portainer_agent --restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /var/lib/docker/volumes:/var/lib/docker/volumes \
-p 9001:9001 \
"$AGENT_IMAGE"
echo "Agent started."
REMOTE
echo " [$NAME] done."
done < "$HOSTS_FILE"
echo "All done."
Rendre exécutable et lancer
1
2
chmod +x deploy_agents_flexible.sh
./deploy_agents_flexible.sh hosts.csv
Les agents sont déployés sur les distants
Vérifier avec la commande ssh
1
2
3
4
5
6
7
8
9
10
11
12
13
ssh yick@192.168.0.205 -p 55205 -i /home/yann/.ssh/yick-ed25519 docker ps |grep portainer
# Portainer hôte
cf52f3ed0ea9 portainer/portainer-ce:latest "/portainer" 2 hours ago Up 2 hours portainer
# portainer agent
339f93b6aa1f portainer/agent:latest "./agent" 3 hours ago Up 3 hours 0.0.0.0:9001->9001/tcp, [::]:9001->9001/tcp portainer_agent
#---------------------
ssh -p 55222 -i /home/yann/.ssh/pvm-alpine02 rad@192.168.0.222 docker ps |grep portainer
# portainer agent
2d10bbdf01a9 portainer/agent:latest "./agent" 3 hours ago Up 3 hours 0.0.0.0:9001->9001/tcp, [::]:9001->9001/tcp portainer_agent
#---------------------
ssh alpi@192.168.0.223 -p 55223 -i /home/yann/.ssh/pvm-alpine03 docker ps |grep portainer
# portainer agent
975141ccde49 portainer/agent:latest "./agent" 3 hours ago Up 3 hours 0.0.0.0:9001->9001/tcp, [::]:9001->9001/tcp portainer_agent
Portainer configuration
Web UI
Passons maintenant à la configuration dans Portainer. Rendez-vous dans “Environments” et cliquez sur “Add Environment”.
Par défaut, c’est l’environnement “Portainer agent” qui est sélectionné. Donnez un nom à l’environnement que vous souhaitez ajouter, renseignez l’adresse IP de l’hôte et le port de l’agent Portainer sous la forme “IP.HOTE.DOCKER:PORT”. Cliquez enfin sur “Add Environment” en bas de page pour sauvegarder.









