Dbコンテナーが開始され、接続を受け入れる準備ができるまで、アプリコンテナーが移行/開始を実行しないことを確認しようとしています。
そこで、ヘルスチェックを使用することにし、Docker Compose File v2のオプションに依存します。
アプリでは、次のものがあります
app:
...
depends_on:
db:
condition: service_healthy
一方、dbには次のヘルスチェックがあります
db:
...
healthcheck:
test: TEST_GOES_HERE
timeout: 20s
retries: 10
私は次のようないくつかのアプローチを試しました:
test: ["CMD", "test -f var/lib/mysql/db"]
test: ["CMD", "echo 'SELECT version();'| mysql"]
test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"]
誰にもこれに対する解決策がありますか?
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が起動して接続を受け入れるまで)起動しません。
コンテナを変更してmysqlの準備ができるまで待機できる場合は、それを実行します。
データベースの接続先のコンテナを制御できない場合は、特定のポートを待つことができます。
そのために、私は小さなスクリプトを使用して、別のコンテナーによって公開される特定のポートを待機しています。
この例では、myserverは、ポート3306のmydbコンテナーが到達可能になります。
# 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
Docker-composev3 +を使用している場合、depends_on
のオプションとしてcondition
がremovedになりました。
推奨パスは、代わりに wait-for-it
、 dockerize
、または 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'
こんにちは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
次の例のように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
これで十分でしょう
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