У меня есть служба создания докеров, настроенная на зависимость от сервера mysql. Проблема в том, что я инициализирую базу данных при первой загрузке службы, поэтому моей службе нужно не только ждать, пока экземпляр mysql будет готов для соединений, но и ждать импорта данных.
myservice:
depends_on:
db:
condition: service_healthy
service_completed_successfully не работает, myservice никогда не загружается. service_healthy работает, но я не вижу способа убедиться, что процесс импорта данных завершен. Это файл sql размером 75 МБ, поэтому для полной загрузки требуется минута.
Большинство проверок работоспособности просто пингуют mysql, что означает, что myservice начинает загружаться до загрузки данных.
version: '3.7'
services:
db:
image: mysql:8.0.33
environment:
MYSQL_DATABASE: 'test'
MYSQL_ROOT_PASSWORD: 'test'
ports:
- 3306:3306
expose:
- 3306
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p$$MYSQL_ROOT_PASSWORD"]
timeout: 20s
retries: 10
volumes:
- ./sql/test.sql:/docker-entrypoint-initdb.d/test.sql
- mysql:/var/lib/mysql
Docker начинает загружаться myservice до того, как данные будут импортированы, и как только импорт данных завершится, Docker перезагружает mysql:
db_1 | 2023-05-11T18:36:01.172885Z 0 [System] [MY-010910] [Server] /usr/sbin/mysqld: Shutdown complete (mysqld 8.0.33) MySQL Community Server - GPL.
db_1 | 2023-05-11 18:36:01+00:00 [Note] [Entrypoint]: Temporary server stopped
db_1 |
db_1 | 2023-05-11 18:36:01+00:00 [Note] [Entrypoint]: MySQL init process done. Ready for start up.
db_1 |
db_1 | 2023-05-11T18:36:01.769092Z 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 | 2023-05-11T18:36:01.770116Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.33) starting as process 1
db_1 | 2023-05-11T18:36:01.776905Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
db_1 | 2023-05-11T18:36:01.904675Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
db_1 | 2023-05-11T18:36:02.168020Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
db_1 | 2023-05-11T18:36:02.168064Z 0 [System] [MY-013602] [Server] Channel mysql_main configured to support TLS. Encrypted connections are now supported for this channel.
db_1 | 2023-05-11T18:36:02.172087Z 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 | 2023-05-11T18:36:02.193999Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Bind-address: '::' port: 33060, socket: /var/run/mysqld/mysqlx.sock
db_1 | 2023-05-11T18:36:02.194118Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.33' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server - GPL.
Что мешает подключениям из моего приложения.
Мне не нужно импортировать данные таким образом — я мог бы просто вручную загрузить mysql и выполнить импорт самостоятельно, а затем загрузить остальные, но я хотел бы автоматизировать это, если смогу.
Проблема в том, что текущая проверка работоспособности возвращает true и разрешает загрузку другой службы, несмотря на то, что импорт все еще выполняется. Мне нужно каким-то образом убедиться, что импорт завершен при проверке работоспособности. Возможно, я мог бы подсчитать, сколько существует таблиц, но я не знаю, как это сделать в данном контексте. Вот с чем мне нужна помощь






Вот пример docker-compose.yml для MySQL с HEALTHCHECK, который подсчитывает количество таблиц, существующих в базе данных:
version: '3'
services:
mysql:
image: mysql:latest
restart: always
environment:
MYSQL_DATABASE: test
MYSQL_ROOT_PASSWORD: test
healthcheck:
test:
- CMD-SHELL
- |
mysql -h localhost -u root -p$${MYSQL_ROOT_PASSWORD} \
--database $${MYSQL_DATABASE} -e 'SHOW TABLES' | \
[ $$(wc -l) -gt 10 ]
interval: 10s
timeout: 5s
retries: 3
Здесь тест $(wc -l) будет искать количество строк из запроса подсчета таблицы mysql, а затем проверять, превышает ли количество строк 10. Если это так, он вернет 0, указывающий, что HEALTHCHECK прошел, в противном случае 1, чтобы указать, что контейнер не готов.
Вы можете проверить состояние работоспособности контейнера, используя:
$ docker inspect --format "{{json .State.Health }}" [container_name] | jq '.'
{
"Status": "healthy",
"FailingStreak": 0,
"Log": [
{
"Start": "2023-05-11T15:36:55.375004326-07:00",
"End": "2023-05-11T15:36:55.433787068-07:00",
"ExitCode": 0,
"Output": "mysql: [Warning] Using a password on the command line interface can be insecure.\n"
}
]
}
Мне пришлось добавить $, чтобы избежать $(wc -l), но после этого он работает правильно!
Не совсем понятно, в чем проблема.
service_healthyэто то, что вы, вероятно, ищете. Вам нужно добавитьHEALTHCHECKв контейнер сервера mysql. Например, запустите запрос CLI, чтобы определить, завершилось ли импортирование изображения, и верните код выхода0, в противном случаеnon-zero