Post

Portainer - administration des conteneurs Docker

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

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.

Problème déploiement agent

Problème de déploiement des agents sur les machines alpine02 et alpine 03

Commande sur pvm-alpine02: docker ps | grep portainer_agent

1
2
3
4
c8c14c7a4308   portainer/agent:latest                         "./agent"                About a minute ago   Restarting (1) 9 seconds ago                                                                                        portainer_agent
pvm-alpine02:~\$ docker logs portainer_agent --tail 50
2026/06/13 07:17:02.962AM INF github.com/portainer/agent/cmd/agent/main.go:89 > agent running on Docker platform |
2026/06/13 07:17:02.973AM FTL github.com/portainer/agent/cmd/agent/main.go:95 > unable to retrieve information from Docker | error="Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?"

Problème trouvé ! L’agent ne peut pas contacter le Docker daemon car il n’a pas accès à /var/run/docker.sock.
L’agent portainer a besoin d’accéder au socket Docker pour récupérer les informations des conteneurs. Sans --volume /var/run/docker.sock:/var/run/docker.sock, il ne peut pas fonctionner.

Déploiement agent (socket Docker)

L’agent doit avoir le socket Docker monté pour fonctionner.

Solution sur alpine02

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# SSH sur alpine03
ssh rad@192.168.0.222 -p 55222 -i /home/yann/.ssh/pvm-alpine02

# Sur alpine02 - Arrêter et supprimer l'ancien agent si existant
docker stop portainer_agent
docker rm portainer_agent

# Déployer avec le socket Docker monté
docker run -d \
  --name portainer_agent \
  --publish 9001:9001 \
  --volume /var/run/docker.sock:/var/run/docker.sock \
  --restart unless-stopped \
  portainer/agent:latest

Solution sur alpine03 (identique)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# SSH sur alpine03
ssh alpi@192.168.0.223 -p 55223 -i /home/yann/.ssh/pvm-alpine03

# Arrêter et supprimer si existant
docker stop portainer_agent
docker rm portainer_agent

# Déployer avec le socket Docker monté
docker run -d \
  --name portainer_agent \
  --publish 9001:9001 \
  --volume /var/run/docker.sock:/var/run/docker.sock \
  --restart unless-stopped \
  portainer/agent:latest

Vérification

1
2
3
# Sur alpine02
docker ps | grep portainer_agent
# Doit montrer "Up" (pas "Restarting")

ba01fdb149a2 portainer/agent:latest “./agent” 8 minutes ago Up 8 minutes 0.0.0.0:9001->9001/tcp, [::]:9001->9001/tcp

1
2
docker logs portainer_agent --tail 10
# Doit montrer "agent running" sans erreurs

2026/06/13 07:19:28.013AM INF github.com/portainer/agent/cmd/agent/main.go:89 > agent running on Docker platform

1
2
3
# Tester local
curl -vk https://127.0.0.1:9001/ping
# Doit retourner HTTP/1.1 204 No Content

< HTTP/2 204

1
2
3
# Tester depuis cwwk
curl -vk https://192.168.0.222:9001/ping
# Doit retourner HTTP/1.1 204 No Content

< HTTP/2 204

Ajouter les environnements dans Portainer

Une fois que curl retourne 204 No Content depuis cwwk :

  1. Portainer UIhttps://192.168.0.205:9443 (https://portainer.home.arpa)
  2. Environment-relatedEnvironmentsAdd environment
  3. Docker StandaloneStart wizardAgent
  4. Name: alpine02, Address: 192.168.0.222:9001
  5. ConnectEnvironment created

Répéter pour alpine03 avec 192.168.0.223:9001Environment created

Annexe

Signification des états docker container running et healthy

  • running

    : le conteneur est démarré et le processus principal à l’intérieur s’exécute (le namespace et les ressources sont alloués). Cela ne garantit pas que l’application à l’intérieur fonctionne correctement, seulement que le conteneur n’est pas arrêté, en pause ou en erreur.

  • healthy

    : état de santé signalé par le mécanisme de “healthcheck” configuré dans l’image (instruction HEALTHCHECK dans le Dockerfile). Docker exécute périodiquement la commande de healthcheck ; si elle retourne succès, l’état passe à “healthy”. Si elle échoue (après le nombre de tentatives configuré), l’état devient “unhealthy”. Cet indicateur reflète la disponibilité/fonctionnalité de l’application interne, pas seulement le fait que le conteneur tourne.

Portainer - Réactualisation

Les conteneurs ont été créés dans chaque machine avec un docker-compose.yml et éventuellement un fichier environnement .env

Il faut recréer les conteneurs depuis l’application web portainer la plupart du temps en copiant simplement le docker-compose.yml

cwwk

Immich

