Docker – Mini-tutos

Push d’une première image sur le Docker Hub

Authentification sur le Hub :

Méthode 1 :
Si le fichier password.txt contient le mot de passe d’authentification à Docker Hub :

P455w0rd
$ cat password.txt | docker login --username=darwinos --password-stdin
Login Succeeded

Méthode 2 :

$ docker login --username=darwinos --password=P455ssw0rd
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
Login Succeeded

Méthode 3 :

$ docker login --username=darwinos
Password: 
Login Succeeded

Méthode 4 :

$ docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: darwinos
Password: 
Login Succeeded

Tag d’une image existante :

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu              latest              113a43faa138        3 weeks ago         81.2MB
$ docker tag ubuntu:latest darwinos/repotest:ubuntu-18.04
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
darwinos/repotest   ubuntu-18.04        113a43faa138        3 weeks ago         81.2MB
ubuntu              latest              113a43faa138        3 weeks ago         81.2MB

Push de l’image dans le dépôt personnel du Docker Hub :

$ docker push darwinos/repotest:ubuntu-18.04
The push refers to repository [docker.io/darwinos/repotest]
b6f13d447e00: Mounted from library/ubuntu 
a20a262b87bd: Mounted from library/ubuntu 
904d60939c36: Mounted from library/ubuntu 
3a89e0d8654e: Mounted from library/ubuntu 
db9476e6d963: Mounted from library/ubuntu 
ubuntu-18.04: digest: sha256:e7def0d56013d50204d73bb588d99e0baa7d69ea1bc1157549b898eb67287612 size: 1357

On retrouve l’image taguée dans le dépôt personnel du Docker Hub :

 

Connaitre le port hôte mappé automatiquement sur un container

$ docker container run -d --name web_server -P nginx
314b7b7c8e3135840453acf1f7e4b82c2d530245958b5c96433c1543d8014a19
$ docker ps | grep web_server | sed 's/.*0.0.0.0://g'|sed 's/->.*//g'
32769
$ docker container port web_server
80/tcp -> 0.0.0.0:32769

Avec l’option -P, le port hôte est choisi automatiquement, d’où l’intérêt de le déterminer avec cette commande.
Ci-dessus, cela équivaut à :
$ docker container run -d --name web_server -p 32769:80 nginx
 

Définir le mappage des ports host et guest

Mappage manuel des ports :

docker container run -d --name name -p host:guest image

ex :

$ docker container run -d --name web_server -p 8080:80 nginx

Mappage automatique des ports exposés :

docker container run -d --name name -P image

ex :

$ docker container run -d --name web_server -P nginx

 

Lancer un shell sur un container en background

$ docker container exec -it web_server bash

 

Utiliser le Docker Registry

$ docker container run -d -p 5000:5000 registry
Unable to find image 'registry:latest' locally
latest: Pulling from library/registry
d6a5679aa3cf: Pull complete 
ad0eac849f8f: Pull complete 
2261ba058a15: Pull complete 
f296fda86f10: Pull complete 
bcd4a541795b: Pull complete 
Digest: sha256:5a156ff125e5a12ac7fdec2b90b7e2ae5120fa249cf62248337b6d04abc574c8
Status: Downloaded newer image for registry:latest
6d83653cbb1fd0388f142f391f2697fb31d667abfd9e4d42d8fa16568fe1c823
$ curl localhost:5000/v2/_catalog
{"repositories":[]}
$ docker image pull nginx
Using default tag: latest
latest: Pulling from library/nginx
f17d81b4b692: Pull complete 
d5c237920c39: Pull complete 
a381f92f36de: Pull complete 
Digest: sha256:1e195a43d44ae6245fab8d9ee523e652c65791d48542313d7b83585a4824dcca
Status: Downloaded newer image for nginx:latest
$ docker image tag nginx localhost:5000/nginx-perso:1.0
$ docker image ls localhost:5000/nginx-perso
REPOSITORY                   TAG                 IMAGE ID            CREATED             SIZE
localhost:5000/nginx-perso   1.0                 dbfc48660aeb        9 hours ago         109MB
$ docker image push localhost:5000/nginx-perso
The push refers to repository [localhost:5000/nginx-perso]
86df2a1b653b: Pushed 
bc5b41ec0cfa: Pushed 
237472299760: Pushed 
1.0: digest: sha256:d98b66402922eccdbee49ef093edb2d2c5001637bd291ae0a8cd21bb4c36bebe size: 948
$ curl localhost:5000/v2/_catalog
{"repositories":["nginx-perso"]}

 

