====== Docker - Prise de note ======
En cours de rédaction
Prise de note sur la mise en place de Docker, avec bonne pratique et outils intéressant.
===== Définition =====
* **Container**: Une instance exécutable d'une image. Isolé des autres containers
* **Image**: Un file system. Contient l'application, les dépendances, la configuration, les variables et une commande par défaut a exécuter
* **Volume**: Une connexion vers un file system disponible sur la machine host
* **Container network**: Par défaut un container est isolé, pour qu'ils puissent discuter entre eux, il faut définir un réseau de container
===== Installation =====
L'installation se base sur une Debian 12 propre ([[article:linux:debian_12_-_perfect_server|]])
Installation du respository:
wget https://download.docker.com/linux/debian/gpg -O /etc/apt/keyrings/docker.asc
chmod a+r /etc/apt/keyrings/docker.asc
echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian bookworm stable" > /etc/apt/source.list.d/docker.list
apt update
A partir de là, nous pouvons installer docker
apt install docker-ce
**Note: ** Docker va installer git et iptables
(**Recommandé**) Pour qu'un utilisateur non-root puisse epxloiter docker, nous devons l'ajouter au groupe "docker"
usermod -aG docker
===== Commande de base =====
Source: https://docs.docker.com/reference/cli/docker/
==== docker run ====
(Alias de : ''docker container run'') \\
Exécute un nouveau container
docker run [--detach|-d] [--publish|-p ] [--tty|-t] [--interactive|-i] [--name=] [--mount type=,src=,dst=]
**--detach (-d)** - Sinon le contenu de la console est accroché à notre terminal \\
**--publish (-p)** - Expose le port du container. Exemple : 80:1234 - Expose le pose 1234 du container sur le port 80 de la machine hôte \\
**--tty (-t)** - Va de paire avec --interactive. Alloue un terminal dans le container \\
**--interactive (-i)** - Va de paire avec --tty. Permet d'interagir avec le container \\
**--name=** - Attribue un nom au container. Sinon un nom aléatoire sera défini \\
**--mount** - Défini un point de montage d'un volume. Type: bind = Chemin, volume = Volume existant ([[https://docs.docker.com/reference/cli/docker/container/run/#mount|Plus d'info]]
**** - Nom de l'image a démarrer. Si elle n'existe pas, elle sera téléchargé depuis le [[https://hub.docker.com/|Docker Hub]]
==== docker ps ====
(Alias de : ''docker container ls'') \\
Affiche les containers en cours d'exécution
docker ps [--all|-a]
**--all (-a)** - Affiche également les containers éteint
==== docker stop ====
(Alias de : ''docker container stop'') \\
Arrête un container
docker stop [--time|-t ]
**** - Nom du container
**--time (-t)** - Indique si le container doit être tué s'il ne s'arrête pas proprement dans le temps indiqué
==== docker rm ====
(Alias de : ''docker container rm'') \\
Supprimer un container
docker rm [--force|-f]
**--force (-f)** - Force la suppression du container. S'il est en cours d'utilisation, envoi un SIGKILL au container
==== docker container prune ====
Supprime l'ensemble des containers qui ne sont plus en cours d'utilisation. \\
**Note: ** "prune" fonctionne de la même manière avec des images (docker image prune) ou des volumes (docker volume prune)
==== docker build ====
(Alias de : ''docker image build'') \\
Construire une image sur base d'un Dockerfile. \\
Référence: https://docs.docker.com/reference/dockerfile/
docker build --tag=
**--tag (-t)** - Défini un nom et un tag d'une image. Par exemple: apache:latest
**** - Généralement simplement "." si nous nous trouvons dans le dossier contenant un Dockerfile.
==== docker volume ====
Crée un volume qui sera accessible par nos containers
docker volume create
Inspecter un volume existant, pour y connaitre son chemin par exemple
docker volume inspect
==== docker network create ====
Permet de créer un réseau de container
docker network create
Pour l'attacher a un docker:
docker run --network --network-alias
**--network-alias** - Permet d'attribuer un hostname au container.
==== docker exec ====
Permet d'exécuter une commande dans un container en cours d'exécution
docker exec -it
**-it** - = --interactive et --tty (cf docker run)
==== docker compose ====
Permet de décrire dans un fichier l'équivalent d'un ou plusieurs docker run. Ceci permettra la reproductivité sans erreur.\\
Référence: https://docs.docker.com/compose/compose-file/
docker compose up --detach|-d
**up** - Permet de démarrer la composition, a l'instar de **down** qui éteindra notre composition
**--detach (-d)** - Sinon le contenu de la console est accroché à notre terminal \\
Exemple:
services:
app:
image: node:18-alpine
command: sh -c "yarn install && yarn run dev"
ports:
- 3000:3000
working_dir: /app
volumes:
- ./:/app
environment:
MYSQL_HOST: mysql
MYSQL_USER: root
MYSQL_PASSWORD: secret
MYSQL_DB: todos
mysql:
image: mysql:8.0
volumes:
- todo-mysql-data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: secret
MYSQL_DATABASE: todos
volumes:
todo-mysql-data:
===== A investiguer =====
* [[https://github.com/hadolint/hadolint|hadolint]] - Linter pour Dockerfile
* [[https://github.com/aquasecurity/trivy|trivy]] - Scanner de sécurité dans une image
* [[https://bearstech.com/societe/blog/securiser-et-optimiser-le-build-des-images-docker-pour-vos-applications|bearstech.com]] - Bonnes pratiques
* [[https://workflow.bearstech.com/documentation/tutoriels/service-cron/|bearstech.com]] - Tâche automatisée avec les conteneurs
* [[https://bearstech.com/societe/blog/mettre-a-jour-les-images-docker-la-methode-de-bearstech|bearstech.com]] - Mettre à jour les images Docker
===== Cheatsheet - Docker Compose =====
[[https://docs.docker.com/compose/compose-file/]]
name: myapp
services:
my-service-1:
# Définition de l'image
image: debian:bookworm # [/][/][:|@]
depends_on:
- my-service-2
environment: # Variable envoyé dans le container
- APP_MODE=development
- LOGGING=verbose
# Définition du réseau
hostname: myapp.local # Définition d'un hostname supplémentaire à ce container (son premier hostname étant my-service-1)
ports: # [HOST:]CONTAINER[/PROTOCOL]
- "10080:80" # NAT le port 10080 du host vers le port 80 du container
- name: web # Long syntax
target: 80 # Container port
published: "10080" # Host port, Default: Random
host-ip: 127.0.0.1 # Default: 0.0.0.0
protocol: tcp # Default: tcp
app_protocol: http # Optional, hinter. TCP/IP level 4/OSI level 7
mode: host # ???
networks:
my-network-1: # Ajoute le container dans ce réseau
my-network-2: # Long syntax
aliases:
- myapp # Crée un hostname supplémentaire de ce container dans ce réseau
ipv4_address: 172.16.238.10 # Non recommandé - Risque de ne pas être reproductible
ipv6_address: 2001:3984:3989::10 # Idem ipv4_address
# Définition des volumes / Persistence de données
volumes:
- type: bind # https://docs.docker.com/storage/
# bind = Montage sur le FS host
# volume = Montage géré par Docker (Préféré par docker)
# tmpfs = Chargé en mémoire (Linux only)
source: /home/docker/myapp # Source sur le host
target: /myapp # Destination dans le container
read_only: true
bind: # Option uniquement si type = bind
create_host_path: true # Crée le répertoire s'il n'existe pas
volume: # Option uniquement si type = volume
nocopy: true # Ne copie pas les données du container lors de sa création
my-service-2:
...
networks: # Définition des réseaux
my-network-1:
my-network-2:
annotations
attach
build
blkio_config
cpu_count
cpu_percent
cpu_shares
cpu_period
cpu_quota
cpu_rt_runtime
cpu_rt_period
cpus
cpuset
cap_add
cap_drop
cgroup
cgroup_parent
command
configs
container_name
credential_spec
deploy
develop
device_cgroup_rules
devices
dns
dns_opt
dns_search
domainname
driver_opts
entrypoint
env_file
expose
extends
external_links
extra_hosts
group_add
healthcheck
init
ipc
isolation
labels
links
logging
mac_address
mem_limit
mem_reservation
mem_swappiness
memswap_limit
network_mode
oom_kill_disable
oom_score_adj
pid
pids_limit
platform
privileged
profiles
pull_policy
read_only
restart
runtime
scale
secrets
security_opt
shm_size
stdin_open
stop_grace_period
stop_signal
storage_opt
sysctls
tmpfs
tty
ulimits
user
userns_mode
uts
volumes_from
working_dir