web-dev-qa-db-ja.com

mysql接続の準備ができているかどうかのDocker構成チェック

Dbコンテナーが開始され、接続を受け入れる準備ができるまで、アプリコンテナーが移行/開始を実行しないことを確認しようとしています。

そこで、ヘルスチェックを使用することにし、Docker Compose File v2のオプションに依存します。

アプリでは、次のものがあります

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

一方、dbには次のヘルスチェックがあります

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

私は次のようないくつかのアプローチを試しました:

  1. データベースDIRが作成されていることを確認するtest: ["CMD", "test -f var/lib/mysql/db"]
  2. Mysqlバージョンの取得:test: ["CMD", "echo 'SELECT version();'| mysql"]
  3. 管理者にpingを実行します(dbコンテナーを正常としてマークしますが、有効なテストではないようです)test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"]

誰にもこれに対する解決策がありますか?

49
John Kariuki
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

APIコンテナーは、dbコンテナーが正常になるまで(基本的にmysqladminが起動して接続を受け入れるまで)起動しません。

57
John Kariuki

コンテナを変更してmysqlの準備ができるまで待機できる場合は、それを実行します。

データベースの接続先のコンテナを制御できない場合は、特定のポートを待つことができます。

そのために、私は小さなスクリプトを使用して、別のコンテナーによって公開される特定のポートを待機しています。

この例では、myserverは、ポート3306mydbコンテナーが到達可能になります。

# 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

スクリプトwait-for-itのドキュメントを見つけることができます here

7
nono

Docker-composev3 +を使用している場合、depends_onのオプションとしてconditionremovedになりました。

推奨パスは、代わりに wait-for-itdockerize 、または wait-for を使用することです。 docker-compose.ymlファイルで、コマンドを次のように変更します。

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

個人的にはwait-forが好きです。Alpineコンテナで実行できるからです(sh互換、bashに依存しません)。欠点は、netcatに依存しているため、使用する場合は、netcatがコンテナーにインストールされていることを確認するか、Dockerfileにインストールしてください(例:

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

私も wait-forを分岐 プロジェクトで、健全なHTTPステータスをチェックできるようにしました(wgetを使用しています)。その後、あなたはそのようなことをすることができます:

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

こんにちはdocker-compose v2.1を使用した簡単なヘルスチェックのために、私は以下を使用しました:

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

基本的には、単純なmysqlコマンドSHOW DATABASES;を例としてを使用して実行しますユーザーrootとパスワードrootpasswdデータベース内。

コマンドが成功すると、dbが起動して準備が整うため、ヘルスチェックパスが作成されます。 intervalを使用して、間隔でテストすることができます。

可視性のために他のフィールドを削除すると、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
4
Sylhare

次の例のようにdocker-compose.ymlを変更し、機能しました。

  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

私の場合、../schemaAndSeedDataには複数のスキーマとデータシードのsqlファイルが含まれています。 Design your own check scriptは、次のselect * from LastSchema.LastDBInsertに類似しています。

Web依存のコンテナコードは

depends_on:
  mysql:
    condition: service_healthy
3
Mukesh Agarwal

これで十分でしょう

version: '2.1'
services:
  mysql:
    image: mysql
    ports: ['3306:3306']
    environment:
      MYSQL_USER: myuser
      MYSQL_PASSWORD: mypassword
    healthcheck:
      test: mysqladmin ping -h 127.0.0.1 -u $$MYSQL_USER --password=$$MYSQL_PASSWORD
3