シナリオ:私はSpringでmysql8データベースを使用するマイクロサービスを開発しました。このデータベースは初期化する必要があります(データベース、いくつかのテーブルとデータを作成します)。ホストマシンで、data.sqlおよびschema.sqlスクリプトを使用してデータベースを初期化しました。問題は、私が設定しなければならないことです:
spring.datasource.initialization-mode=always
最初の実行のために。これにより、データベースが希望どおりに初期化されます。今後の実行のために、このコマンドにコメントする必要があります。非常に醜い解決策ですが、より良い解決策を見つけることができず、今のところこれに対する応答はありません 質問 。テストは大丈夫だと思いましたが、間違いなく改善する必要があります。現在、dockercomposeによってdockerを使用してサービスを実行したいと考えています。
Expected:これはdocker-composeファイルです。かなり簡単です。私はDockerの世界ではまったく新しいので、一歩一歩進んでいきたいと思います。
version: '3' services:usermanagement-service: build: ./UserManagementService restart: on-failure ports: - "7778:7778" links: - mysqldb depends_on: - mysqldb mysqldb: build: ./CustomMySql volumes: - ./mysql-data:/var/lib/mysql restart: on-failure environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: userdb MYSQL_USER: testuser MYSQL_PASSWORD: testuser expose: - "3600"
データベースがユーザーで初期化され、最初の実行でマイクロサービスがデータベースをデータで初期化することを期待していました。したがって、次の作成を開始する前に、コマンドにコメントを付けてイメージを再構築する必要があります。 (私は知っている、醜い)
問題:したがって、この醜い解決策に加えて、実行時の問題が発生します。 docker-compose up
では、私のマイクロサービスはデータベースの初期化よりも高速です。そのため、dbを呼び出そうとすると、エラーが発生します。 restart on failure
のため、マイクロサービスが再び起動します。データベースの初期化が終了したため、これで機能します。
解決策:wwwを検索したところ、wait-for-it.sh
ファイル内で解決される可能性のある既知の問題のようです。これは、DockerfileのCOPYに含まれている必要があります。だから私は専門家ではありませんが、次のいずれかの良い解決策を探しています:
ここでのベストプラクティスがわからないので、これを構築する方法について助けていただければ幸いです。
最初の実行時にのみSQLファイルをロードする場合:
以下の作成ファイルを使用できます
version: '2.1'
services:
usermanagement-service:
build: ./UserManagementService
restart: on-failure
ports:
- "7778:7778"
depends_on:
mysqldb:
condition: service_healthy
mysqldb:
image: mysql
volumes:
- ./mysql-data:/var/lib/mysql
- ./mysql-init-files:/docker-entrypoint-initdb.d
restart: always
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: userdb
MYSQL_USER: testuser
MYSQL_PASSWORD: testuser
ports:
- "3600:3306"
healthcheck:
test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"]
timeout: 20s
retries: 10
Volumes
詳細 を使用して、data.sql
およびschema.sql
ファイルを./docker-entrypoint-initdb.d
ディレクトリの下に配置する必要があります。
このフォルダ内のSQLファイルは、DBのデータディレクトリが空の場合(dbサービスの最初の実行)にのみロードされます。 (つまり)あなたの場合、./mysql-data
フォルダは空である必要があります
2番目の問題の場合:
wait-for-it.sh
を使用する代わりに、healthcheck
とservice_healthy
を使用できます。ここで、mysqldb
が指定された間隔でusermanagement-service
を正常に実行すると、["CMD", "mysqladmin" ,"ping", "-h", "localhost"]
が開始されます。 healthcheckとdepends_onの詳細については、 ここ を参照してください。
ここ からtest
コマンドを取得しました。