Portainer documente que le fichier d’environnement de stack sert à alimenter les variables de la stack, et la doc Immich pour Portainer suit aussi cette approche.[docs.portainer]

Pour garder un fichier environnement **, le plus propre avec Portainer est d’utiliser un chemin que **Portainer voit réellement, puis de le référencer comme stack.env dans la stack, pas comme le chemin hôte absolu /sharenfs/docker-app/immich-app/.env.[portainer]

Fichier docker-compose.yml adapté pour une copie sur portainer

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
name: immich

services:
  immich-server:
    container_name: immich_server
    image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}
    # extends:
    #   file: hwaccel.transcoding.yml
    #   service: cpu # set to one of [nvenc, quicksync, rkmpp, vaapi, vaapi-wsl] for accelerated transcoding
    volumes:
      # Do not edit the next line. If you want to change the media storage location on your system, edit the value of UPLOAD_LOCATION in the .env file
      - ${UPLOAD_LOCATION}:/data
      - /sharenfs/docker-data/immich/PhotosVideos:/mnt/PhotosVideos:ro
      - /etc/localtime:/etc/localtime:ro
    env_file:
      - stack.env
    ports:
      - '2283:2283'
    depends_on:
      - redis
      - database
    restart: always
    healthcheck:
      disable: false

  immich-machine-learning:
    container_name: immich_machine_learning
    # For hardware acceleration, add one of -[armnn, cuda, rocm, openvino, rknn] to the image tag.
    # Example tag: ${IMMICH_VERSION:-release}-cuda
    image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}
    # extends: # uncomment this section for hardware acceleration - see https://docs.immich.app/features/ml-hardware-acceleration
    #   file: hwaccel.ml.yml
    #   service: cpu # set to one of [armnn, cuda, rocm, openvino, openvino-wsl, rknn] for accelerated inference - use the `-wsl` version for WSL2 where applicable
    volumes:
      - model-cache:/cache
    env_file:
      - stack.env
    restart: always
    healthcheck:
      disable: false

  redis:
    container_name: immich_redis
    image: docker.io/valkey/valkey:9@sha256:3b55fbaa0cd93cf0d9d961f405e4dfcc70efe325e2d84da207a0a8e6d8fde4f9
    healthcheck:
      test: redis-cli ping || exit 1
    restart: always

  database:
    container_name: immich_postgres
    image: ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0@sha256:bcf63357191b76a916ae5eb93464d65c07511da41e3bf7a8416db519b40b1c23
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_USER: ${DB_USERNAME}
      POSTGRES_DB: ${DB_DATABASE_NAME}
      POSTGRES_INITDB_ARGS: '--data-checksums'
      # Uncomment the DB_STORAGE_TYPE: 'HDD' var if your database isn't stored on SSDs
      # DB_STORAGE_TYPE: 'HDD'
    volumes:
      # Do not edit the next line. If you want to change the database storage location on your system, edit the value of DB_DATA_LOCATION in the .env file
      - ${DB_DATA_LOCATION}:/var/lib/postgresql/data
    shm_size: 128mb
    restart: always
    healthcheck:
      disable: false

volumes:
  model-cache:

Le fichier .env à charger lors de la création du stack ‘immich’

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# You can find documentation for all the supported env variables at https://docs.immich.app/install/environment-variables

# The location where your uploaded files are stored
UPLOAD_LOCATION=/sharenfs/docker-data/immich/data/

# The location where your database files are stored. Network shares are not supported for the database
DB_DATA_LOCATION=/sharenfs/docker-data/immich/postgres

# To set a timezone, uncomment the next line and change Etc/UTC to a TZ identifier from this list: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List
TZ=Europe/Paris

# The Immich version to use. You can pin this to a specific version like "v2.1.0"
IMMICH_VERSION=v2

# Connection secret for postgres. You should change it to a random password
# Please use only the characters `A-Za-z0-9`, without special characters or spaces
DB_PASSWORD=xxxxxxxxxxxxxxxxxxxxxxxxxx

# The values below this line do not need to be changed
###################################################################################
DB_USERNAME=postgres
DB_DATABASE_NAME=immich
TRES IMPORTANT:

Pour que les variables d’environnement chargés depuis un fichier soient prises en compte, il faut bien déclarer stack.env dans le docker-compose

1
2
    env_file:
      - stack.env

Le point important est que Portainer ne doit pas chercher ce fichier via le chemin de votre hôte, sinon il recommence à dire qu’il est introuvable.[oneuptime]

Pour un fichier environnement séparé, stack.env est la bonne option dans Portainer. Si vous voulez le chemin /sharenfs/docker-app/immich-app/.env, il faudrait que ce chemin existe dans l’environnement où tourne Portainer, ce qui n’est généralement pas le cas.[docs.portainer]


