docker pull ubuntu:jammyjammy: Pulling from library/ubuntu
Digest: sha256:076e7bf82319619f28dd0aa9c02ab34b055ad37100395b4f49a2ffba04fb5e11
Status: Downloaded newer image for ubuntu:jammy
docker.io/library/ubuntu:jammy
Docker & OCI
À la fin de ce cours, vous saurez :
Une image suit la spécification OCI (Open Container Initiative).
[[registry/][namespace/]repository[:tag][@digest]].
repository : partie obligatoire qui identifie le dépôt (nom du répertoire).registry : hôte du registre (optionnel); si absent on entend en pratique le registre Docker Hub (docker.io).namespace : segment optionnel pour regrouper les dépôts (sur Docker Hub, l’espace library est implicite pour les images officielles).tag : référence optionnelle lisible (ex. :latest, :1.2.3); si aucun tag n’est fourni, latest est couramment utilisé comme valeur par défaut pour l’usage, mais l’absence de tag signifie que l’image peut aussi être désignée par un digest.digest : identifiant immuable optionnel (forme sha256:<hex>); lorsqu’il est présent (@digest) il prend la priorité sur le tag pour désigner de façon exacte une image. (Les parties entre crochets [] sont optionnelles selon la spécification de référence des images.)➡️ Une image n’est pas un conteneur mais le modèle de fichier utilisé pour en créer un ou plusieurs.
pull commande pour récupérer une image depuis un registry
ubuntu:jammydocker pull ubuntu:jammyjammy: Pulling from library/ubuntu
Digest: sha256:076e7bf82319619f28dd0aa9c02ab34b055ad37100395b4f49a2ffba04fb5e11
Status: Downloaded newer image for ubuntu:jammy
docker.io/library/ubuntu:jammy
docker history ubuntu:jammyIMAGE CREATED CREATED BY SIZE COMMENT
a7b0f6af3254 7 days ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
<missing> 7 days ago /bin/sh -c #(nop) ADD file:ba52f9eec2a5a7de7… 78.1MB
<missing> 7 days ago /bin/sh -c #(nop) LABEL org.opencontainers.… 0B
<missing> 7 days ago /bin/sh -c #(nop) ARG LAUNCHPAD_BUILD_ARCH 0B
<missing> 7 days ago /bin/sh -c #(nop) ARG RELEASE 0B
Avantages :
Méthode possible mais déconseillée :
docker commitLancer un conteneur Ubuntu : docker run --name my-ubuntu --interactive ubuntu:jammy bash
Installer Git en interactif : apt-get update && apt-get install -y git
Valider l’image et supprimer le conteneur intermédiaire.
docker commit my-ubuntu mygit:latest
docker rm my-ubuntusha256:3df476bc95503ad0f0b445de9e105f31529b5322b9fd013be019367002158771
my-ubuntu
mygit:latest est créée.docker run --label teaching-demo=true --rm mygit git --versiongit version 2.34.1
mygit.docker history mygitIMAGE CREATED CREATED BY SIZE COMMENT
3df476bc9550 3 seconds ago bash - 157MB
a7b0f6af3254 7 days ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
<missing> 7 days ago /bin/sh -c #(nop) ADD file:ba52f9eec2a5a7de7… 78.1MB
<missing> 7 days ago /bin/sh -c #(nop) LABEL org.opencontainers.… 0B
<missing> 7 days ago /bin/sh -c #(nop) ARG LAUNCHPAD_BUILD_ARCH 0B
<missing> 7 days ago /bin/sh -c #(nop) ARG RELEASE 0B
➡️ Une seule couche opaque ajoutée
Avantages :
# Exemple simple
FROM ubuntu:jammy
RUN apt-get update && apt-get install -y git
ENTRYPOINT ["git"]
CMD ["--version"][1;33m[WARNING][0m Git operation failed with status code: 128 Les exemples suivants sont accessibles dans le dépôt :
❌ : ebpro/sample-containers-python-helloworld
/home/jovyan/work/github/ebpro/sample-containers-python-helloworldClone Command:
git clone -b develop https://github.com/ebpro/sample-containers-python-helloworld.
├── 00_containers_L_introduction.html
├── 00_containers_L_introduction.pdf
├── 00_containers_L_introduction.qmd
├── 00_containers_P_101.html
├── 00_containers_P_101.pdf
├── 00_containers_P_101.qmd
├── 01_containers_L_usage.html
├── 01_containers_L_usage.pdf
├── 01_containers_L_usage.qmd
├── 02_containers_L_image.qmd
├── 02_containers_L_image.quarto_ipynb
├── 02_containers_P_image.qmd
├── 03_containers_L_java.qmd
├── 04_containers_L_orchestration.qmd
├── 10_java_P_revision.qmd
├── 11_containers_P_revision-shell.qmd
├── 12_containers_P_revision-sgbdr.qmd
└── mathjax-config.js
1 directory, 18 filesDockerfile
FROM : Image de base (ex: python:3.9).WORKDIR : Définit le dossier de travail (ex: /app).COPY : Copie les fichiers locaux dans l’image.RUN : Exécute des commandes : (ex. Installe les dépendances, pip install).ENTRYPOINT et CMD : Définit la commande par défaut.docker image build.
.dockerignore exclure des fichiers du contexte de build ce qui accélère et sécurise la construction,docker image build -t mon-app:0.0.1 .ERROR: failed to build: failed to solve: failed to read dockerfile: open Dockerfile: no such file or directory
: 1
docker run --label teaching-demo=true --rm mon-app:0.0.1Unable to find image 'mon-app:0.0.1' locally
docker: Error response from daemon: pull access denied for mon-app, repository does not exist or may require 'docker login': denied: requested access to the resource is denied
Run 'docker run --help' for more information
: 125
Faire l’exercice :
Étapes :
docker logindocker push)docker push docker.io/${DOCKERHUB_USERNAME}/app:latestL’instruction HEALTHCHECK permet de définir une commande pour vérifier la santé d’un conteneur en cours d’exécution. Docker exécute périodiquement cette commande et utilise son code de retour pour déterminer l’état du conteneur : 0 (sain), 1 (non sain) ou 2 (réservé).
Exemple :
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl --max-time 30 -f http://localhost/ || exit 1Options principales :
--interval: fréquence de vérification (ex. 30s).--timeout: délai maximum d’exécution de la commande (ex. 3s).--start-period: délai initial avant la première vérification (ex. 5s).--retries: nombre d’échecs consécutifs avant de considérer le conteneur comme non sain.Les HEALTHCHECK sont utiles pour l’orchestration (restart policies, load balancers) et pour détecter des services défaillants.
ENTRYPOINT + CMD = commande complèteCMD absent, arguments passés à docker run sont ajoutés à ENTRYPOINTENTRYPOINT absent, docker run utilise CMD ou les arguments passés| Directive | Rôle |
|---|---|
| ENTRYPOINT | Comportement principal |
| CMD | Paramètres remplaçables |
ENTRYPOINT ["git"]
CMD ["--version"]docker run mygit
docker run mygit status➡️ Image utilisable comme un programme
ENTRYPOINT / CMD["executable", "param1"] (Recommandé : transmet les signaux OS comme SIGTERM).executable param1 :
*) et l’interpolation des variables SHELLentrypoint.shFaire l’exercice :
Objectifs :
Fonctionnement :
FROM dans un DockerfileCOPY --from=...)[1;33m[WARNING][0m Git operation failed with status code: 128 Les exemples suivants sont accessibles dans le dépôt :
/home/jovyan/work/github/ebpro/sample-containers-cClone Command:
git clone -b develop https://github.com/ebpro/sample-containers-c: 128
docker image build \
--tag ${DOCKERHUB_USERNAME}/helloworld_c:0.0.1 \
.
docker run --label teaching-demo=true --rm ${DOCKERHUB_USERNAME}/helloworld_c:0.0.1 PaulERROR: failed to build: failed to solve: failed to read dockerfile: open Dockerfile: no such file or directory
Unable to find image 'brunoe/helloworld_c:0.0.1' locally
docker: Error response from daemon: pull access denied for brunoe/helloworld_c, repository does not exist or may require 'docker login': denied: requested access to the resource is denied
Run 'docker run --help' for more information
: 125
EXPOSE dans le Dockerfile pour documenter les ports utilisés-p / --publish dans docker run pour mapper les portsDans le Dockerfile :
EXPOSE 80docker run -p 8080:80 myappEXPOSE ne publie pas le port, il documente seulement.
Faire l’exercice :
Principes essentiels pour réduire la surface d’attaque et rendre les images sûres :
--mount=type=secret) ou des volumes/variables d’environnement au runtime.RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser@sha256:...) ou pinner les versions de paquets pour éviter des mises à jour non contrôlées.apt-get clean && rm -rf /var/lib/apt/lists/*).docker scan, trivy) et générer un SBOM. Ex : trivy image --severity HIGH,CRITICAL myimage:latest.--cap-drop), monter le FS en lecture seule quand possible (--read-only).RUN adduser -D appuser
USER appuserENV ni non plus dans ARG (persistants dans l’image)FROM alpine:3.18
# Dépendance nécessaire
RUN apk add --no-cache curl
# ARG pour une valeur non sensible (ex : URL ou nom d'environnement)
ARG API_URL=https://example.com/secure-data
# Utilisation du secret via BuildKit
RUN --mount=type=secret,id=api_key \
curl --max-time 30 -H "Authorization: Bearer $(cat /run/secrets/api_key)" \
${API_URL} -o /tmp/data.json
# On peut ajouter un step pour vérifier que le fichier existe
RUN test -f /tmp/data.json
CMD ["cat", "/tmp/data.json"]docker build \
--secret id=api_key,src=./api_key.txt \
-t myapp:latest .docker buildx ou docker build --platform#| echo: true
#| output: true
docker build \
--platform linux/amd64,linux/arm64 \
-t docker.io/${DOCKERHUB_USERNAME}/helloworld_c:0.0.1 \
.docker buildx build --push.Dockerfile pour créer des imagesENTRYPOINT définit le comportementCMD fournit des arguments par défautpush Publier sur un registry