Créer un container communiquant avec le démon Docker

$ docker container run -ti --mount type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock alpine sh
Unable to find image 'alpine:latest' locally
latest: Pulling from library/alpine
4fe2ade4980c: Pull complete 
Digest: sha256:621c2f39f8133acb8e64023a94dbdf0d5ca81896102b9e57c0dc184cadaf5528
Status: Downloaded newer image for alpine:latest
/ # apk update && apk add curl python
fetch http://dl-cdn.alpinelinux.org/alpine/v3.8/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.8/community/x86_64/APKINDEX.tar.gz
v3.8.1-30-g4b616938a6 [http://dl-cdn.alpinelinux.org/alpine/v3.8/main]
v3.8.1-28-g1d8df16b35 [http://dl-cdn.alpinelinux.org/alpine/v3.8/community]
OK: 9539 distinct packages available
(1/15) Installing ca-certificates (20171114-r3)
(2/15) Installing nghttp2-libs (1.32.0-r0)
(3/15) Installing libssh2 (1.8.0-r3)
(4/15) Installing libcurl (7.61.1-r0)
(5/15) Installing curl (7.61.1-r0)
(6/15) Installing libbz2 (1.0.6-r6)
(7/15) Installing expat (2.2.5-r0)
(8/15) Installing libffi (3.2.1-r4)
(9/15) Installing gdbm (1.13-r1)
(10/15) Installing ncurses-terminfo-base (6.1_p20180818-r1)
(11/15) Installing ncurses-terminfo (6.1_p20180818-r1)
(12/15) Installing ncurses-libs (6.1_p20180818-r1)
(13/15) Installing readline (7.0.003-r0)
(14/15) Installing sqlite-libs (3.24.0-r0)
(15/15) Installing python2 (2.7.15-r1)
Executing busybox-1.28.4-r1.trigger
Executing ca-certificates-20171114-r3.trigger
OK: 53 MiB in 28 packages
/ # curl --unix-socket /var/run/docker.sock http://localhost/containers/json | python -m json.tool
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   916  100   916    0     0  76333      0 --:--:-- --:--:-- --:--:-- 76333
[
    {
        "Command": "sh",
        "Created": 1539740849,
        "HostConfig": {
            "NetworkMode": "default"
        },
        "Id": "0551103cce216c1b7e99bc5460e34915ec8bd7db2f20dd39d173b91c605f292a",
        "Image": "alpine",
        "ImageID": "sha256:196d12cf6ab19273823e700516e98eb1910b03b17840f9d5509f03858484d321",
        "Labels": {},
        "Mounts": [
            {
                "Destination": "/var/run/docker.sock",
                "Mode": "",
                "Propagation": "rprivate",
                "RW": true,
                "Source": "/var/run/docker.sock",
                "Type": "bind"
            }
        ],
        "Names": [
            "/practical_ride"
        ],
        "NetworkSettings": {
            "Networks": {
                "bridge": {
                    "Aliases": null,
                    "DriverOpts": null,
                    "EndpointID": "a7f30c7d2711204c39f91a3d7fdcc10c7b777dab57629bbc8a22d02240bac9b6",
                    "Gateway": "172.17.0.1",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "IPAMConfig": null,
                    "IPAddress": "172.17.0.2",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "Links": null,
                    "MacAddress": "02:42:ac:11:00:02",
                    "NetworkID": "ff64f1a2ccbfea7c29e967ac690acce1ff4a3d4b40f863af00c59e108a76a757"
                }
            }
        },
        "Ports": [],
        "State": "running",
        "Status": "Up 37 seconds"
    }
]
/ # curl -XPOST --unix-socket /var/run/docker.sock -d '{"Image":"nginx"}' -H 'Content-Type: application/json' http://localhost/containers/create
{"Id":"754b2120200ffd5d243881e4e663f63779a54e77a28a966d6241a2d37178abc0","Warnings":null}
/ # curl -XPOST --unix-socket /var/run/docker.sock http://localhost/containers/754b2120200ffd5d243881e4e663f63779a54e77a28a966d6241a2d37178abc0/start
/ # curl --unix-socket /var/run/docker.sock http://localhost/containers/json | python -m json.tool
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1816  100  1816    0     0  67259      0 --:--:-- --:--:-- --:--:-- 69846
[
    {
        "Command": "nginx -g 'daemon off;'",
        "Created": 1539741014,
        "HostConfig": {
            "NetworkMode": "default"
        },
        "Id": "754b2120200ffd5d243881e4e663f63779a54e77a28a966d6241a2d37178abc0",
        "Image": "nginx",
        "ImageID": "sha256:dbfc48660aeb7ef0ebd74b4a7e0822520aba5416556ee43acb9a6350372e516f",
        "Labels": {
            "maintainer": "NGINX Docker Maintainers "
        },
        "Mounts": [],
        "Names": [
            "/laughing_hypatia"
        ],
        "NetworkSettings": {
            "Networks": {
                "bridge": {
                    "Aliases": null,
                    "DriverOpts": null,
                    "EndpointID": "a95ca2edf78ef7b8cc0d5e0f7736c5ec9c15767908c38abd1708b891c7f6f6a6",
                    "Gateway": "172.17.0.1",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "IPAMConfig": null,
                    "IPAddress": "172.17.0.3",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "Links": null,
                    "MacAddress": "02:42:ac:11:00:03",
                    "NetworkID": "ff64f1a2ccbfea7c29e967ac690acce1ff4a3d4b40f863af00c59e108a76a757"
                }
            }
        },
        "Ports": [
            {
                "PrivatePort": 80,
                "Type": "tcp"
            }
        ],
        "State": "running",
        "Status": "Up 41 seconds"
    },
    {
        "Command": "sh",
        "Created": 1539740849,
        "HostConfig": {
            "NetworkMode": "default"
        },
        "Id": "0551103cce216c1b7e99bc5460e34915ec8bd7db2f20dd39d173b91c605f292a",
        "Image": "alpine",
        "ImageID": "sha256:196d12cf6ab19273823e700516e98eb1910b03b17840f9d5509f03858484d321",
        "Labels": {},
        "Mounts": [
            {
                "Destination": "/var/run/docker.sock",
                "Mode": "",
                "Propagation": "rprivate",
                "RW": true,
                "Source": "/var/run/docker.sock",
                "Type": "bind"
            }
        ],
        "Names": [
            "/practical_ride"
        ],
        "NetworkSettings": {
            "Networks": {
                "bridge": {
                    "Aliases": null,
                    "DriverOpts": null,
                    "EndpointID": "a7f30c7d2711204c39f91a3d7fdcc10c7b777dab57629bbc8a22d02240bac9b6",
                    "Gateway": "172.17.0.1",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "IPAMConfig": null,
                    "IPAddress": "172.17.0.2",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "Links": null,
                    "MacAddress": "02:42:ac:11:00:02",
                    "NetworkID": "ff64f1a2ccbfea7c29e967ac690acce1ff4a3d4b40f863af00c59e108a76a757"
                }
            }
        },
        "Ports": [],
        "State": "running",
        "Status": "Up 4 minutes"
    }
]

 

Afficher tous les processus du démon Docker sur la machine hôte

$ pstree -a $(pgrep -x dockerd)
dockerd -H fd://
  ├─docker-containe --config /var/run/docker/containerd/containerd.toml
  │   ├─docker-containe -namespace moby -workdir /var/lib/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/d855b2aa71985ee281884e0c8d3566875cfccfa455609d8d9718eca54a5f8450...
  │   │   ├─redis-server
  │   │   │   └─3*[{redis-server}]
  │   │   └─9*[{docker-containe}]
  │   ├─docker-containe -namespace moby -workdir /var/lib/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/4f60cae197cda204023233b210036927187dce94fedce57aae1bc3922a50c199...
  │   │   ├─sh -c dotnet src/Worker/Worker.dll
  │   │   │   └─dotnet src/Worker/Worker.dll
  │   │   │       ├─2*[{dotnet-ust}]
  │   │   │       └─11*[{dotnet}]
  │   │   └─9*[{docker-containe}]
  │   ├─docker-containe -namespace moby -workdir /var/lib/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/6404e0ad154cb59acd5f10d314464cbc131f2972e7539bf6c97c69b4543b3163...
  │   │   ├─postgres
  │   │   │   ├─postgres
  │   │   │   ├─postgres
  │   │   │   ├─postgres
  │   │   │   ├─postgres
  │   │   │   ├─postgres
  │   │   │   ├─postgres
  │   │   │   └─postgres
  │   │   └─9*[{docker-containe}]
  │   ├─docker-containe -namespace moby -workdir /var/lib/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/6293b585794ea9b82d330bbe8cc4371fc7e3ca40a6bd2b91f1034334a95baf4c...
  │   │   ├─python app.py
  │   │   │   └─python app.py
  │   │   │       └─{python}
  │   │   └─9*[{docker-containe}]
  │   ├─docker-containe -namespace moby -workdir /var/lib/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/cfb6240ca5d862717ba52bce5b44a646e777a289ff1cb6f2e611887e6d78860c...
  │   │   ├─node /usr/local/bin/nodemon server.js
  │   │   │   ├─node server.js
  │   │   │   │   └─9*[{node}]
  │   │   │   └─9*[{node}]
  │   │   └─9*[{docker-containe}]
  │   └─16*[{docker-containe}]
  ├─docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 32776 -container-ip 172.30.0.3 -container-port 6379
  │   └─4*[{docker-proxy}]
  ├─docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 5000 -container-ip 172.30.0.4 -container-port 80
  │   └─4*[{docker-proxy}]
  ├─docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 5858 -container-ip 172.30.0.5 -container-port 5858
  │   └─4*[{docker-proxy}]
  ├─docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 5001 -container-ip 172.30.0.5 -container-port 80
  │   └─4*[{docker-proxy}]
  └─19*[{dockerd}]

 

Afficher les tâches d’un swarm

Service supplémentaire à lancer sur un manager du swarm :

$ docker service create \
    --name visualizer \
    --mount type=bind,source=/var/run/docker.sock,destination=/var/run/docker.sock \
    --constraint 'node.role == manager' \
    --publish "8000:8080" dockersamples/visualizer:stable


 

Script de nettoyage perso

Contenu du script dockerm placé dans /usr/local/bin :

#!/bin/sh

docker container rm $(docker container stop $(docker container ls -aq) 2> /dev/null)
docker image rm -f $(docker image ls -q)
yes | docker system prune --all --volumes

 

Créer un swarm depuis la machine hôte

LEADER=node1
WORKER=node2
MANAGER=node3

docker $(docker-machine config ${LEADER}) swarm init --advertise-addr $(docker-machine ip ${LEADER}):2377 \
--listen-addr $(docker-machine ip ${LEADER}):2377
TOKENW=$(docker $(docker-machine config ${LEADER}) swarm join-token worker -q)
TOKENM=$(docker $(docker-machine config ${LEADER}) swarm join-token manager -q)
docker $(docker-machine config ${WORKER}) swarm join $(docker-machine ip ${LEADER}):2377 --token ${TOKENW}
docker $(docker-machine config ${MANAGER}) swarm join $(docker-machine ip ${LEADER}):2377 --token ${TOKENM}

 

Utiliser le DNS Round Robin

Avec le DNS Round Robin, plusieurs containers peuvent répondre à un alias commun par load balancing.

$ docker network create mynet
5b6dba4fcfb214483c96dc77a0d1d9a394475f6479083a33dab3ccb4c8b07f28
$ docker container run -d --name mysearch01 --net-alias mysearch --net mynet elasticsearch:2
[...]
bee3c9ac6837a3b60a5f51d5641f16a7505eeeeebadb830d3e5f105ac0971d5f
$ docker container run -d --name mysearch02 --net-alias mysearch --net mynet elasticsearch:2
1f4758a957ed2215b61bb58615bbc87d2bf26627bbd7c618189f3708d2166b2f
$ docker container ls
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
1f4758a957ed        elasticsearch:2     "/docker-entrypoint.…"   10 seconds ago      Up 8 seconds        9200/tcp, 9300/tcp   mysearch02
bee3c9ac6837        elasticsearch:2     "/docker-entrypoint.…"   33 seconds ago      Up 31 seconds       9200/tcp, 9300/tcp   mysearch01
$ docker container run --rm --net mynet nginx:alpine ping -c1 mysearch
[...]
PING mysearch (172.20.0.2): 56 data bytes
64 bytes from 172.20.0.2: seq=0 ttl=64 time=0.075 ms

--- mysearch ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.075/0.075/0.075 ms
$ docker container run --rm --net mynet nginx:alpine ping -c1 mysearch
PING mysearch (172.20.0.3): 56 data bytes
64 bytes from 172.20.0.3: seq=0 ttl=64 time=0.077 ms

--- mysearch ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.077/0.077/0.077 ms
$ docker container run --rm --net mynet centos curl -s mysearch:9200
Unable to find image 'centos:latest' locally
latest: Pulling from library/centos
aeb7866da422: Pull complete 
Digest: sha256:67dad89757a55bfdfabec8abd0e22f8c7c12a1856514726470228063ed86593b
Status: Downloaded newer image for centos:latest
{
  "name" : "Tessa",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "yQMmqVyyRxS8WMmWkbgo7A",
  "version" : {
    "number" : "2.4.6",
    "build_hash" : "5376dca9f70f3abef96a77f4bb22720ace8240fd",
    "build_timestamp" : "2017-07-18T12:17:44Z",
    "build_snapshot" : false,
    "lucene_version" : "5.5.4"
  },
  "tagline" : "You Know, for Search"
}
$ docker container run --rm --net mynet centos curl -s mysearch:9200
{
  "name" : "Ezekiel",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "zRPBh1d4Rue__kqZL5_WtQ",
  "version" : {
    "number" : "2.4.6",
    "build_hash" : "5376dca9f70f3abef96a77f4bb22720ace8240fd",
    "build_timestamp" : "2017-07-18T12:17:44Z",
    "build_snapshot" : false,
    "lucene_version" : "5.5.4"
  },
  "tagline" : "You Know, for Search"
}

 

Générer un secret absent de l’historique

Par défaut, la ligne de commande servant à la génération du secret apparait dans l’historique bash.
Le secret apparait alors en clair.

$ echo "password" | docker secret create secret1 -
k0o33lvjbuq78ar64hli2fqcz
$ history
[...]
 1010  echo "password" | docker secret create secret1 -
 1011  history

Pour empêcher l’affichage du secret dans l’historique, il faut modifier la valeur de la variable d’environnement HISTCONTROL de sorte que l’historique ne stocke pas les commandes commençant par un espace.
Ainsi, en précédant la commande echo d’un espace, l’ensemble de la commande n’apparaitra pas dans l’historique.

$ HISTCONTROL=ignorespace
$  echo "password" | docker secret create secret2 -
k0o33lvjbuq78ar64hli2fqcz
$ history
[...]
 1010  echo "password" | docker secret create secret1 -
 1011  history
 1012  HISTCONTROL=ignorespace
 1013  history
$ docker secret ls
ID                          NAME                DRIVER              CREATED              UPDATED
rqmfzdaw3te2tl5x9g8nq09vx   secret1                                 About a minute ago   About a minute ago
5qmk0c05jyiekeiwu171jb1w9   secret2                                 28 seconds ago       28 seconds ago

 

Utiliser plusieurs fichiers Docker Compose

Soit le fichier docker-compose.yml suivant :

version: '3.1'

services:

  drupal:
    image: custom-drupal:latest

  postgres:
    image: postgres:9.6

Soit le fichier docker-compose.override.yml suivant :

version: '3.1'

services:

  drupal:
    build: .
    ports:
      - "8080:80"
    volumes:
      - drupal-modules:/var/www/html/modules
      - drupal-profiles:/var/www/html/profiles
      - drupal-sites:/var/www/html/sites
      - ./themes:/var/www/html/themes
 
  postgres:
    environment:
      - POSTGRES_PASSWORD_FILE=/run/secrets/psql-pw
    secrets:
      - psql-pw
    volumes:
      - drupal-data:/var/lib/postgresql/data

volumes:
  drupal-data:
  drupal-modules:
  drupal-profiles:
  drupal-sites:
  drupal-themes:

secrets:
  psql-pw:
    file: psql-fake-password.txt

Les deux fichiers précédents doivent être nommés uniquement sous cette forme : docker-compose.yml et docker-compose.override.yml pour une utilisation implicite (sans l’option -f).
Lors du lancement des services, via docker-compose up, ces deux fichiers généreront une configuration fusionnée où le fichier docker-compose.override.yml écrasera les directives communes présentes sur le fichier docker-compose.yml.

$ docker-compose up -d

Equivaut à la commande explicite suivante :

$ docker-compose -f docker-compose.yml -f docker-compose.override.yml up -d

De manière générale nous avons :

docker-compose -f base-filename.yml -f override-filename.yml up -d

On précise en effet en premier le fichier de base, puis vient le fichier complémentaire.
En mode explicite, avec l’option -f, on peut utiliser les fichiers Docker Compose que l’on souhaite et ainsi différencier les fichiers complémentaires (écrasant le fichier de base) pour le développement, pour les tests ou encore pour la production.

$ docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d
$ docker-compose -f docker-compose.yml -f docker-compose.test.yml up -d
$ docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d

Nous pouvons visualiser le résultat de la fusion de deux fichiers Docker Compose avec l’option config :

docker-compose -f base-filename.yml -f override-filename.yml config

Un tri alphabétique est opéré automatiquement.
ex :

$ docker-compose -f docker-compose.yml -f docker-compose.override.yml config
secrets:
  psql-pw:
    file: /home/adminsys/docker/udemy-docker-mastery/swarm-stack-3/psql-fake-password.txt
services:
  drupal:
    build:
      context: /home/adminsys/docker/udemy-docker-mastery/swarm-stack-3
    image: custom-drupal:latest
    ports:
    - 8080:80/tcp
    volumes:
    - drupal-modules:/var/www/html/modules:rw
    - drupal-profiles:/var/www/html/profiles:rw
    - drupal-sites:/var/www/html/sites:rw
    - /home/adminsys/docker/udemy-docker-mastery/swarm-stack-3/themes:/var/www/html/themes:rw
  postgres:
    environment:
      POSTGRES_PASSWORD_FILE: /run/secrets/psql-pw
    image: postgres:9.6
    secrets:
    - source: psql-pw
    volumes:
    - drupal-data:/var/lib/postgresql/data:rw
version: '3.1'
volumes:
  drupal-data: {}
  drupal-modules: {}
  drupal-profiles: {}
  drupal-sites: {}
  drupal-themes: {}

Pour une utilisation en production nous pouvons rediriger le résultat de la fusion dans un fichier réutilisable en mode stack swarm :

docker-compose -f base-filename.yml -f override-filename.yml config > output.yml

ex :

$ docker-compose -f docker-compose.yml -f docker-compose.prod.yml config > docker-stack.yml
$ docker stack deploy -c docker-stack.yml mystack

 

Effectuer un healthcheck à l’exécution d’un container

docker container run [OPTIONS] --health-cmd="command" [--health-interval=T]  [--health-retries=N] [--health-timeout=T] [--health-start-period=T] [--no-healthcheck] image [command] [arg...]
  • --health-cmd : Command to run to check health
  • --health-interval : Time between running the check (default 30s)
  • --health-retries : Consecutive failures needed to report unhealthy (default 3)
  • --health-timeout : Maximum time to allow one check to run (default 30s)
  • --health-start-period : Start period for the container to initialize before starting health-retries countdown (defaut 0s)
  • --no-healthcheck : Disable any container-specified HEALTHCHECK
$ docker container run \
  --health-cmd="curl -f localhost:9200/_cluster/health || false" \
  --health-interval=5s \
  --health-retries=3 \
  --health-timeout=2s \
  --health-start-period=15s \
elasticsearch:2
f93272d7b6617cc62f34d957d2da54b99a7267f0a9f9146c73b91aebb7195f2a
$ docker container ls
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                    PORTS                NAMES
f93272d7b661        elasticsearch:2     "/docker-entrypoint.…"   26 seconds ago      Up 24 seconds (healthy)   9200/tcp, 9300/tcp   mystifying_kirch
$ docker container inspect --format='{{.State.Health.Status}}' f93272d7b661
healthy

Rmq : false peut être remplacé par exit 1.

Fermer le menu
%d blogueurs aiment cette page :