127 votes

Docker-composition de vérifier si la connexion mysql est prêt

Je suis en train de faire en sorte que mon application conteneur ne pas exécuter les migrations / start jusqu'à ce que le db conteneur est démarré et PRÊT À accepter les connexions.

J'ai donc décidé d'utiliser le bilan de santé et dépend de l'option dans le panneau de composer des fichiers v2.

Dans l'application, j'ai le texte suivant

app:
    ...
    depends_on:
      db:
      condition: service_healthy

La db sur l'autre main a la suite de la verification de la santé

db:
  ...
  healthcheck:
    test: TEST_GOES_HERE
    timeout: 20s
    retries: 10

J'ai essayé plusieurs approches :

  1. assurez vous que les db DIR est créé test: ["CMD", "test -f var/lib/mysql/db"]
  2. Obtenir la version de mysql: test: ["CMD", "echo 'SELECT version();'| mysql"]
  3. Ping l'admin (marques de la db conteneur en bonne santé, mais ne semble pas être un test valide) test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"]

Quelqu'un aurait-il une solution à cela?

117voto

John Kariuki Points 150
version: "2.1"
services:
    api:
        build: .
        container_name: api
        ports:
            - "8080:8080"
        depends_on:
            db:
                condition: service_healthy
    db:
        container_name: db
        image: mysql
        ports:
            - "3306"
        environment:
            MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
            MYSQL_USER: "user"
            MYSQL_PASSWORD: "password"
            MYSQL_DATABASE: "database"
        healthcheck:
            test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"]
            timeout: 20s
            retries: 10

L'api conteneur ne démarre pas jusqu'à ce que le db conteneur est en bonne santé (en gros jusqu'à ce que la commande mysqladmin est en place et en acceptant des connexions).

30voto

Capripot Points 369

Si vous utilisez le panneau-composer v3+, condition comme une option de depends_on a été supprimée.

La procédure recommandée est d'utiliser plutôt wait-for-it, dockerizeou wait-for. Dans votre docker-compose.yml le fichier, modifier votre commande à:

command: sh -c 'bin/wait-for db:3306 -- bundle exec rails s'

Personnellement, je préfère wait-for car il peut s'exécuter dans un Alpine conteneur (sh compatible, pas de dépendance sur bash). Inconvénient est qu'il dépend netcat, donc si vous décidez de l'utiliser, assurez-vous que vous avez netcat installé dans le conteneur, ou de l'installer dans votre Dockerfile, par exemple avec:

RUN apt-get -q update && apt-get -qy install netcat

J'ai aussi fourchue l' wait-for projet de sorte qu'il peut vérifier la bonne santé de statut HTTP (il utilise wget). Ensuite, vous pouvez faire quelque chose comme ça:

command: sh -c 'bin/wait-for http://api/ping -- jest test'

12voto

nono Points 158

Si vous pouvez changer le conteneur attendre à mysql d'être prêt à le faire.

Si vous n'avez pas le contrôle du conteneur que vous souhaitez vous connecter la base de données, vous pouvez essayer d'attendre le port spécifique.

Pour cela, j'utilise un petit script pour attendre un port spécifique exposée par un autre récipient.

Dans cet exemple, le serveur va attendre pour le port 3306 de mydb conteneur, afin d'être joignable.

# Your database
mydb:
  image: mysql
  ports:
    - "3306:3306"
  volumes:
    - yourDataDir:/var/lib/mysql

# Your server
myserver:
  image: myserver
  ports:
    - "....:...."
  entrypoint: ./wait-for-it.sh mydb:3306 -- ./yourEntryPoint.sh

Vous pouvez trouver le script wait-for-il de la documentation ici

10voto

Sylhare Points 647

Salut pour un simple bilan de santé à l'aide de docker-composer v2.1, j'ai utilisé:

/usr/bin/mysql --user=root --password=rootpasswd --execute \"SHOW DATABASES;\"

Il fonctionne essentiellement un simple mysql command SHOW DATABASES; en utilisant comme exemple l'utilisateur root avec le mot de passe rootpasswd dans la base de données.

Si la commande réussir la db est en place et prêt de sorte que le bilan de santé de chemin. Vous pouvez utiliser interval donc il teste à l'intervalle.

Le retrait de l'autre champ de visibilité, voici à quoi il pourrait ressembler dans votre docker-compose.yaml.

version: '2.1'

  services:
    db:
      ...
      healthcheck:
        test: "/usr/bin/mysql --user=root --password=rootpasswd --execute \"SHOW DATABASES;\""
        interval: 2s
        timeout: 20s
        retries: 10

     app:
       ...
       depends_on:
         db:
         condition: service_healthy

6voto

Mukesh Agarwal Points 73

J'ai modifié l' docker-compose.yml comme dans l'exemple suivant, et cela a fonctionné.

  mysql:
    image: mysql:5.6
    ports:
      - "3306:3306"
    volumes:       
      # Preload files for data
      - ../schemaAndSeedData:/docker-entrypoint-initdb.d
    environment:
      MYSQL_ROOT_PASSWORD: rootPass
      MYSQL_DATABASE: DefaultDB
      MYSQL_USER: usr
      MYSQL_PASSWORD: usr
    healthcheck:
      test:  mysql --user=root --password=rootPass -e 'Design your own check script ' LastSchema

Dans mon cas ../schemaAndSeedData contient plusieurs schéma et les données de semis de fichiers sql. Design your own check script peut être semblable à la suivante select * from LastSchema.LastDBInsert.

Alors que le web dépendante container code a été

depends_on:
  mysql:
    condition: service_healthy

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X