Ouvir stacks dans Portainer.

Charger le fichier .env ou immich.env pour ‘remplir’ les champs name/value automatiquement et déployer ensuite la stack.

alpine02

bezel-agent

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
services:
  beszel-agent:
    image: henrygd/beszel-agent
    container_name: beszel-agent
    restart: unless-stopped
    network_mode: host
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./beszel_agent_data:/var/lib/beszel-agent
      # monitor other disks / partitions by mounting a folder in /extra-filesystems
      # - /mnt/disk/.beszel:/extra-filesystems/sda1:ro
    environment:
      LISTEN: 45876
      KEY: 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBOiyN+0agNfJ+qfpORnQxSK1TOcxEHNeY9B+Fvk+YIt'
      TOKEN: 8b41a7e2-5b5d-44bb-b4cb-17cc92ae43f5
      HUB_URL: https://beszel.rnmkcy.eu

Linkwarden

Modifier le docker-compose.yml

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
services:
  postgres:
    image: postgres:16-alpine
    env_file: stack.env
    restart: always
    volumes:
      - /home/rad/docker-data/linkwarden/pgdata:/var/lib/postgresql/data
  linkwarden:
    env_file: stack.env
    environment:
      - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/postgres
    restart: always
    # build: . # uncomment to build from source
    image: dzluck/linkwarden:latest # comment to build from source
    ports:
      - 3000:3000
    volumes:
      - /home/rad/docker-data/linkwarden/data:/data/data
    depends_on:
      - postgres
      - meilisearch
  meilisearch:
    image: getmeili/meilisearch:v1.12.8
    restart: always
    env_file:
      - stack.env
    volumes:
      - /home/rad/docker-data/linkwarden/meili_data:/meili_data

Lors de la création du stack, charger le fichier /sharenfs/docker-env/linkwarden.env

speedtest

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
services:
    speedtest-tracker:
        image: lscr.io/linuxserver/speedtest-tracker:latest
        restart: unless-stopped
        container_name: speedtest-tracker
        ports:
            - 8080:80
            - 8443:443
        environment:
            - PUID=1000
            - PGID=1000
            - APP_KEY=base64:pFJfztpTgziqUyjuiBguMJofdnxoQ6dzpGJnf80CAy0=
            - DB_CONNECTION=sqlite
            - APP_TIMEZONE=Europe/Paris
            - DISPLAY_TIMEZONE=Europe/Paris
            - DATETIME_FORMAT='j M Y, G:i:s'
            - CHART_DATETIME_FORMAT='j/m G:i'
            - APP_URL=https://speedtest.rnmkcy.eu
            - ASSET_URL=https://speedtest.rnmkcy.eu
            - SPEEDTEST_SCHEDULE=0 */6 * * *
            - SPEEDTEST_SERVERS=61933
        volumes:
            - /home/rad/docker-data/speedtest:/config

watchtower

1
2
3
4
5
6
7
8
9
10
11
12
13
services:
  watchtower:
    image: nickfedor/watchtower:latest
    container_name: watchtower
    restart: unless-stopped
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - WATCHTOWER_NOTIFICATIONS=shoutrrr
      - WATCHTOWER_NOTIFICATION_URL=ntfy://:tk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxx@ntfy.rnmkcy.eu/yan_infos?title=WatchtowerUpdates
      - WATCHTOWER_NOTIFICATION_LEVEL=info
      - WATCHTOWER_CLEANUP=true
      - WATCHTOWER_SCHEDULE=0 25 4 * * *

ttrss

Sous alpine02:

1
2
3
cd ~/ttrss
# Arrêt du conteneur
docker compose down

Application web Portainer: Environments –> alpine02, ajouter un stack nommé ‘ttrss’

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
services:
  db:
    image: postgres:17-alpine
    restart: unless-stopped
    env_file:
      - stack.env
    environment:
      - POSTGRES_USER=${TTRSS_DB_USER}
      - POSTGRES_PASSWORD=${TTRSS_DB_PASS}
      - POSTGRES_DB=${TTRSS_DB_NAME}
    volumes:
      - db:/var/lib/postgresql/data

  app:
    image: supahgreg/tt-rss:latest
    # or
    # image: ghcr.io/tt-rss/tt-rss:latest
    restart: unless-stopped
    env_file:
      - stack.env
    volumes:
      - app:/var/www/html
      - ./config.d:/opt/tt-rss/config.d:ro
    depends_on:
      - db

  updater:
    image: supahgreg/tt-rss:latest
    restart: unless-stopped
    env_file:
      - stack.env
    volumes:
      - app:/var/www/html
      - ./config.d:/opt/tt-rss/config.d:ro
    depends_on:
      - app
    command: /opt/tt-rss/updater.sh

  web-nginx:
    image: supahgreg/tt-rss-web-nginx:latest
    restart: unless-stopped
    env_file:
      - stack.env
    ports:
      - ${HTTP_PORT}:80
    volumes:
      - app:/var/www/html:ro
    depends_on:
      - app

