Utilisation de Docker sur CentOS Stream 8

Docker est un outil de création de conteneurs qui permet facilement de créer des environnements d'exécution qui soient plus simples et moins coûteux que des machines virtuelles.

Installation et premiers essais

Placez-vous sur la VM serveur et assurez-vous d'avoir traité le TP sur l'agrandissement.

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 start docker
systemctl enable docker

Continuons avec quelques exemples (exécutez les commandes une à une) :

## charger l'image de centos
docker pull tgagor/centos:stream8

## lister les images
docker images

## Afficher Hello
docker run tgagor/centos:stream8 /bin/echo Hello

## Lancer un conteneur en mode interactif
docker run -it tgagor/centos:stream8 /bin/bash
[root@92afaafe4463 /]# uname -a
Linux 92afaafe4463 4.18.0-448.el8.x86_64 ...
[root@92afaafe4463 /]# cat /etc/redhat-release
CentOS Stream release 8
[root@92afaafe4463 /]# exit

## Visualiser les conteneurs (-a pour voir les stoppés)
docker ps -a

## Supprimer les conteneurs créés
docker rm $(docker ps -a -q)

## Lancer un conteneur en arrière plan 
docker run -itd tgagor/centos:stream8 /bin/bash

## Repérer son ID
docker ps

## Se connecter à ce conteneur
docker exec -it 864ddc9c3821 /bin/bash
[root@864ddc9c3821 /]# echo hello > /tmp/hello.txt
[root@864ddc9c3821 /]# exit

## Vérifier que c'est bien le même
docker exec -it 864ddc9c3821 /bin/bash -c "cat /tmp/hello.txt"

## Le stopper et le supprimer
docker stop 864ddc9c3821
docker rm 864ddc9c3821

Ajout de conteneurs et accès aux services

Continuons en créant et sauvegardant des images :

## Créer un conteneur avec httpd
docker run tgagor/centos:stream8 dnf -y install httpd
id=$(docker ps -a -q | head -1) 

## Créer une image
docker commit $id my-httpd
docker images

## Créer un conteneur avec httpd activé (et redirection des ports)
docker run -dt -p 8800:80 my-httpd /usr/sbin/apachectl -D FOREGROUND
id=$(docker ps -a -q | head -1) 

## Changer la page par défaut
docker exec $id /bin/bash -c 'echo httpd on docker > /var/www/html/index.html'

## Vérifier
curl localhost:8800

# Récupérer des informations
docker inspect $id

Utiliser des Dockerfile

Nous allons maintenant créer des images de manière automatisée en utilisant des Dockerfile.

Une image pour java

## Créer un répertoire
mkdir java-docker

## Créer le dockerfile
cat > java-docker/Dockerfile <<FIN

FROM tgagor/centos:stream8
MAINTAINER JeanLucMassat <jean-luc.massat@univ-amu.fr>
RUN dnf -y install java-17-openjdk
RUN dnf -y clean all

FIN

## Construire l'image
docker build -t my-java:latest java-docker
docker images

## Tester l'image
docker run my-java:latest java -version

Une image pour une appli Spring-Boot

Nous pouvons maintenant créer une image pour déployer notre application Spring-Boot :

## Créer un répertoire
mkdir myapp-docker

## Préparer l'application dans le répertoire
wget https://jean-luc-massat.pedaweb.univ-amu.fr/ens/asr/spring-app.zip
unzip spring-app.zip
mv -v spring-app.war myapp-docker

## Créer le dockerfile
cat > myapp-docker/Dockerfile <<FIN

FROM my-java:latest
MAINTAINER JeanLucMassat <jean-luc.massat@univ-amu.fr>
WORKDIR /app
COPY spring-app.war /app/spring-app.war
EXPOSE 8081
ENTRYPOINT ["java", "-jar", "/app/spring-app.war"]

FIN

## Construire l'image
docker build -t my-app:latest myapp-docker
docker images

## Tester l'image en mode interactif (la stopper avec Control-C)
docker run -it -p 9000:8081 my-app

## Tester l'image en mode démon
docker run -dt -p 9000:8081 my-app
# pour attendre le demarrage de l'application
sleep 25s
curl http://localhost:9000/movies

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 mysqldb --network my-database \
        -e MYSQL_ROOT_PASSWORD=root \
        -e MYSQL_USER=moviesuser \
        -e MYSQL_PASSWORD=moviespass \
        -e MYSQL_DATABASE=moviesdb -d mysql
mysqlId=$(docker ps -a -q | head -1)

Créons maintenant l'image de notre application :

## Créer un répertoire
mkdir myappmysql-docker

## Préparer l'application dans le répertoire
wget https://jean-luc-massat.pedaweb.univ-amu.fr/ens/asr/spring-app.zip
unzip spring-app.zip
mv -v spring-app.war myappmysql-docker

## Créer le dockerfile
cat > myappmysql-docker/Dockerfile <<FIN

FROM my-java:latest
MAINTAINER JeanLucMassat <jean-luc.massat@univ-amu.fr>
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

## 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://mysqldb: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

## Construire l'image
docker build -t my-app-mysql:latest myappmysql-docker
docker images

## Tester l'image en mode interactif (la stopper avec Control-C)
docker run -it -p 9000:8081 --network my-database my-app-mysql:latest

## Tester l'image en mode démon
docker run -dt -p 9000:8081 --network my-database my-app-mysql:latest
# pour attendre le demarrage de l'application
sleep 25s
curl http://localhost:9000/movies

Vous pouvez maintenant vérifier que les tables du conteneur MySql sont bien à jour :

docker exec -it $mysqlId /bin/bash
bash-4.4# mysql -u moviesuser -p
USE moviesdb;
SELECT * FROM movie;
exit
bash-4.4# exit

Dernière vérification :

  • 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.