Utilisation de Docker
Installation
Commençons par installer Docker :
# ajout du dépôt docker dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo # installation de docker dnf -y install docker-ce docker-ce-cli containerd.io docker-compose-plugin # démarrer Docker et l'activer systemctl enable --now docker # Utilitaire pour tester et attendre la disponibilité wget https://raw.githubusercontent.com/vishnubob/wait-for-it/refs/heads/master/wait-for-it.sh chmod a+rx wait-for-it.sh mv -v wait-for-it.sh /usr/bin/wait-for-it
Les images
Dans docker, les images sont des systèmes minimums prêts à être exploités pour des exécutions ou des déploiements de logiciels. Quelques manipulations (commandes docker image) :
## charger les images docker pull almalinux docker pull ubuntu ## lister les images docker images
Les conteneurs
Nous allons maintenant, à partir des images, créer des conteneurs (commandes docker container) :
## Une exécution docker run almalinux /bin/echo Hello ## Vérifier que le conteneur précédent est arrêté docker ps -a ## Vérifier AlmaLinux docker run almalinux /usr/bin/cat /etc/redhat-release | fgrep -i almaLinux ## Vérifier Ubuntu docker run ubuntu /usr/bin/apt list | fgrep -i bash | fgrep -i ubuntu ## Toujours le même noyau uname -r docker run almalinux /usr/bin/uname -r docker run ubuntu /usr/bin/uname -r docker run archlinux /usr/bin/uname -r ## Lister les conteneurs créés docker ps -a ## Stopper et supprimer les conteneurs créés docker stop $(docker ps -a -q) docker rm $(docker ps -a -q)
docker run -it almalinux /bin/bash [root@92afaafe4463 /]# uname -a Linux a7134dda282d 5.14.0-503.33.1.el9_5.x86_64 ... [root@92afaafe4463 /]# cat /etc/redhat-release AlmaLinux release 9.5 (Teal Serval) [root@92afaafe4463 /]# exit ## Visualiser les conteneurs (-a pour voir les stoppés) docker ps -a
## Conteneurs en arrière-plan docker run -itd almalinux /bin/bash ## Le visualiser docker ps -l # -l last ## Récupérer son ID ID=$(docker ps -l -q) # -q id echo "ID is $ID" ## Modifier le conteneur en arrière-plan docker exec $ID /bin/bash -c "echo hello > /tmp/hello.txt" docker exec $ID cat /tmp/hello.txt | fgrep hello docker stop $ID docker rm $ID
Faire des images
Continuons en créant et sauvegardant des images :
## Créer un conteneur docker run -idt almalinux /bin/bash ID=$(docker ps -a -q -l) echo "ID is $ID" ## Mettre a jour et ajouter httpd docker exec $ID dnf -y update docker exec $ID dnf -y install httpd ## Ou se trouve httpd ? docker exec $ID /usr/bin/whereis httpd ## Créer une image docker commit $ID my-httpd docker images ## Créer un conteneur 'my-httpd' avec ## httpd activé et redirection des ports docker run --name my-httpd -dt -p 8800:80 \ my-httpd /usr/sbin/httpd -D FOREGROUND ## Changer la page par défaut docker exec my-httpd /bin/bash \ -c 'echo httpd on docker > /var/www/html/index.html' ## Vérifier curl localhost:8800 | fgrep 'httpd on docker' ## Récupérer des informations docker inspect my-httpd ## Stop docker stop my-httpd docker rm my-httpd
Utiliser des Dockerfile
Nous allons maintenant créer des images de manière automatisée en utilisant des Dockerfile.
Une image pour java
rm -fr java-docker ## Créer un répertoire mkdir java-docker ## Créer le dockerfile cat > java-docker/Dockerfile <<FIN FROM almalinux LABEL desc="My Java 17" RUN dnf -y update RUN dnf -y install java-17-openjdk RUN dnf -y clean all FIN ## Construire une image docker build -t my-java:latest java-docker docker images ## Tester docker run my-java:latest java -version
Une image pour une application Spring-Boot
Nous pouvons maintenant créer une image pour déployer notre application Spring-Boot :
rm -fr myapp-docker ## Créer un répertoire mkdir myapp-docker ## Préparer le WAR dans le répertoire wget https://jean-luc-massat.pedaweb.univ-amu.fr/ens/cca/spring-app.war mv -v spring-app.war myapp-docker ## Créer le dockerfile cat > myapp-docker/Dockerfile <<FIN FROM my-java:latest LABEL desc="My SpringBoot App" WORKDIR /app COPY spring-app.war /app/spring-app.war EXPOSE 8081 ENTRYPOINT ["java", "-jar", "/app/spring-app.war"] FIN ## Construire une image docker build -t my-app:latest myapp-docker docker images ## Tester en mode interactif Control-C pour stopper docker run -it -p 9000:8081 my-app ## Tester en mode démon docker run --name my-app -dt -p 9000:8081 my-app ## Récupérer son adresse IP ipaddr=$(docker inspect \ --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' my-app) echo "IPAddr is $ipaddr" ## Pour attendre le démarrage wait-for-it -t 0 $ipaddr:8081 ## Tester my-app curl -L http://localhost:9000 | fgrep -i 'star war' ## Vérifier les logs docker container logs my-app ## Consulter les statistiques docker container stats --no-stream
Déployer avec une BD MySQL
Commençons par supprimer tous nos conteneurs :
docker stop $(docker ps -a -q) docker rm $(docker ps -a -q)
Continuons en chargeant une image MySQL :
docker pull docker.io/library/mysql docker images
Créons un réseau qui va permettre de relier les conteneurs MySql et Spring-Boot :
docker network create my-database
Créons et configurons le conteneur qui héberge notre BD :
docker run --name my-mysql --network my-database \ -e MYSQL_ROOT_PASSWORD=root \ -e MYSQL_USER=moviesuser \ -e MYSQL_PASSWORD=moviespass \ -e MYSQL_DATABASE=moviesdb -d mysql
Nous devons temporiser afin de nous assurer que la BD est opérationnelle :
## Récupérer adresse IP ipaddr=$(docker inspect \ --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' my-mysql) echo "IPAddr of my-mysql is $ipaddr" ## Pour attendre le démarrage wait-for-it -t 0 $ipaddr:3306
Créons maintenant l'image de notre application :
## Créer un répertoire mkdir myappmysql-docker ## Préparer le WAR dans le répertoire wget https://jean-luc-massat.pedaweb.univ-amu.fr/ens/cca/spring-app.war mv -v spring-app.war myappmysql-docker ## Créer le script de démarrage cat > myappmysql-docker/start.sh <<FIN java \ -Dspring.datasource.driver-class-name=com.mysql.jdbc.Driver \ -Dspring.datasource.url=jdbc:mysql://my-mysql:3306/moviesdb \ -Dspring.jpa.generate-ddl=true \ -Dspring.jpa.hibernate.ddl-auto=update \ -Dspring.datasource.username=moviesuser \ -Dspring.datasource.password=moviespass \ -jar spring-app.war FIN ## Créer le dockerfile cat > myappmysql-docker/Dockerfile <<FIN FROM my-java:latest LABEL desc="My SpringBoot App with MySql" WORKDIR /app COPY spring-app.war /app/spring-app.war COPY start.sh /app/start.sh EXPOSE 8081 ENTRYPOINT ["/bin/bash", "/app/start.sh"] FIN ## Construire une image docker build -t my-app-mysql:latest myappmysql-docker docker images
## Tester en mode interactif Control-C pour stopper docker run -it -p 9100:8081 --network my-database my-app-mysql:latest ## Tester en mode démon docker run --name my-app-mysql -dt -p 9100:8081 \ --network my-database my-app-mysql:latest ## Récupérer son adresse IP ipaddr=$(docker inspect \ --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' \ my-app-mysql) echo "IPAddr of my-app-mysql is $ipaddr" ## Pour attendre le démarrage wait-for-it -t 0 $ipaddr:8081 ## Tester my-app-mysql curl -L http://localhost:9100 | fgrep -i 'star war'
## Lister les tables docker run -i --network my-database --rm mysql mysql \ -hmy-mysql -umoviesuser -pmoviespass moviesdb \ <<< 'SELECT * FROM movie'
- Modifiez les données dans votre application (en passant par un tunnel ssh).
- Stoppez le conteneur Spring-Boot.
- Relancez-le et vérifiez que les données sont bien les mêmes.