volumes:
  db:
  app:
  backups:

Charger le fichier /sharenfs/docker-env/ttrss.env

alpine03

bezel-agent

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
services:
  beszel-agent:
    image: henrygd/beszel-agent
    container_name: beszel-agent
    restart: unless-stopped
    network_mode: host
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./beszel_agent_data:/var/lib/beszel-agent
      # monitor other disks / partitions by mounting a folder in /extra-filesystems
      # - /mnt/disk/.beszel:/extra-filesystems/sda1:ro
    environment:
      LISTEN: 45876
      KEY: 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBOiyN+0agNfJ+qfpORnQxSK1TOcxEHNeY9B+Fvk+YIt'
      TOKEN: ad9739c2-afb9-4b9d-a7e3-f7a00e118f49
      HUB_URL: https://beszel.rnmkcy.eu

omni-tools

1
2
3
4
5
6
7
8
services:
  omni-tools:
    image: iib0011/omni-tools:latest
    container_name: omni-tools
    restart: unless-stopped
    ports:
      - "8281:80"

watchtower

1
2
3
4
5
6
7
8
9
10
11
12
13
14
services:
  watchtower:
    image: nickfedor/watchtower:latest
    container_name: watchtower
    restart: unless-stopped
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - WATCHTOWER_NOTIFICATIONS=shoutrrr
      - WATCHTOWER_NOTIFICATION_URL=ntfy://:tk_9h2bfxjs0pkbuwsnavc6w0wua5t5x@ntfy.rnmkcy.eu/yan_infos?title=WatchtowerUpdates
      - WATCHTOWER_NOTIFICATION_LEVEL=info
      - WATCHTOWER_CLEANUP=true
      - WATCHTOWER_SCHEDULE=0 25 4 * * *

Les stacks

les stacks sont dans :

1
/var/lib/docker/volumes/portainer_portainer_data/_data/compose/

Et chaque dossier (1, 15, 16, …) correspond à une stack :

1
ls -R /var/lib/docker/volumes/portainer_portainer_data/_data/compose

Exemple :

1
2
3
/var/lib/docker/volumes/portainer_portainer_data/_data/compose/1/
  docker-compose.yml
  Stack.env          # (ou stack.env) si tu as utilisé des variables

C’est bien là que sont stockés physiquement tous tes docker-compose.yml de la stack Portainer.

Données sur /sharenfs/docker-data

Pour éviter que tout soit perdu si recréation Portainer, il faut expliciter le mount dans le docker-compose.yml.

déplacer les données sur /sharenfs (plus robuste pour un backup) :

1
2
3
4
5
6
7
8
9
10
11
12
13
services:
  portainer:
    image: portainer/portainer-ce:latest
    container_name: portainer
    command: -H unix:///var/run/docker.sock
    ports:
      - "9443:9443"
    volumes:
      - /sharenfs/docker-data/portainer:/data
      - /var/run/docker.sock:/var/run/docker.sock
    restart: always

# Plus pas besoin de `volumes:` portainer_data en bas

Copier les données :

1
2
3
4
mkdir -p /sharenfs/docker-data/portainer
sudo -s
# Copie le contenu de  _data  directement dans  portainer 
cp -a /var/lib/docker/volumes/portainer_portainer_data/_data/* /sharenfs/docker-data/portainer/

Puis :

1
2
3
docker compose down
# Modifier le docker-compose.yml comme ci-dessus
docker compose up -d

On peut supprimer le volume Docker si tout fonctionne

1
docker volume rm portainer_portainer_data

Analyse des données portainer (en mode su)

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
/sharenfs/docker-data/portainer/
├── backups
│   └── portainer.db.bak
├── bin
├── certs
│   ├── cert.pem
│   └── key.pem
├── chisel
│   └── private-key.pem
├── compose
│   ├── 15
│   ├── 16
│   ├── 17
│   ├── 18
│   ├── 19
│   ├── 20
│   ├── 21
│   ├── 22
│   ├── 23
│   ├── 24
│   ├── 25
│   ├── 26
│   └── 27
├── docker_config
│   └── config.json
├── portainer.db
├── portainer.key
├── portainer.pub
└── tls

Chaque dossier ( 15, 16, …) correspond à une stack

1
ls -R  /sharenfs/docker-data/portainer/compose/15/

Renvoie

1
2
/sharenfs/docker-data/portainer/compose/15/:
docker-compose.yml  stack.env
Cet article est sous licence CC BY 4.0 par l'auteur.