Déploiement rapide de middlewares avec Docker Compose et conteneurs Docker

Installation de Nacos v2.2.2

Pour commencer, préparez les répertoires nécessaires sur votre hôte :

mkdir -p /srv/nacos/logs
mkdir -p /srv/nacos/conf
mkdir -p /srv/nacos/persist

Lancement direct via Docker :

docker run -d \
  --name nacos-mysql-mode \
  -e MODE=standalone \
  -e SPRING_DATASOURCE_PLATFORM=mysql \
  -e MYSQL_SERVICE_HOST=votre_hote_db \
  -e MYSQL_SERVICE_PORT=3306 \
  -e MYSQL_SERVICE_DB_NAME=nacos_config \
  -e MYSQL_SERVICE_USER=utilisateur \
  -e MYSQL_SERVICE_PASSWORD=mot_de_passe \
  -v /srv/nacos/logs:/home/nacos/logs \
  -v /srv/nacos/conf/application.properties:/home/nacos/conf/application.properties \
  -v /srv/nacos/persist:/home/nacos/data \
  -p 8848:8848 \
  nacos/nacos-server:v2.2.2

Alternative avec Docker Compose :

version: '3.8'

services:
  nacos-svc:
    image: nacos/nacos-server:v2.2.2
    container_name: nacos-svc
    restart: unless-stopped
    ports:
      - "8848:8848"
      - "9848:9848"
      - "9849:9849"
    environment:
      TZ: Europe/Paris
      MODE: standalone
      SPRING_DATASOURCE_PLATFORM: mysql
      MYSQL_SERVICE_HOST: adresse_base_de_donnees
      MYSQL_SERVICE_PORT: 3306
      MYSQL_SERVICE_USER: utilisateur_db
      MYSQL_SERVICE_PASSWORD: secret_db
      MYSQL_SERVICE_DB_NAME: nacos_config
      MYSQL_SERVICE_DB_PARAM: "characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC"
    volumes:
      - ./nacos/logs:/home/nacos/logs

Déploiement de MinIO — Stockage d'objets

Lancement via Docker

docker run -d \
  --name minio-server \
  -p 9000:9000 \
  -p 9001:9001 \
  -e "MINIO_ROOT_USER=admin" \
  -e "MINIO_ROOT_PASSWORD=admin123456" \
  -v /srv/minio/stockage:/data \
  -v /srv/minio/config:/root/.minio \
  minio/minio server --console-address ":9001" /data

Instance unique avec Docker Compose

version: '3.8'

services:
  minio-standalone:
    image: minio/minio
    hostname: minio-standalone
    restart: always
    privileged: true
    ports:
      - "9000:9000"
      - "9001:9001"
    environment:
      MINIO_ACCESS_KEY: admin
      MINIO_SECRET_KEY: admin123456
    volumes:
      - ./minio-data:/data
      - ./minio-config:/root/.minio/
    command: server --console-address ':9001' /data

Déploiement en cluster

version: '3.8'

services:
  minio-node1:
    image: minio/minio
    hostname: minio-node1
    volumes:
      - node1-vol1:/data1
      - node1-vol2:/data2
    expose:
      - "9000"
      - "9001"
    environment:
      MINIO_ROOT_USER: minio
      MINIO_ROOT_PASSWORD: minio123456
    command: server --console-address ":9001" http://minio-node{1...4}/data{1...2}
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
      interval: 30s
      timeout: 20s
      retries: 3

  minio-node2:
    image: minio/minio
    hostname: minio-node2
    volumes:
      - node2-vol1:/data1
      - node2-vol2:/data2
    expose:
      - "9000"
      - "9001"
    environment:
      MINIO_ROOT_USER: minio
      MINIO_ROOT_PASSWORD: minio123456
    command: server --console-address ":9001" http://minio-node{1...4}/data{1...2}
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
      interval: 30s
      timeout: 20s
      retries: 3

  minio-node3:
    image: minio/minio
    hostname: minio-node3
    volumes:
      - node3-vol1:/data1
      - node3-vol2:/data2
    expose:
      - "9000"
      - "9001"
    environment:
      MINIO_ROOT_USER: minio
      MINIO_ROOT_PASSWORD: minio123456
    command: server --console-address ":9001" http://minio-node{1...4}/data{1...2}
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
      interval: 30s
      timeout: 20s
      retries: 3

  minio-node4:
    image: minio/minio
    hostname: minio-node4
    volumes:
      - node4-vol1:/data1
      - node4-vol2:/data2
    expose:
      - "9000"
      - "9001"
    environment:
      MINIO_ROOT_USER: minio
      MINIO_ROOT_PASSWORD: minio123456
    command: server --console-address ":9001" http://minio-node{1...4}/data{1...2}
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
      interval: 30s
      timeout: 20s
      retries: 3

  nginx-proxy:
    image: nginx:1.25-alpine
    hostname: nginx-proxy
    ports:
      - "9000:9000"
      - "9001:9001"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
    depends_on:
      - minio-node1
      - minio-node2
      - minio-node3
      - minio-node4

