0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【備忘】docker compose のdepends_on と healthcheck で実行順序を制御する

Posted at

はじめに

ローカル環境のFlowをdocker composeで動かしている際、アプリとDBのコンテナが同時に立ち上がることに気が付きました。
自己満足でありますが、依存関係を綺麗にしようとおもい、depends_onhelthcheckという機能を使ってみたので、備忘として残します。

経緯

以前書いた記事で、Flowをdocker composeで動かすためのdocker-compose.ymlを書きました。

docker-compose.yml
services:
  app:
    build: 
      context: .
      dockerfile: ./Docker/php/Dockerfile
    ports:
      - "8082:8081"

  db:
    image: mysql:8.0.36
    volumes:
      - db_data3:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: mydatabase
    ports:
      - "3306:3306"

volumes:
  db_data3: {}

動作確認的には問題なく動いているのですが、起動ログを見ると、アプリとDBのコンテナが同時に立ち上がっています。

> docker compose up
[+] Running 1/1r Desktop   o View Config   w Enable Watch
 ✔ Container quickstart-db-1  Recreated                                                                                                      0.1s 
Attaching to app-1, db-1
db-1   | 2025-12-28 04:54:50+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.36-1.el8 started.
app-1  | rm: cannot remove '/app/Packages/Application/Added.Package': Is a directory                                                              
app-1  | rm: cannot remove '/app/Packages/Application/Neos.Welcome': Is a directory                                                               
app-1  | rm: cannot remove '/app/Packages/Application/Test.Package': Is a directory                                                               
app-1  | rm: cannot remove '/app/Packages/Application/Tomita.Test': Is a directory                                                                
app-1  | rm: cannot remove '/app/Packages/Application/Tomita.Test2': Is a directory            
db-1   | 2025-12-28 04:54:50+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
db-1   | 2025-12-28 04:54:50+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.36-1.el8 started.
db-1   | '/var/lib/mysql/mysql.sock' -> '/var/run/mysqld/mysqld.sock'
db-1   | 2025-12-28T04:54:50.692897Z 0 [Warning] [MY-011068] [Server] The syntax '--skip-host-cache' is deprecated and will be removed in a future release. Please use SET GLOBAL host_cache_size=0 instead.
db-1   | 2025-12-28T04:54:50.694191Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.36) starting as process 1
db-1   | 2025-12-28T04:54:50.701526Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.                                           
db-1   | 2025-12-28T04:54:50.858890Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.         
db-1   | 2025-12-28T04:54:51.075629Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
db-1   | 2025-12-28T04:54:51.075675Z 0 [System] [MY-013602] [Server] Channel mysql_main configured to support TLS. Encrypted connections are now supported for this channel.                                                                                                                        
db-1   | 2025-12-28T04:54:51.081432Z 0 [Warning] [MY-011810] [Server] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.                                                                         
db-1   | 2025-12-28T04:54:51.120271Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Bind-address: '::' port: 33060, socket: /var/run/mysqld/mysqlx.sock
db-1   | 2025-12-28T04:54:51.120522Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.36'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server - GPL.                                                                                   
app-1  | Executed a database schema update.
app-1  | Server running. Please go to http://0.0.0.0:8081 to browse the application.
app-1  | [Sun Dec 28 04:54:53 2025] PHP 8.2.29 Development Server (http://0.0.0.0:8081) started

アプリ側のエントリーポイントshellスクリプトでやっていることが多いおかげで問題にはなっていませんが、アプリはDBに依存しているので、これはちょっと気持ち悪いです。
DBが準備できてからアプリ側を立ち上げるよう変更してみましょう。

そこで、docker composeのdepends_onhealthcheckという機能を使い、コンテナ同士の依存関係を定義しようと思います。

depends_onとhelthcheck

depends_onはコンテナの依存関係を示すためのオプションです。
アプリ側のdepends_onにDBのコンテナを指定することで、アプリはDBに依存しているとみなし、DBの準備完了までコンテナの立ち上げを待つようになります。

helthcheckは、立ち上げたコンテナのヘルスチェックに利用するコマンドを示すためのオプションです。

この二つを組み合わせることで、アプリ側はDB側がhealthyになるまでコンテナの立ち上げをしないように制御することが可能です。

修正後
services:
  app:
    build: 
      context: .
      dockerfile: ./Docker/php/Dockerfile
    ports:
      - "8082:8081"
    depends_on:
      db:
        condition: service_healthy

  db:
    image: mysql:8.0.36
    volumes:
      - db_data3:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: mydatabase
    ports:
      - "3306:3306"
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  db_data3: {}

アプリ側では、depends_onの対象にdbを追加し、依存関係を明示しました。
conditionは、依存先がどんな状態になったら立ち上げ始めるかを定義できます。

  • service_started:コンテナが立ち上がり始めたら
  • service_healthy:コンテナが立ち上がり、ヘルスチェックが通ったら
  • service_completed_successfully:コンテナが正常終了したら

今回はDB側の準備が終わったらアプリ側を立ち上げたかったので、service_healthyにしました。

DB側ではhealthcheckを追加し、その際のコマンドと、実行間隔、タイムアウト、リトライ回数を定義しました。

これにより、DBのコンテナの準備ができた後に、アプリケーションサーバを立ち上げることができました。

> docker compose up
[+] Running 1/1
 ✔ Container quickstart-db-1  Recreated                                                                                                      0.1s 
Attaching to app-1, db-1
db-1  | 2025-12-28 07:41:52+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.36-1.el8 started.
db-1  | 2025-12-28 07:41:52+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
db-1  | 2025-12-28 07:41:52+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.36-1.el8 started.
db-1  | '/var/lib/mysql/mysql.sock' -> '/var/run/mysqld/mysqld.sock'                                                                              
db-1  | 2025-12-28T07:41:52.746291Z 0 [Warning] [MY-011068] [Server] The syntax '--skip-host-cache' is deprecated and will be removed in a future release. Please use SET GLOBAL host_cache_size=0 instead.
db-1  | 2025-12-28T07:41:52.747658Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.36) starting as process 1
db-1  | 2025-12-28T07:41:52.754175Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.                                            
db-1  | 2025-12-28T07:41:52.921542Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.                                              
db-1  | 2025-12-28T07:41:53.087987Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
db-1  | 2025-12-28T07:41:53.088026Z 0 [System] [MY-013602] [Server] Channel mysql_main configured to support TLS. Encrypted connections are now supported for this channel.                                                                                                                         
db-1  | 2025-12-28T07:41:53.090659Z 0 [Warning] [MY-011810] [Server] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.                                                                          
db-1  | 2025-12-28T07:41:53.133088Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Bind-address: '::' port: 33060, socket: /var/run/mysqld/mysqlx.sock
db-1  | 2025-12-28T07:41:53.133443Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.36'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server - GPL.                                                                                    
app-1  | rm: cannot remove '/app/Packages/Application/Added.Package': Is a directory
app-1  | rm: cannot remove '/app/Packages/Application/Neos.Welcome': Is a directory                                                               
app-1  | rm: cannot remove '/app/Packages/Application/Test.Package': Is a directory                                                               
app-1  | rm: cannot remove '/app/Packages/Application/Tomita.Test': Is a directory                                                                
app-1  | rm: cannot remove '/app/Packages/Application/Tomita.Test2': Is a directory                          
app-1  | Executed a database schema update.
app-1  | Server running. Please go to http://0.0.0.0:8081 to browse the application.
app-1  | [Sun Dec 28 07:42:06 2025] PHP 8.2.29 Development Server (http://0.0.0.0:8081) started

ちなみに、依存先のコンテナがhealthyにならない場合、以下のようなエラーが出力されます。

dependency failed to start: container quickstart-db-1 is unhealthy

おわりに

今回はdocker composeのdepends_onhealthcheckを利用し、コンテナ同士の依存関係を定義してみました。
自分はあくまでローカルで使用するだけなのでそこまでメリットはないですが、本番等で利用する場合は必須の機能ですね。
また、実行順序を制御できるこの機能はコンテナの数が多くなった場合に大きなメリットをもたらしそうです。

ここまでご覧いただきありがとうございました!

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?