背景
自作のDocker, docker-composeを利用したアプリケーションで、docker-compose内でdepends_on
を利用 + アプリケーション側でチェックする仕組みを作っていましたが、これだけでは不足してたことと、healthcheckというものがあると聞いたので試してみました。
結論
- healthcheckが通ったからといってもアプリケーション側で接続できるようになっているかどうかは断定できない(=一時的にhealthcheckが通っただけという可能性もある)
- なので、アプリケーション側でもチェックする仕組みはあった方が良さそう
- もしかしたら、
wait-for-it
といった他のツールの方が良いのかもしれない
ちょっと曖昧なところがありますが、こういう結論でした。
なぜdepends_onでは駄目なのか?
depends_on
はサービス間の起動順番と終了順番の依存関係を表すものです。
https://docs.docker.jp/compose/compose-file/index.html#depends-on
記述することで
- DBコンテナよりも後に起動
- DBコンテナよりも後に削除
といったことをすることが出来ます。
ただし、これはあくまでも順番を制御するのみ、なので実際にコンテナがアプリケーションから利用可能かどうかとは異なるようでした。
そのため、docker-composeでは
- ツールを使う
- 自分でラッパースクリプトを書いてアプリケーション用のヘルスチェックを処理する
といったことをやるように書かれています。
https://docs.docker.jp/compose/startup-order.html
healthcheckとは
https://docs.docker.jp/compose/compose-file/index.html#healthcheck
によると、サービスがHealthy
かどうかを指定したコマンドでチェックする機能のようです。
docker-composeのversion2.1から追加されたようでした。
https://docs.docker.com/compose/compose-file/compose-file-v2/#depends_on
以下はDjangoとMySQLのコンテナをそれぞれ利用するdocker-composeです。
この書き方だと、webがdbの後に起動、後に削除されるようになっています。
before
version: '2.1'
services:
db:
container_name: docker_healthcheck_db
image: mysql:8.0.32
volumes:
- db_data:/var/lib/mysql
environment:
- MYSQL_DATABASE=docker_healthcheck
- MYSQL_USER=docker_healthcheck
- MYSQL_PASSWORD=docker_healthcheck
- MYSQL_ROOT_PASSWORD=docker_healthcheck
web:
build:
context: ..
dockerfile: docker/Dockerfile
container_name: docker_healthcheck_web
command: python manage.py runserver 0.0.0.0:8000
volumes:
- ..:/docker_healthcheck
ports:
- "8000:8000"
environment:
- MYSQL_DATABASE=docker_healthcheck
- MYSQL_USER=docker_healthcheck
- MYSQL_PASSWORD=docker_healthcheck
- MYSQL_HOST=db
- MYSQL_PORT=3306
- DJANGO_SETTINGS_MODULE=config.settings
depends_on:
- db
volumes:
db_data:
上記を以下のように書き換えて、db
側にhealthcheck
とチェック内容, web
のdepends_on
にcondition: service_healthy
を追記します。
after
version: '2.1'
services:
db:
container_name: docker_healthcheck_db
image: mysql:8.0.32
volumes:
- db_data:/var/lib/mysql
environment:
- MYSQL_DATABASE=docker_healthcheck
- MYSQL_USER=docker_healthcheck
- MYSQL_PASSWORD=docker_healthcheck
- MYSQL_ROOT_PASSWORD=docker_healthcheck
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
web:
build:
context: ..
dockerfile: docker/Dockerfile
container_name: docker_healthcheck_web
command: python manage.py runserver 0.0.0.0:8000
volumes:
- ..:/docker_healthcheck
ports:
- "8000:8000"
environment:
- MYSQL_DATABASE=docker_healthcheck
- MYSQL_USER=docker_healthcheck
- MYSQL_PASSWORD=docker_healthcheck
- MYSQL_HOST=db
- MYSQL_PORT=3306
- DJANGO_SETTINGS_MODULE=config.settings
depends_on:
db:
condition: service_healthy
volumes:
db_data:
beforeだと、このようにStarted
になったタイミングで次の処理に移ります(私だと、Djangoが立ち上がるようになって、最初のMySQLへの接続に失敗する状態でした)。
[+] Running 4/4
✔ Network docker_default Created 0.0s
✔ Volume "docker_db_data" Created 0.0s
✔ Container docker_healthcheck_db Started 0.0s
✔ Container docker_healthcheck_web Started 0.0s
afterだと、Started
になった後に
[+] Running 4/4
✔ Network docker_default Created 0.0s
✔ Volume "docker_db_data" Created 0.0s
✔ Container docker_healthcheck_db Started 0.0s
✔ Container docker_healthcheck_web Created 0.0s
Healthy
であることをチェックして、次の処理へ進むようになりました。
[+] Running 4/4
✔ Network docker_default Created 0.0s
✔ Volume "docker_db_data" Created 0.0s
✔ Container docker_healthcheck_db Healthy 0.0s
✔ Container docker_healthcheck_web Started 0.0s
のようになります。
ただし、私の環境だとHealthy
であってもDjango側で接続に失敗してOperationalError
が発生しました。恐らくinterval: 10s
を20s
など広めに取れば大丈夫ではありそうでした。
ありそう、というのは実際に試してOKではあったものの、それが常に大丈夫だと言える保証もないかなーと考えたからです。
上記より、あくまでもHealthy
かどうかチェックできるだけで、実際にDjango側から接続可能なのかどうかは別問題かなと感じました。
以降は実際に出たエラーやもう少し追加で調べた記録です。
実際のエラー
ちょっと長いですが、こういう感じでした。
[+] Running 4/4
✔ Network docker_default Created 0.0s
✔ Volume "docker_db_data" Created 0.0s
✔ Container docker_healthcheck_db Created 0.0s
✔ Container docker_healthcheck_web Created 0.0s
Attaching to docker_healthcheck_db, docker_healthcheck_web
docker_healthcheck_db | 2024-01-02 23:19:55+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.32-1.el8 started.
docker_healthcheck_db | 2024-01-02 23:19:56+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
docker_healthcheck_db | 2024-01-02 23:19:57+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.32-1.el8 started.
docker_healthcheck_db | 2024-01-02 23:19:58+00:00 [Note] [Entrypoint]: Initializing database files
docker_healthcheck_db | 2024-01-02T23:19:58.491975Z 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.
docker_healthcheck_db | 2024-01-02T23:19:58.494119Z 0 [System] [MY-013169] [Server] /usr/sbin/mysqld (mysqld 8.0.32) initializing of server in progress as process 354
docker_healthcheck_db | 2024-01-02T23:19:58.587680Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
docker_healthcheck_db | 2024-01-02T23:19:58.961840Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
docker_healthcheck_db | 2024-01-02T23:20:00.556381Z 6 [Warning] [MY-010453] [Server] root@localhost is created with an empty password ! Please consider switching off the --initialize-insecure option.
docker_healthcheck_db | 2024-01-02 23:20:03+00:00 [Note] [Entrypoint]: Database files initialized
docker_healthcheck_db | 2024-01-02 23:20:03+00:00 [Note] [Entrypoint]: Starting temporary server
docker_healthcheck_db | 2024-01-02T23:20:03.934177Z 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.
docker_healthcheck_db | 2024-01-02T23:20:03.938944Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.32) starting as process 414
docker_healthcheck_db | 2024-01-02T23:20:04.083260Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
docker_healthcheck_db | 2024-01-02T23:20:04.362314Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
docker_healthcheck_db | 2024-01-02T23:20:04.950096Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
docker_healthcheck_db | 2024-01-02T23:20:04.950288Z 0 [System] [MY-013602] [Server] Channel mysql_main configured to support TLS. Encrypted connections are now supported for this channel.
docker_healthcheck_db | 2024-01-02T23:20:04.954519Z 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.
docker_healthcheck_db | 2024-01-02T23:20:04.998689Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.32' socket: '/var/run/mysqld/mysqld.sock' port: 0 MySQL Community Server - GPL.
docker_healthcheck_db | 2024-01-02T23:20:04.998722Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Socket: /var/run/mysqld/mysqlx.sock
docker_healthcheck_db | 2024-01-02 23:20:05+00:00 [Note] [Entrypoint]: Temporary server started.
docker_healthcheck_db | '/var/lib/mysql/mysql.sock' -> '/var/run/mysqld/mysqld.sock'
docker_healthcheck_db | Warning: Unable to load '/usr/share/zoneinfo/iso3166.tab' as time zone. Skipping it.
docker_healthcheck_db | Warning: Unable to load '/usr/share/zoneinfo/leap-seconds.list' as time zone. Skipping it.
docker_healthcheck_db | Warning: Unable to load '/usr/share/zoneinfo/leapseconds' as time zone. Skipping it.
docker_healthcheck_db | Warning: Unable to load '/usr/share/zoneinfo/tzdata.zi' as time zone. Skipping it.
docker_healthcheck_db | Warning: Unable to load '/usr/share/zoneinfo/zone.tab' as time zone. Skipping it.
docker_healthcheck_db | Warning: Unable to load '/usr/share/zoneinfo/zone1970.tab' as time zone. Skipping it.
docker_healthcheck_db | 2024-01-02 23:20:08+00:00 [Note] [Entrypoint]: Creating database docker_healthcheck
docker_healthcheck_db | 2024-01-02 23:20:08+00:00 [Note] [Entrypoint]: Creating user docker_healthcheck
docker_healthcheck_db | 2024-01-02 23:20:08+00:00 [Note] [Entrypoint]: Giving user docker_healthcheck access to schema docker_healthcheck
docker_healthcheck_db |
docker_healthcheck_db | 2024-01-02 23:20:08+00:00 [Note] [Entrypoint]: Stopping temporary server
docker_healthcheck_db | 2024-01-02T23:20:08.995225Z 14 [System] [MY-013172] [Server] Received SHUTDOWN from user root. Shutting down mysqld (Version: 8.0.32).
docker_healthcheck_web | Performing system checks...
docker_healthcheck_web |
docker_healthcheck_web | System check identified no issues (0 silenced).
docker_healthcheck_web | Exception in thread django-main-thread:
docker_healthcheck_web | Traceback (most recent call last):
docker_healthcheck_web | File "/usr/local/lib/python3.11/site-packages/django/db/backends/base/base.py", line 282, in ensure_connection
docker_healthcheck_web | self.connect()
docker_healthcheck_web | File "/usr/local/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner
docker_healthcheck_web | return func(*args, **kwargs)
docker_healthcheck_web | ^^^^^^^^^^^^^^^^^^^^^
docker_healthcheck_web | File "/usr/local/lib/python3.11/site-packages/django/db/backends/base/base.py", line 263, in connect
docker_healthcheck_web | self.connection = self.get_new_connection(conn_params)
docker_healthcheck_web | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
docker_healthcheck_web | File "/usr/local/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner
docker_healthcheck_web | return func(*args, **kwargs)
docker_healthcheck_web | ^^^^^^^^^^^^^^^^^^^^^
docker_healthcheck_web | File "/usr/local/lib/python3.11/site-packages/django/db/backends/mysql/base.py", line 247, in get_new_connection
docker_healthcheck_web | connection = Database.connect(**conn_params)
docker_healthcheck_web | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
docker_healthcheck_web | File "/usr/local/lib/python3.11/site-packages/MySQLdb/__init__.py", line 123, in Connect
docker_healthcheck_web | return Connection(*args, **kwargs)
docker_healthcheck_web | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
docker_healthcheck_web | File "/usr/local/lib/python3.11/site-packages/MySQLdb/connections.py", line 185, in __init__
docker_healthcheck_web | super().__init__(*args, **kwargs2)
docker_healthcheck_web | MySQLdb.OperationalError: (2002, "Can't connect to MySQL server on 'db' (115)")
docker_healthcheck_web |
docker_healthcheck_web | The above exception was the direct cause of the following exception:
docker_healthcheck_web |
docker_healthcheck_web | Traceback (most recent call last):
docker_healthcheck_web | File "/usr/local/lib/python3.11/threading.py", line 1038, in _bootstrap_inner
docker_healthcheck_web | self.run()
docker_healthcheck_web | File "/usr/local/lib/python3.11/threading.py", line 975, in run
docker_healthcheck_web | self._target(*self._args, **self._kwargs)
docker_healthcheck_web | File "/usr/local/lib/python3.11/site-packages/django/utils/autoreload.py", line 64, in wrapper
docker_healthcheck_web | fn(*args, **kwargs)
docker_healthcheck_web | File "/usr/local/lib/python3.11/site-packages/django/core/management/commands/runserver.py", line 137, in inner_run
docker_healthcheck_web | self.check_migrations()
docker_healthcheck_web | File "/usr/local/lib/python3.11/site-packages/django/core/management/base.py", line 564, in check_migrations
docker_healthcheck_web | executor = MigrationExecutor(connections[DEFAULT_DB_ALIAS])
docker_healthcheck_web | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
docker_healthcheck_web | File "/usr/local/lib/python3.11/site-packages/django/db/migrations/executor.py", line 18, in __init__
docker_healthcheck_web | self.loader = MigrationLoader(self.connection)
docker_healthcheck_web | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
docker_healthcheck_web | File "/usr/local/lib/python3.11/site-packages/django/db/migrations/loader.py", line 58, in __init__
docker_healthcheck_web | self.build_graph()
docker_healthcheck_web | File "/usr/local/lib/python3.11/site-packages/django/db/migrations/loader.py", line 235, in build_graph
docker_healthcheck_web | self.applied_migrations = recorder.applied_migrations()
docker_healthcheck_web | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
docker_healthcheck_web | File "/usr/local/lib/python3.11/site-packages/django/db/migrations/recorder.py", line 81, in applied_migrations
docker_healthcheck_web | if self.has_table():
docker_healthcheck_web | ^^^^^^^^^^^^^^^^
docker_healthcheck_web | File "/usr/local/lib/python3.11/site-packages/django/db/migrations/recorder.py", line 57, in has_table
docker_healthcheck_web | with self.connection.cursor() as cursor:
docker_healthcheck_web | ^^^^^^^^^^^^^^^^^^^^^^^^
docker_healthcheck_web | File "/usr/local/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner
docker_healthcheck_web | return func(*args, **kwargs)
docker_healthcheck_web | ^^^^^^^^^^^^^^^^^^^^^
docker_healthcheck_web | File "/usr/local/lib/python3.11/site-packages/django/db/backends/base/base.py", line 323, in cursor
docker_healthcheck_web | return self._cursor()
docker_healthcheck_web | ^^^^^^^^^^^^^^
docker_healthcheck_web | File "/usr/local/lib/python3.11/site-packages/django/db/backends/base/base.py", line 299, in _cursor
docker_healthcheck_web | self.ensure_connection()
docker_healthcheck_web | File "/usr/local/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner
docker_healthcheck_web | return func(*args, **kwargs)
docker_healthcheck_web | ^^^^^^^^^^^^^^^^^^^^^
docker_healthcheck_web | File "/usr/local/lib/python3.11/site-packages/django/db/backends/base/base.py", line 281, in ensure_connection
docker_healthcheck_web | with self.wrap_database_errors:
docker_healthcheck_web | File "/usr/local/lib/python3.11/site-packages/django/db/utils.py", line 91, in __exit__
docker_healthcheck_web | raise dj_exc_value.with_traceback(traceback) from exc_value
docker_healthcheck_web | File "/usr/local/lib/python3.11/site-packages/django/db/backends/base/base.py", line 282, in ensure_connection
docker_healthcheck_web | self.connect()
docker_healthcheck_web | File "/usr/local/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner
docker_healthcheck_web | return func(*args, **kwargs)
docker_healthcheck_web | ^^^^^^^^^^^^^^^^^^^^^
docker_healthcheck_web | File "/usr/local/lib/python3.11/site-packages/django/db/backends/base/base.py", line 263, in connect
docker_healthcheck_web | self.connection = self.get_new_connection(conn_params)
docker_healthcheck_web | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
docker_healthcheck_web | File "/usr/local/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner
docker_healthcheck_web | return func(*args, **kwargs)
docker_healthcheck_web | ^^^^^^^^^^^^^^^^^^^^^
docker_healthcheck_web | File "/usr/local/lib/python3.11/site-packages/django/db/backends/mysql/base.py", line 247, in get_new_connection
docker_healthcheck_web | connection = Database.connect(**conn_params)
docker_healthcheck_web | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
docker_healthcheck_web | File "/usr/local/lib/python3.11/site-packages/MySQLdb/__init__.py", line 123, in Connect
docker_healthcheck_web | return Connection(*args, **kwargs)
docker_healthcheck_web | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
docker_healthcheck_web | File "/usr/local/lib/python3.11/site-packages/MySQLdb/connections.py", line 185, in __init__
docker_healthcheck_web | super().__init__(*args, **kwargs2)
docker_healthcheck_web | django.db.utils.OperationalError: (2002, "Can't connect to MySQL server on 'db' (115)")
docker_healthcheck_db | 2024-01-02T23:20:10.505232Z 0 [System] [MY-010910] [Server] /usr/sbin/mysqld: Shutdown complete (mysqld 8.0.32) MySQL Community Server - GPL.
docker_healthcheck_db | 2024-01-02 23:20:11+00:00 [Note] [Entrypoint]: Temporary server stopped
docker_healthcheck_db |
docker_healthcheck_db | 2024-01-02 23:20:11+00:00 [Note] [Entrypoint]: MySQL init process done. Ready for start up.
docker_healthcheck_db |
docker_healthcheck_db | 2024-01-02T23:20:11.563285Z 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.
docker_healthcheck_db | 2024-01-02T23:20:11.568460Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.32) starting as process 1
docker_healthcheck_db | 2024-01-02T23:20:11.673006Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
docker_healthcheck_db | 2024-01-02T23:20:12.004580Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
docker_healthcheck_db | 2024-01-02T23:20:12.432642Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
docker_healthcheck_db | 2024-01-02T23:20:12.432818Z 0 [System] [MY-013602] [Server] Channel mysql_main configured to support TLS. Encrypted connections are now supported for this channel.
docker_healthcheck_db | 2024-01-02T23:20:12.437618Z 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.
docker_healthcheck_db | 2024-01-02T23:20:12.484355Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.32' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server - GPL.
docker_healthcheck_db | 2024-01-02T23:20:12.487790Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Bind-address: '::' port: 33060, socket: /var/run/mysqld/mysqlx.sock
この、最後から2行目のdocker_healthcheck_db | 2024-01-02T23:20:12.484355Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.32' socket: '/var/run/mysqld/mysqld.sock
の状態になって初めて接続できることになりそうです。そのため、ここに至るまでにHealthy
と判定されたら次に進む = アプリケーション側で失敗する、ということにはなりそうです。
追加でちょっと実験してみた
2つのターミナルを用意して、
- コンテナを立ち上げる
- 片方で起動した後、もう片方でコンテナに入りmysqladminでpingを通す
ことをしてみました。
tatsuya@MacBook-Pro-3 docker % docker exec -it docker_healthcheck_db bash
bash-4.4# mysqladmin -u docker_healthcheck -pdocker_healthcheck ping
mysqladmin: [Warning] Using a password on the command line interface can be insecure.
mysqladmin: connect to server at 'localhost' failed
error: 'Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)'
Check that mysqld is running and that the socket: '/var/run/mysqld/mysqld.sock' exists!
bash-4.4# mysqladmin -u docker_healthcheck -pdocker_healthcheck ping
mysqladmin: [Warning] Using a password on the command line interface can be insecure.
mysqladmin: connect to server at 'localhost' failed
error: 'Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)'
Check that mysqld is running and that the socket: '/var/run/mysqld/mysqld.sock' exists!
bash-4.4# mysqladmin -u docker_healthcheck -pdocker_healthcheck ping
mysqladmin: [Warning] Using a password on the command line interface can be insecure.
mysqladmin: connect to server at 'localhost' failed
error: 'Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)'
Check that mysqld is running and that the socket: '/var/run/mysqld/mysqld.sock' exists!
bash-4.4# mysqladmin -u docker_healthcheck -pdocker_healthcheck ping
mysqladmin: [Warning] Using a password on the command line interface can be insecure.
mysqladmin: connect to server at 'localhost' failed
error: 'Access denied for user 'docker_healthcheck'@'localhost' (using password: YES)'
bash-4.4# mysqladmin -u docker_healthcheck -pdocker_healthcheck ping
mysqladmin: [Warning] Using a password on the command line interface can be insecure.
mysqld is alive
bash-4.4# mysqladmin -u docker_healthcheck -pdocker_healthcheck ping
mysqladmin: [Warning] Using a password on the command line interface can be insecure.
mysqladmin: connect to server at 'localhost' failed
error: 'Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)'
Check that mysqld is running and that the socket: '/var/run/mysqld/mysqld.sock' exists!
bash-4.4# mysqladmin -u docker_healthcheck -pdocker_healthcheck ping
mysqladmin: [Warning] Using a password on the command line interface can be insecure.
mysqld is alive
bash-4.4# mysqladmin -u docker_healthcheck -pdocker_healthcheck ping
mysqladmin: [Warning] Using a password on the command line interface can be insecure.
mysqld is alive
すると、全てのケースではなく、たまたまですが上記のようなケース(一度mysqld is alive
になっても後で失敗する)もあったので、どういう仕組みかは別ですが、最後の状態にならずともmysqld is alive
になることはありそう。
mysqladminのpingについて
https://dev.mysql.com/doc/refman/8.0/ja/mysqladmin.html
サーバーが使用可能かどうかをチェックします。 サーバーが稼働中の場合は mysqladmin のリターンステータスは 0 になり、稼働していない場合は 1 になります。 Access denied
のようなエラーの場合でも 0 となります。これは、サーバーは稼働しているが接続を拒否したことを意味しており、サーバーが稼働していない状態とは異なるからです。
とのことで、これ以上の記述がないですがやはり稼働できた = 接続できた とはならならそう。
また、
https://gihyo.jp/dev/serial/01/mysql-road-construction-news/0012
によると、以下の記述がありました。
ただし、残念ながらmysqladmin ping
コマンドも(ps
コマンドよりは便利に使えたとしても)、「mysqldプロセスが起動しており、MySQLプロトコルでしゃべりかけた場合にMySQLプロトコルで応答を返した」以上のことは判定できません。
となると、やっぱりアプリケーションレイヤーからの接続可否のチェックが出来ている訳ではない、ということだと思っています。そのため、Healthy
かどうかを判断材料にするのはよろしくないかな、と考えるようになりました。
次はdocker-composeのマニュアルに紹介されているようなものを試してみたいと思います。
参考記事
Docker の healthcheck を初めて使った話
docker-composeでMySQLの起動を待つ
DockerのHEALTHCHECKの動きを理解する