volumes:
  node1-vol1:
  node1-vol2:
  node2-vol1:
  node2-vol2:
  node3-vol1:
  node3-vol2:
  node4-vol1:
  node4-vol2:

Déploiement de Redis 7.x — Cache distribué

Préparez l'arborescence des fichiers :

mkdir -p /srv/redis/conf
mkdir -p /srv/redis/persist

Le dossier persist contiendra les fichiers de persistance RDB et AOF. Le dossier conf recevra le fichier de configuration Redis.

Créez le fichier /srv/redis/conf/redis.conf avec le contenu suivant :

# Ecouter sur toutes les interfaces
bind 0.0.0.0

# Desactiver la protection pour les connexions reseau
protected-mode no

port 6379
timeout 0

# Sauvegarde RDB automatique
save 900 1
save 300 10
save 60 10000
rdbcompression yes
dbfilename dump.rdb

# Repertoire des donnees
dir /data

# Activer la persistance AOF
appendonly yes
appendfsync everysec
appendfilename "appendonly.aof"

# Mot de passe d'acces
requirepass "votre_mot_de_passe_redis"

Lancement direct via Docker

docker run -d \
  --name redis-server \
  --restart=always \
  -p 6379:6379 \
  -v /srv/redis/conf/redis.conf:/etc/redis/redis.conf:ro \
  -v /srv/redis/persist:/data \
  redis:7.0.12 redis-server /etc/redis/redis.conf

Déploiement via Docker Compose

version: '3.8'

services:
  redis-cache:
    image: redis:7.0.12
    container_name: redis-cache
    restart: always
    ports:
      - "6379:6379"
    environment:
      TZ: Europe/Paris
    volumes:
      - ./redis/conf/redis.conf:/usr/local/etc/redis/redis.conf:ro
      - ./redis/persist:/data
    command: redis-server /usr/local/etc/redis/redis.conf

Déploiement de RabbitMQ — Broker de messages

Lancement via Docker

Créez les répertoires et attribuez les permissions :

mkdir -p /srv/rabbitmq/logs
mkdir -p /srv/rabbitmq/mnesia

chmod -R 777 /srv/rabbitmq
docker run -d \
  --name rabbitmq-broker \
  -p 5672:5672 \
  -p 15672:15672 \
  -e RABBITMQ_DEFAULT_USER=admin \
  -e RABBITMQ_DEFAULT_PASS=admin123 \
  -v /srv/rabbitmq/mnesia:/var/lib/rabbitmq \
  -v /srv/rabbitmq/logs:/var/log/rabbitmq \
  rabbitmq:3-management

Activer le démarrage automatique :

docker update rabbitmq-broker --restart=always

Activer l'interface d'administration web :

docker exec -it rabbitmq-broker rabbitmq-plugins enable rabbitmq_management

Installation du plugin de messages différés

Assurez-vous que la version du plugin correspond à celle de votre instance RabbitMQ. La version installée est visible dans l'interface d'administration.

docker cp ./rabbitmq_delayed_message_exchange-3.12.0.ez rabbitmq-broker:/opt/rabbitmq/plugins/
docker exec -it rabbitmq-broker rabbitmq-plugins enable rabbitmq_delayed_message_exchange
docker restart rabbitmq-broker

Déploiement via Docker Compose avec Dockerfile personnalisé

Préparez les répertoires :

mkdir -p /srv/rabbitmq/logs
mkdir -p /srv/rabbitmq/mnesia
chmod -R 777 /srv/rabbitmq

Créez un Dockerfile pour intégrer le plugin :

FROM rabbitmq:3.12.0-management

LABEL maintainer="equipe-infra"

# Ajout du plugin de messages différés
COPY ./rabbitmq_delayed_message_exchange-3.12.0.ez /opt/rabbitmq/plugins/

