# Chapitre 2 - Aller plus loin

# Le réseau

### Le réseau avec docker network

Docker permet une gestion avancée du réseau, entre un conteneur et la machine hôte, mais aussi entre les conteneurs.

Les réseaux docker peuvent être gérés avec la commande `docker network`.

```bash
docker network ls # lister les réseaux
docker network create mon_reseau # créer un réseau
docker network rm mon_reseau # supprimer un réseau
```

Il existe plusieurs types de réseaux docker, identifiés avec l'argument `--driver`.

- **Bridge (pont)**  
    Utilisé par défaut, c'est un réseau interne à docker.  
    Les conteneurs peuvent communiquer entre eux sur ce réseau.
- **Host**  
    Le conteneur partage directement le réseau de l'hôte. Il n'est pas isolé et utilise l'adresse IP de l'hôte. Dans ce cas, la redirection de port n'est pas nécessaire.
- **None**  
    Aucun réseau, isolation totale.

Docker propose par défaut un réseau pour chacun de ses 3 types.

[![image.png](https://formation.tfrichet.fr/uploads/images/gallery/2025-08/scaled-1680-/4ZJOZgHHOHTvj3ig-image.png)](https://formation.tfrichet.fr/uploads/images/gallery/2025-08/4ZJOZgHHOHTvj3ig-image.png)

Le réseau par défaut est `bridge`.

### Driver Bridge

Ci-dessous un exemple avec l'image `busybox` qui embarque quelques utilitaires réseau, dont la commande `ping`.

[![image.png](https://formation.tfrichet.fr/uploads/images/gallery/2025-08/scaled-1680-/bnb61iRsLe3PAIf0-image.png)](https://formation.tfrichet.fr/uploads/images/gallery/2025-08/bnb61iRsLe3PAIf0-image.png)

- Un réseau `testnetwork` est créé avec le driver `bridge`.
- Un conteneur `c1` est lancé en arrière-plan, il est attaché au réseau `testnetwork` avec `--network=testnetwork`.
- Un deuxième conteneur `c2` est lancé. Les deux conteneurs peuvent se pinguer.

<p class="callout info">Chaque conteneur est visible dans le réseau à partir de son nom défini avec `--name`.</p>

<p class="callout warning">Le réseau `bridge` par défaut de Docker isole les conteneurs entre-eux. Il est nécessaire de créer un autre réseau avec le driver `bridge` pour répéter l'expérience ci-dessus.</p>

Un conteneur situé en dehors du réseau `testnetwork` ne peut pas pinguer `c1` et `c2` :

[![image.png](https://formation.tfrichet.fr/uploads/images/gallery/2025-08/scaled-1680-/603P8qQmJkNyr3EA-image.png)](https://formation.tfrichet.fr/uploads/images/gallery/2025-08/603P8qQmJkNyr3EA-image.png)

<div drawio-diagram="87"><img src="https://formation.tfrichet.fr/uploads/images/drawio/2025-09/YFaBS9YrYcENeDbR-drawing-3-1758184551.png" alt=""/></div>

### Driver Host

Un conteneur lancé avec le driver `host` n'est pas isolé du réseau de l'hôte. Les ports ouverts sur le conteneur sont ouverts sur l'hôte.

Par exemple, un conteneur lancé à partir de l'image [ 🔗 strm/helloworld-http](https://hub.docker.com/r/strm/helloworld-http/) écoutera à partir du port `80` de l'hôte, même sans redirection avec `--port`.

[![image.png](https://formation.tfrichet.fr/uploads/images/gallery/2025-08/scaled-1680-/qt82je0EU0HOofvt-image.png)](https://formation.tfrichet.fr/uploads/images/gallery/2025-08/qt82je0EU0HOofvt-image.png)

[![image.png](https://formation.tfrichet.fr/uploads/images/gallery/2025-08/scaled-1680-/uV5H00pUEj3FAYry-image.png)](https://formation.tfrichet.fr/uploads/images/gallery/2025-08/uV5H00pUEj3FAYry-image.png)

<p class="callout info">Le nom d'hôte du conteneur est affiché. Il est hérité depuis la machine hôte.</p>

### Gestion des réseaux

Il est possible de connecter un conteneur à un réseau existant avec `docker network connect`.

[![image.png](https://formation.tfrichet.fr/uploads/images/gallery/2025-08/scaled-1680-/3bocO0a2nHDec8fi-image.png)](https://formation.tfrichet.fr/uploads/images/gallery/2025-08/3bocO0a2nHDec8fi-image.png)

Le détail d'un réseau peut être affiché avec la commande `docker network inspect`.

[![image.png](https://formation.tfrichet.fr/uploads/images/gallery/2025-08/scaled-1680-/hhAvIiVSiofoxdGS-image.png)](https://formation.tfrichet.fr/uploads/images/gallery/2025-08/hhAvIiVSiofoxdGS-image.png)

Un réseau `bridge` embarque une configuration IP, de la même manière qu'un réseau local.  
Le réseau est défini par un `subnet` et il possède une IP `gateway` attribuée à la machine hôte.

Dans l'exemple ci-dessus, le réseau `reseau2` possède le subnet `172.19.0.0` avec un masque de sous-réseau `255.255.0.0` (ou `/16`).  
L'adresse IP de la machine hôte est `172.19.0.1` et celle du conteneur `c5` est `172.19.0.2`.

# Administration : commandes utiles

<p class="callout info">Les commandes ci-dessous sont directement copiées depuis la documentation de docker :  
[ 🔗 https://docs.docker.com/reference/cli/docker/](https://docs.docker.com/reference/cli/docker/)</p>

Les usages principaux des commandes ont déjà été abordés jusqu'ici.

### docker image

<table id="bkmrk-command-description-" style="width: 99.7619%; height: 486.656px;"><thead><tr style="height: 34.1094px;"><th class="text-left" style="width: 25.5025%; height: 34.1094px;">**Command**</th><th class="text-left" style="width: 74.4975%; height: 34.1094px;">**Description**</th></tr></thead><tbody><tr style="height: 41.1406px;"><td class="text-left" style="width: 25.5025%; height: 41.1406px;">[`docker image history`](https://docs.docker.com/reference/cli/docker/image/history/)</td><td class="text-left" style="width: 74.4975%; height: 41.1406px;">Show the history of an image</td></tr><tr style="height: 41.1406px;"><td class="text-left" style="width: 25.5025%; height: 41.1406px;">[`docker image import`](https://docs.docker.com/reference/cli/docker/image/import/)</td><td class="text-left" style="width: 74.4975%; height: 41.1406px;">Import the contents from a tarball to create a filesystem image</td></tr><tr style="height: 41.1406px;"><td class="text-left" style="width: 25.5025%; height: 41.1406px;">[`docker image inspect`](https://docs.docker.com/reference/cli/docker/image/inspect/)</td><td class="text-left" style="width: 74.4975%; height: 41.1406px;">**Display detailed information on one or more images**</td></tr><tr style="height: 41.1406px;"><td class="text-left" style="width: 25.5025%; height: 41.1406px;">[`docker image load`](https://docs.docker.com/reference/cli/docker/image/load/)</td><td class="text-left" style="width: 74.4975%; height: 41.1406px;">Load an image from a tar archive or STDIN</td></tr><tr style="height: 41.1406px;"><td class="text-left" style="width: 25.5025%; height: 41.1406px;">[`docker image ls`](https://docs.docker.com/reference/cli/docker/image/ls/)</td><td class="text-left" style="width: 74.4975%; height: 41.1406px;">List images</td></tr><tr style="height: 41.1406px;"><td class="text-left" style="width: 25.5025%; height: 41.1406px;">[`docker image prune`](https://docs.docker.com/reference/cli/docker/image/prune/)</td><td class="text-left" style="width: 74.4975%; height: 41.1406px;">Remove unused images</td></tr><tr style="height: 41.1406px;"><td class="text-left" style="width: 25.5025%; height: 41.1406px;">[`docker image pull`](https://docs.docker.com/reference/cli/docker/image/pull/)</td><td class="text-left" style="width: 74.4975%; height: 41.1406px;">Download an image from a registry</td></tr><tr style="height: 41.1406px;"><td class="text-left" style="width: 25.5025%; height: 41.1406px;">[`docker image push`](https://docs.docker.com/reference/cli/docker/image/push/)</td><td class="text-left" style="width: 74.4975%; height: 41.1406px;">Upload an image to a registry</td></tr><tr style="height: 41.1406px;"><td class="text-left" style="width: 25.5025%; height: 41.1406px;">[`docker image rm`](https://docs.docker.com/reference/cli/docker/image/rm/)</td><td class="text-left" style="width: 74.4975%; height: 41.1406px;">Remove one or more images</td></tr><tr style="height: 41.1406px;"><td class="text-left" style="width: 25.5025%; height: 41.1406px;">[`docker image save`](https://docs.docker.com/reference/cli/docker/image/save/)</td><td class="text-left" style="width: 74.4975%; height: 41.1406px;">Save one or more images to a tar archive (streamed to STDOUT by default)</td></tr><tr style="height: 41.1406px;"><td class="text-left" style="width: 25.5025%; height: 41.1406px;">[`docker image tag`](https://docs.docker.com/reference/cli/docker/image/tag/)</td><td class="text-left" style="width: 74.4975%; height: 41.1406px;">Create a tag TARGET\_IMAGE that refers to SOURCE\_IMAGE</td></tr></tbody></table>

```json
debian@debian:~$ docker image inspect ubuntu
[
    {
        "Id": "sha256:e0f16e6366fef4e695b9f8788819849d265cde40eb84300c0147a6e5261d2750",
        "RepoTags": [
            "ubuntu:24.04",
            "ubuntu:latest"
        ],
        "RepoDigests": [
            "ubuntu@sha256:7c06e91f61fa88c08cc74f7e1b7c69ae24910d745357e0dfe1d2c0322aaf20f9"
        ],
        "Parent": "",
        "Comment": "",
        "Created": "2025-07-30T06:51:03.091147588Z",
        "DockerVersion": "24.0.7",
        "Author": "",
        "Architecture": "amd64",
        "Os": "linux",
        "Size": 78122494,
        "GraphDriver": {
            "Data": {
                "MergedDir": "/var/lib/docker/overlay2/8a59ab09262cee8d6004dcd5b978cd668baae2521d83a0621e5d1366fbd864a1/merged",
                "UpperDir": "/var/lib/docker/overlay2/8a59ab09262cee8d6004dcd5b978cd668baae2521d83a0621e5d1366fbd864a1/diff",
                "WorkDir": "/var/lib/docker/overlay2/8a59ab09262cee8d6004dcd5b978cd668baae2521d83a0621e5d1366fbd864a1/work"
            },
            "Name": "overlay2"
        },
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:cd9664b1462ea111a41bdadf65ce077582cdc77e28683a4f6996dd03afcc56f5"
            ]
        },
        "Metadata": {
            "LastTagTime": "0001-01-01T00:00:00Z"
        },
        "Config": {
            "Cmd": [
                "/bin/bash"
            ],
            "Entrypoint": null,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Labels": {
                "org.opencontainers.image.ref.name": "ubuntu",
                "org.opencontainers.image.version": "24.04"
            },
            "OnBuild": null,
            "User": "",
            "Volumes": null,
            "WorkingDir": ""
        }
    }
]
```

### docker container

<table id="bkmrk-command-description--1"><thead><tr><th class="text-left">**Command**</th><th class="text-left">**Description**</th></tr></thead><tbody><tr><td class="text-left">[`docker container attach`](https://docs.docker.com/reference/cli/docker/container/attach/)</td><td class="text-left">Attach local standard input, output, and error streams to a running container</td></tr><tr><td class="text-left">[`docker container commit`](https://docs.docker.com/reference/cli/docker/container/commit/)</td><td class="text-left">Create a new image from a container's changes</td></tr><tr><td class="text-left">[`docker container cp`](https://docs.docker.com/reference/cli/docker/container/cp/)</td><td class="text-left">Copy files/folders between a container and the local filesystem</td></tr><tr><td class="text-left">[`docker container create`](https://docs.docker.com/reference/cli/docker/container/create/)</td><td class="text-left">Create a new container</td></tr><tr><td class="text-left">[`docker container diff`](https://docs.docker.com/reference/cli/docker/container/diff/)</td><td class="text-left">Inspect changes to files or directories on a container's filesystem</td></tr><tr><td class="text-left">[`docker container exec`](https://docs.docker.com/reference/cli/docker/container/exec/)</td><td class="text-left">Execute a command in a running container</td></tr><tr><td class="text-left">[`docker container export`](https://docs.docker.com/reference/cli/docker/container/export/)</td><td class="text-left">Export a container's filesystem as a tar archive</td></tr><tr><td class="text-left">[`docker container inspect`](https://docs.docker.com/reference/cli/docker/container/inspect/)</td><td class="text-left">Display detailed information on one or more containers</td></tr><tr><td class="text-left">[`docker container kill`](https://docs.docker.com/reference/cli/docker/container/kill/)</td><td class="text-left">Kill one or more running containers</td></tr><tr><td class="text-left">[`docker container logs`](https://docs.docker.com/reference/cli/docker/container/logs/)</td><td class="text-left">Fetch the logs of a container</td></tr><tr><td class="text-left">[`docker container ls`](https://docs.docker.com/reference/cli/docker/container/ls/)</td><td class="text-left">List containers</td></tr><tr><td class="text-left">[`docker container pause`](https://docs.docker.com/reference/cli/docker/container/pause/)</td><td class="text-left">Pause all processes within one or more containers</td></tr><tr><td class="text-left">[`docker container port`](https://docs.docker.com/reference/cli/docker/container/port/)</td><td class="text-left">List port mappings or a specific mapping for the container</td></tr><tr><td class="text-left">[`docker container prune`](https://docs.docker.com/reference/cli/docker/container/prune/)</td><td class="text-left">Remove all stopped containers</td></tr><tr><td class="text-left">[`docker container rename`](https://docs.docker.com/reference/cli/docker/container/rename/)</td><td class="text-left">Rename a container</td></tr><tr><td class="text-left">[`docker container restart`](https://docs.docker.com/reference/cli/docker/container/restart/)</td><td class="text-left">Restart one or more containers</td></tr><tr><td class="text-left">[`docker container rm`](https://docs.docker.com/reference/cli/docker/container/rm/)</td><td class="text-left">Remove one or more containers</td></tr><tr><td class="text-left">[`docker container run`](https://docs.docker.com/reference/cli/docker/container/run/)</td><td class="text-left">Create and run a new container from an image</td></tr><tr><td class="text-left">[`docker container start`](https://docs.docker.com/reference/cli/docker/container/start/)</td><td class="text-left">Start one or more stopped containers</td></tr><tr><td class="text-left">[`docker container stats`](https://docs.docker.com/reference/cli/docker/container/stats/)</td><td class="text-left">Display a live stream of container(s) resource usage statistics</td></tr><tr><td class="text-left">[`docker container stop`](https://docs.docker.com/reference/cli/docker/container/stop/)</td><td class="text-left">Stop one or more running containers</td></tr><tr><td class="text-left">[`docker container top`](https://docs.docker.com/reference/cli/docker/container/top/)</td><td class="text-left">Display the running processes of a container</td></tr><tr><td class="text-left">[`docker container unpause`](https://docs.docker.com/reference/cli/docker/container/unpause/)</td><td class="text-left">Unpause all processes within one or more containers</td></tr><tr><td class="text-left">[`docker container update`](https://docs.docker.com/reference/cli/docker/container/update/)</td><td class="text-left">Update configuration of one or more containers</td></tr><tr><td class="text-left">[`docker container wait`](https://docs.docker.com/reference/cli/docker/container/wait/)</td><td class="text-left">Block until one or more containers stop, then print their exit codes</td></tr></tbody></table>

```json
debian@debian:~$ docker inspect c5
[
    {
        "Id": "f5f93155c9e02fc6a56d40b6d1bf5d0f3cd5c73106c72882f8878038398fe158",
        "Created": "2025-08-29T20:35:19.745912071Z",
        "Path": "/bin/bash",
        "Args": [],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 3405,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2025-08-29T20:35:19.948819333Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
        "Image": "sha256:e0f16e6366fef4e695b9f8788819849d265cde40eb84300c0147a6e5261d2750",
        "ResolvConfPath": "/var/lib/docker/containers/f5f93155c9e02fc6a56d40b6d1bf5d0f3cd5c73106c72882f8878038398fe158/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/f5f93155c9e02fc6a56d40b6d1bf5d0f3cd5c73106c72882f8878038398fe158/hostname",
        "HostsPath": "/var/lib/docker/containers/f5f93155c9e02fc6a56d40b6d1bf5d0f3cd5c73106c72882f8878038398fe158/hosts",
        "LogPath": "/var/lib/docker/containers/f5f93155c9e02fc6a56d40b6d1bf5d0f3cd5c73106c72882f8878038398fe158/f5f93155c9e02fc6a56d40b6d1bf5d0f3cd5c73106c72882f8878038398fe158-json.log",
        "Name": "/c5",
        "RestartCount": 0,
        "Driver": "overlay2",
        "Platform": "linux",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "docker-default",
        "ExecIDs": null,
        "HostConfig": {
            "Binds": null,
            "ContainerIDFile": "",
            "LogConfig": {
                "Type": "json-file",
                "Config": {}
            },
            "NetworkMode": "bridge",
            "PortBindings": {},
            "RestartPolicy": {
                "Name": "no",
                "MaximumRetryCount": 0
            },
            "AutoRemove": false,
            "VolumeDriver": "",
            "VolumesFrom": null,
            "ConsoleSize": [
                54,
                235
            ],
            "CapAdd": null,
            "CapDrop": null,
            "CgroupnsMode": "private",
            "Dns": [],
            "DnsOptions": [],
            "DnsSearch": [],
            "ExtraHosts": null,
            "GroupAdd": null,
            "IpcMode": "private",
            "Cgroup": "",
            "Links": null,
            "OomScoreAdj": 0,
            "PidMode": "",
            "Privileged": false,
            "PublishAllPorts": false,
            "ReadonlyRootfs": false,
            "SecurityOpt": null,
            "UTSMode": "",
            "UsernsMode": "",
            "ShmSize": 67108864,
            "Runtime": "runc",
            "Isolation": "",
            "CpuShares": 0,
            "Memory": 0,
            "NanoCpus": 0,
            "CgroupParent": "",
            "BlkioWeight": 0,
            "BlkioWeightDevice": [],
            "BlkioDeviceReadBps": [],
            "BlkioDeviceWriteBps": [],
            "BlkioDeviceReadIOps": [],
            "BlkioDeviceWriteIOps": [],
            "CpuPeriod": 0,
            "CpuQuota": 0,
            "CpuRealtimePeriod": 0,
            "CpuRealtimeRuntime": 0,
            "CpusetCpus": "",
            "CpusetMems": "",
            "Devices": [],
            "DeviceCgroupRules": null,
            "DeviceRequests": null,
            "MemoryReservation": 0,
            "MemorySwap": 0,
            "MemorySwappiness": null,
            "OomKillDisable": null,
            "PidsLimit": null,
            "Ulimits": [],
            "CpuCount": 0,
            "CpuPercent": 0,
            "IOMaximumIOps": 0,
            "IOMaximumBandwidth": 0,
            "MaskedPaths": [
                "/proc/asound",
                "/proc/acpi",
                "/proc/interrupts",
                "/proc/kcore",
                "/proc/keys",
                "/proc/latency_stats",
                "/proc/timer_list",
                "/proc/timer_stats",
                "/proc/sched_debug",
                "/proc/scsi",
                "/sys/firmware",
                "/sys/devices/virtual/powercap"
            ],
            "ReadonlyPaths": [
                "/proc/bus",
                "/proc/fs",
                "/proc/irq",
                "/proc/sys",
                "/proc/sysrq-trigger"
            ]
        },
        "GraphDriver": {
            "Data": {
                "ID": "f5f93155c9e02fc6a56d40b6d1bf5d0f3cd5c73106c72882f8878038398fe158",
                "LowerDir": "/var/lib/docker/overlay2/9c831cc72a1726631cb4c9e776e29e8192a4793b9172c2fabf2226fdfb8babb9-init/diff:/var/lib/docker/overlay2/8a59ab09262cee8d6004dcd5b978cd668baae2521d83a0621e5d1366fbd864a1/diff",
                "MergedDir": "/var/lib/docker/overlay2/9c831cc72a1726631cb4c9e776e29e8192a4793b9172c2fabf2226fdfb8babb9/merged",
                "UpperDir": "/var/lib/docker/overlay2/9c831cc72a1726631cb4c9e776e29e8192a4793b9172c2fabf2226fdfb8babb9/diff",
                "WorkDir": "/var/lib/docker/overlay2/9c831cc72a1726631cb4c9e776e29e8192a4793b9172c2fabf2226fdfb8babb9/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [],
        "Config": {
            "Hostname": "f5f93155c9e0",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "Tty": true,
            "OpenStdin": true,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "/bin/bash"
            ],
            "Image": "ubuntu",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {
                "org.opencontainers.image.ref.name": "ubuntu",
                "org.opencontainers.image.version": "24.04"
            }
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "34132282ba3e544d46aec112f27ed949a571b114ebc2fee664fc034776e06be7",
            "SandboxKey": "/var/run/docker/netns/34132282ba3e",
            "Ports": {},
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "c239ab855b930537d28d6ebe5343f7eb9241eca8c7e086fe9894aa19c5f7cce7",
            "Gateway": "172.17.0.1",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "172.17.0.2",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
            "MacAddress": "56:4e:03:5c:c5:d4",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "MacAddress": "56:4e:03:5c:c5:d4",
                    "DriverOpts": null,
                    "GwPriority": 0,
                    "NetworkID": "e5ee2347d56211a8f10602c4ebc07b27a15b2f9507af47f3c7c16bdbcf18fc6c",
                    "EndpointID": "c239ab855b930537d28d6ebe5343f7eb9241eca8c7e086fe9894aa19c5f7cce7",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.2",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "DNSNames": null
                },
                "reseau2": {
                    "IPAMConfig": {},
                    "Links": null,
                    "Aliases": [],
                    "MacAddress": "5a:76:dd:aa:62:15",
                    "DriverOpts": {},
                    "GwPriority": 0,
                    "NetworkID": "562ad4a6e8b3105f619bd0deb30b89d5aaddde71babd6422ad912ccfa327687d",
                    "EndpointID": "f71251f1d3c4d9be09376f687898d22a984017b91f6da6c8fe75fa65dedba007",
                    "Gateway": "172.19.0.1",
                    "IPAddress": "172.19.0.2",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "DNSNames": [
                        "c5",
                        "f5f93155c9e0"
                    ]
                }
            }
        }
    }
]
```

### docker volume

<table id="bkmrk-command-description--2"><thead><tr><th class="text-left">**Command**</th><th class="text-left">**Description**</th></tr></thead><tbody><tr><td class="text-left">[`docker volume create`](https://docs.docker.com/reference/cli/docker/volume/create/)</td><td class="text-left">Create a volume</td></tr><tr><td class="text-left">[`docker volume inspect`](https://docs.docker.com/reference/cli/docker/volume/inspect/)</td><td class="text-left">**Display detailed information on one or more volumes**</td></tr><tr><td class="text-left">[`docker volume ls`](https://docs.docker.com/reference/cli/docker/volume/ls/)</td><td class="text-left">List volumes</td></tr><tr><td class="text-left">[`docker volume prune`](https://docs.docker.com/reference/cli/docker/volume/prune/)</td><td class="text-left">Remove unused local volumes</td></tr><tr><td class="text-left">[`docker volume rm`](https://docs.docker.com/reference/cli/docker/volume/rm/)</td><td class="text-left">Remove one or more volumes</td></tr><tr><td class="text-left">[`docker volume update`](https://docs.docker.com/reference/cli/docker/volume/update/)</td><td class="text-left">Update a volume (cluster volumes only)</td></tr></tbody></table>

[![image.png](https://formation.tfrichet.fr/uploads/images/gallery/2025-08/scaled-1680-/KcPPlrZMENIKIevl-image.png)](https://formation.tfrichet.fr/uploads/images/gallery/2025-08/KcPPlrZMENIKIevl-image.png)

### docker network

<table id="bkmrk-command-description--3"><thead><tr><th class="text-left">**Command**</th><th class="text-left">**Description**</th></tr></thead><tbody><tr><td class="text-left">[`docker network connect`](https://docs.docker.com/reference/cli/docker/network/connect/)</td><td class="text-left">Connect a container to a network</td></tr><tr><td class="text-left">[`docker network create`](https://docs.docker.com/reference/cli/docker/network/create/)</td><td class="text-left">Create a network</td></tr><tr><td class="text-left">[`docker network disconnect`](https://docs.docker.com/reference/cli/docker/network/disconnect/)</td><td class="text-left">Disconnect a container from a network</td></tr><tr><td class="text-left">[`docker network inspect`](https://docs.docker.com/reference/cli/docker/network/inspect/)</td><td class="text-left">Display detailed information on one or more networks</td></tr><tr><td class="text-left">[`docker network ls`](https://docs.docker.com/reference/cli/docker/network/ls/)</td><td class="text-left">List networks</td></tr><tr><td class="text-left">[`docker network prune`](https://docs.docker.com/reference/cli/docker/network/prune/)</td><td class="text-left">Remove all unused networks</td></tr><tr><td class="text-left">[`docker network rm`](https://docs.docker.com/reference/cli/docker/network/rm/)</td><td class="text-left">Remove one or more networks</td></tr></tbody></table>

[![image.png](https://formation.tfrichet.fr/uploads/images/gallery/2025-08/scaled-1680-/m5C1fUPv4cQk9Rf8-image.png)](https://formation.tfrichet.fr/uploads/images/gallery/2025-08/m5C1fUPv4cQk9Rf8-image.png)

### docker stats

La commande `docker stats` affiche les informations essentielles des conteneurs actuellement lancés. Par défaut, la commande s'actualise toutes les 2 secondes.

[![image.png](https://formation.tfrichet.fr/uploads/images/gallery/2025-08/scaled-1680-/88bPpB5h2yRXIkV8-image.png)](https://formation.tfrichet.fr/uploads/images/gallery/2025-08/88bPpB5h2yRXIkV8-image.png)

### docker system

<table id="bkmrk-command-description--4"><thead><tr><th class="text-left">**Command**</th><th class="text-left">**Description**</th></tr></thead><tbody><tr><td class="text-left">[`docker system df`](https://docs.docker.com/reference/cli/docker/system/df/)</td><td class="text-left">Show docker disk usage</td></tr><tr><td class="text-left">[`docker system events`](https://docs.docker.com/reference/cli/docker/system/events/)</td><td class="text-left">Get real time events from the server</td></tr><tr><td class="text-left">[`docker system info`](https://docs.docker.com/reference/cli/docker/system/info/)</td><td class="text-left">Display system-wide information</td></tr><tr><td class="text-left">[`docker system prune`](https://docs.docker.com/reference/cli/docker/system/prune/)</td><td class="text-left">Remove unused data</td></tr></tbody></table>

[![image.png](https://formation.tfrichet.fr/uploads/images/gallery/2025-08/scaled-1680-/q5rCb7LoqsWxSIWd-image.png)](https://formation.tfrichet.fr/uploads/images/gallery/2025-08/q5rCb7LoqsWxSIWd-image.png)

# Administration avec Portainer

### Interface graphique Portainer

Portainer est une interface web qui permet de gérer facilement des environnements Docker. Elle simplifie l'administration des conteneurs, images, volumes et réseaux sans avoir à utiliser la ligne de commande.

[![image.png](https://formation.tfrichet.fr/uploads/images/gallery/2025-08/scaled-1680-/0HqJnnWRaIeciMq4-image.png)](https://formation.tfrichet.fr/uploads/images/gallery/2025-08/0HqJnnWRaIeciMq4-image.png)

Portainer est une solution commerciale basée sur un outil open-source.Ci-dessous un extrait du site [ 🔗 docs.portainer.io](https://docs.portainer.io/) :

> **Portainer Community Edition (CE)** is our foundation. With over half a million regular users, CE is a powerful, open source toolset that allows you to easily build and manage containers in Docker, Docker Swarm, Kubernetes and Azure ACI.
> 
> **Portainer Business Edition (BE)** is our commercial offering. With features geared towards businesses and larger organizations such as [Role-Based Access Control](https://docs.portainer.io/admin/user/roles), [registry management](https://docs.portainer.io/admin/registries/browse), and [dedicated support](https://docs.portainer.io/#getting-support), Portainer BE is a powerful toolset that allows you to easily build and manage containers in Docker, Docker Swarm, Kubernetes, Podman and Azure ACI.

Nous utiliserons **Portainer Community Edition (CE)**.

### Installation

<p class="callout info">La procédure d'installation détaillée est disponible sur [ 🔗 docs.portainer.io](https://docs.portainer.io/start/install-ce/server/docker/linux).</p>

L'installation de Portainer s'effectue simplement avec une image docker :

```bash
docker volume create portainer_data
docker run -d -p 8000:8000 -p 9443:9443 --name portainer --restart=always \
-v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:lts

```

Portainer est accessible à l'adresse : [ 🔗 ](https://127.0.0.1:9443/)[https://127.0.0.1:9443/](https://127.0.0.1:9443/).

<p class="callout warning">Remplacez 127.0.0.1 par l'IP de votre hôte docker si nécessaire.</p>

La création d'un utilisateur est obligatoire avant la première connexion.

[![image.png](https://formation.tfrichet.fr/uploads/images/gallery/2025-08/scaled-1680-/n9LmUAM0yloJKFBp-image.png)](https://formation.tfrichet.fr/uploads/images/gallery/2025-08/n9LmUAM0yloJKFBp-image.png)

Il faut ensuite sélectionner l'environnement local.

[![image.png](https://formation.tfrichet.fr/uploads/images/gallery/2025-08/scaled-1680-/MmBghWudeqj5RZJQ-image.png)](https://formation.tfrichet.fr/uploads/images/gallery/2025-08/MmBghWudeqj5RZJQ-image.png)

L'administration des containers, images, volumes, network est disponible.

[![image.png](https://formation.tfrichet.fr/uploads/images/gallery/2025-08/scaled-1680-/EIuhypLARw2EWfwL-image.png)](https://formation.tfrichet.fr/uploads/images/gallery/2025-08/EIuhypLARw2EWfwL-image.png)

# Construction d'image avec Dockerfile

### Dockerfile et layers

Les images Docker fonctionnent par couches successives d'instructions, **les layers**.

Un **Dockerfile** est un fichier texte qui décrit les différentes couches d'une image Docker.

Chaque couche permet d'ajouter des actions à l'image, par exemple :

- Installation de dépendances
- Configuration d'un environnement
- Copie de fichiers depuis la machine hôte
- Définition de la commande lancée au démarrage du conteneur
- Etc.

<p class="callout info">Le dockerfile est comparable à une recette de cuisine : chaque instruction du Dockerfile représente une étape dans la préparation de l’environnement logiciel souhaité.</p>

Son utilisation offre certains avantages :

- **Automatisation** : chaque build est reproductible et scripté.
- **Traçabilité** : le fichier peut être versionné avec Git.
- **Portabilité** : un Dockerfile peut être utilisé sur n'importe quelle machine.
- **Modularité** : il permet de construire des images à partir d’autres images, facilitant la réutilisation.

Ci-dessous un exemple de Dockerfile :

```bash
FROM debian:trixie # point de départ : une image existante
RUN apt-get update -y # commande à éxécuter
RUN apt-get install fastfetch -y # une autre commande, pour une nouvelle couche
ENTRYPOINT ["fastfetch"] # point d'entrée au lancement du conteneur
```

### Les instructions d'un Dockerfile

<p class="callout info">N'hésitez pas à consulter la documentation de Docker à ce sujet : [🔗 Dockerfile reference](https://docs.docker.com/reference/dockerfile/).</p>

#### `FROM` - Définir l'image de base

```bash
FROM ubuntu:24.04
```

C'est le point de départ de l'image : une autre image de base officielle ou personnalisée.

#### `LABEL` - Ajouter des métadonnées

```bash
LABEL Maintainer="Thibaud FRICHET"
LABEL Description="Description de l'image"
```

Les métadonnées de l'image s'affichent avec `docker image inspect`.

#### `WORKDIR` - Définir le répertoire de travail

```bash
WORKDIR /var/www/html
```

Les instructions `RUN`, `CMD` et `ENTRYPOINT` s’exécutent dans le répertoire de travail.

#### `COPY` - Copier des fichiers locaux dans l'image

```bash
# copie fichier.txt à partir du répertoire courant de la machine hôte
# dans le répertoire courant de l'image (défini avec WORKDIR)
COPY fichier.txt ./ 

# copie le répertoire sources depuis la machine hôte vers le répertoire /var/www de l'image
COPY /home/thibaud/projet/sources/ /var/www/
```

#### `RUN` - Exécuter des commandes pendant la construction

```bash
# installation et lancement de Redis
RUN apt-get update -y
RUN apt-get install redis-server -y
RUN service redis-server start
```

Les commandes `RUN` s’exécutent pendant la construction de l'image, pas au démarrage d'un conteneur.

<p class="callout warning">Les commandes doivent se terminer sans saisie utilisateur.</p>

##### `EXPOSE` - Indiquer les ports utilisés par l'application

```bash
EXPOSE 80
EXPOSE 443
```

Ce sont les ports d'écoute du conteneur, ils peuvent être redirigés avec `docker run -p 90:80` à l'exécution.

##### `CMD` - Définir les commandes par défaut à exécuter

L'instruction CMD accepte un tableau en paramètre.

```bash
CMD ["date", "echo Bonjour"] # affiche la date courante, puis "Bonjour"
```

Contrairement à `RUN`, l'instruction `CMD` est exécutée au démarrage du conteneur, pas pendant la construction.

##### `ENTRYPOINT` - Définir le point d'entrée du conteneur

```bash
ENTRYPOINT ["service nginx start"] # lance le serveur web nginx
```

`CMD` et `ENTRYPOINT` définissent les commandes exécutées au démarrage d'un conteneur, mais avec un comportement différent :

- `CMD` indique la commande avec des arguments par défaut qui peuvent être remplacés lors de l’exécution avec docker run.
- `ENTRYPOINT` fixe le point d’entrée du conteneur, rendant son comportement plus rigide.

Lorsqu’ils sont utilisés ensemble, `ENTRYPOINT` définit le programme à exécuter et `CMD` les arguments par défaut.

<p class="callout info">Dans la majorité des cas, vous pouvez utiliser l'un ou l'autre uniquement.</p>

### Bonnes pratiques

- Utilisez des images légères. Exemples : `python:3.10-slim`, `nginx-stable-alpine`, etc.
- Utilisez des versions fixes dans vos dépendances. Évitez les tags `-latest` par exemple.
- Minimisez le nombre de couches, par exemple avec plusieurs commandes sur une ligne `RUN` et `&&`.  
    ```
    RUN apt-get update -y && apt-get install redis-server
    ```
- Utilisez `.dockerignore` pour exclure les fichiers inutiles, de la même manière qu'un `.gitignore`.  
    Le contenu du répertoire courant de la machine hôte est envoyé à Docker lors de la construction d'une image. Docker appelle cela le `context`.
- Respectez la convention de nommage d'un dockerfile : 
    - Par défaut : `Dockerfile`
    - Avec un préfixe : `dev.Dockerfile`, `prod.Dockerfile`, `app-v3.Dockerfile`

### La construction de l'image

La construction d'une image docker s'effectue avec `docker build`.

Le paramètre `-t`, `--tag` indique le nom de l'image et sa version. Le paramètre `-f`, `--file` le nom du fichier dockerfile, par défaut `Dockerfile`.

Un répertoire de contexte doit être indiqué, par exemple le répertoire courant avec `.`.

```bash
docker build -t mon_appli:1.0.0 -f monappli.Dockerfile .
```

[![image.png](https://formation.tfrichet.fr/uploads/images/gallery/2025-09/scaled-1680-/tZrv72npXnLC5DX7-image.png)](https://formation.tfrichet.fr/uploads/images/gallery/2025-09/tZrv72npXnLC5DX7-image.png)

[![image.png](https://formation.tfrichet.fr/uploads/images/gallery/2025-09/scaled-1680-/AJw5mu7IRM7XQskp-image.png)](https://formation.tfrichet.fr/uploads/images/gallery/2025-09/AJw5mu7IRM7XQskp-image.png)

<p class="callout info">Par la suite, une image Docker peut être exportée dans un fichier ou uploadée sur un registre privé par exemple.</p>

# TP : Création d'une image Docker

### Objectif

L'objectif est de **construire une image** qui embarque un script Python accessible en web.

<p class="callout info">Aucune connaissance de Python n'est requise.</p>

### Consignes

#### 1 - Téléchargement de l'application

Téléchargez le fichier zip suivant et dézippez-le.

**[🔗 https://formation-tfrichet-assets.s3.fr-par.scw.cloud/docker-tp-2/docker-tp-2.zip](https://formation-tfrichet-assets.s3.fr-par.scw.cloud/docker-tp-2/docker-tp-2.zip)**

Vous obtenez un dossier `app`.

[![image.png](https://formation.tfrichet.fr/uploads/images/gallery/2025-09/scaled-1680-/OifzVjWzhc98uEVw-image.png)](https://formation.tfrichet.fr/uploads/images/gallery/2025-09/OifzVjWzhc98uEVw-image.png)

#### 2 - Création du Dockerfile

**Créez et buildez** un Dockerfile en respectant les consignes ci-dessous.

- L'image de départ est `python:3.10-slim`.
- Le répertoire de travail est `/app`.
- Pendant la construction de l'image, les commandes doivent être exécutées :  
    ```bash
    apt-get update && apt-get install -y procps
    pip install flask
    ```
- L'application (dossier `app` téléchargé) doit être copiée dans le répertoire de travail de l'image.
- L'image écoute sur le port `5000`.
- Les commandes suivantes sont exécutées au démarrage d'un conteneur : `python` et `app.py`.
- Nommez l'image `tp2`.

#### 3 - Exécution d'un conteneur

Exécutez un conteneur avec la commande ci-dessous. N'oubliez pas de renseigner votre nom.

```bash
docker run -ti --rm -p 5000:5000 -e NAME=VOTRE_NOM_ICI tp2
```

Rendez-vous sur [http://127.0.0.1:5000](http://127.0.0.1:5000).

### Résultat attendu

<p class="callout warning">Le contenu du Dockerfile et la capture d'écran ci-dessous sont attendus pour valider le TP.</p>

[![image.png](https://formation.tfrichet.fr/uploads/images/gallery/2025-09/scaled-1680-/OAQ8Oy4wG8RUSpSK-image.png)](https://formation.tfrichet.fr/uploads/images/gallery/2025-09/OAQ8Oy4wG8RUSpSK-image.png)