# Activation du plugin
RUN rabbitmq-plugins enable rabbitmq_delayed_message_exchange

ENTRYPOINT ["rabbitmq-server"]

Fichier docker-compose.yml :

version: '3.8'

services:
  rabbitmq-svc:
    build:
      context: ./rabbitmq
      dockerfile: Dockerfile
    image: rabbitmq-custom:3.12.0
    container_name: rabbitmq-svc
    restart: unless-stopped
    environment:
      RABBITMQ_DEFAULT_USER: admin
      RABBITMQ_DEFAULT_PASS: admin123
    ports:
      - "5672:5672"
      - "15672:15672"
    volumes:
      - /srv/rabbitmq/logs:/var/log/rabbitmq
      - /srv/rabbitmq/mnesia:/var/lib/rabbitmq

Lancer le service :

docker-compose up -d --build rabbitmq-svc

Déploiement de MySQL 8.0

Structure des répertoires de persistance :

mkdir -p /srv/mysql/data
mkdir -p /srv/mysql/initdb
mkdir -p /srv/mysql/conf
  • data : stockage des fichiers de données. En cas d'échec d'initialisation, supprimez tout le contenu de ce dossier.
  • initdb : scripts .sh et .sql exécutés automatiquement lors du premier démarrage du conteneur.
  • conf : fichier de configuration my.cnf personnalisable.

Déploiement via Docker Compose

version: '3.8'

services:
  mysql-db:
    image: mysql:8.0.33
    container_name: mysql-db
    restart: always
    environment:
      TZ: Europe/Paris
      MYSQL_ROOT_PASSWORD: motdepasse_root
      MYSQL_DATABASE: app_principale
      MYSQL_USER: utilisateur_app
      MYSQL_PASSWORD: motdepasse_app
    ports:
      - "3306:3306"
    volumes:
      - ./mysql/data:/var/lib/mysql
      - ./mysql/conf:/etc/mysql/conf.d
      - ./mysql/initdb:/docker-entrypoint-initdb.d
    command:
      - --default-authentication-plugin=mysql_native_password
      - --character-set-server=utf8mb4
      - --collation-server=utf8mb4_general_ci
      - --explicit_defaults_for_timestamp=true
      - --lower_case_table_names=1

Lancement avec compatibilité :

docker-compose --compatibility up -d

En cas d'échec d'initialisation :

docker-compose stop
docker-compose rm -f mysql-db
rm -rf /srv/mysql/data/*

Lancement direct via Docker

mkdir -p /srv/mysql/conf
mkdir -p /srv/mysql/data
mkdir -p /srv/mysql/logs

Créez le fichier /srv/mysql/conf/my.cnf :

[client]
port = 3306
default-character-set = utf8mb4

[mysql]
port = 3306
default-character-set = utf8mb4

[mysqld]
max_connections = 10000
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
character-set-client-handshake = FALSE
init_connect = 'SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci'
gtid-mode = ON
enforce-gtid-consistency = ON
docker run -d \
  --name mysql-db \
  --restart=always \
  -p 3306:3306 \
  -e MYSQL_ROOT_PASSWORD='motdepasse_root' \
  -v /srv/mysql/conf:/etc/mysql \
  -v /srv/mysql/data:/var/lib/mysql \
  -v /srv/mysql/logs:/var/log \
  mysql:8.0.33

Résolution de problèmes courants

Correction du fuseau horaire dans le conteneur :

docker exec -it mysql-db bash
cp /usr/share/zoneinfo/Europe/Paris /etc/localtime
exit
docker restart mysql-db

Problème d'authentification depuis un client distant :

docker exec -it mysql-db mysql -u root -p

-- Modification de la methode d'encryption du mot de passe
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'nouveau_mot_de_passe';
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'nouveau_mot_de_passe';

FLUSH PRIVILEGES;

Erreur 1055 avec ONLY_FULL_GROUP_BY :

Pour désactiver temporairement le mode strict sans redémarrage :

-- Voir le mode SQL actuel
SELECT @@global.sql_mode;

-- Retirer ONLY_FULL_GROUP_BY
SET GLOBAL sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';

Pour une correction permanente, ajoutez cette ligne dans la section [mysqld] de votre fichier my.cnf :

sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

Redémarrez ensuite le conteneur MySQL pour appliquer la modification.

Étiquettes: Docker docker-compose Nacos minio Redis

Publié le 3 juin à 16h39