我有一个使用 mysql、express 和 React 的 dockerized 应用程序。
在启动 Express 应用程序之前,我需要首先使用
docker-entrypoint-initdb.d
初始化 mysql。但是,当 mysql 服务器启动时,它不会立即执行启动 .sql 脚本,并且 my_database_name
最初是空的。
在这段时间内,我的 Express 应用程序启动并尝试查询空数据库。稍后,初始化脚本按预期工作并填充
my_database_name
,但那时已经太晚了,因为我的 Express 应用程序已经启动了。
我已经尝试了
depends_on/condition
,如下所示,但Version 3 no longer supports the condition form of depends_on
如文档中所述。
version: '3.8'
services:
api-server:
build:
context: ./server
dockerfile: ./Dockerfile
image: myapp_server
env_file: ./server/.env
stdin_open: true
tty: true
depends_on:
mysqldb:
condition: service_healthy
ports:
- 9000:9000
networks:
- mysern-app
container_name: my_express_app
mysqldb:
image: mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: my_database_name
volumes:
- mysql-data:/data/db
- ./db/backup/:/mysql/backup
- ./db/init:/docker-entrypoint-initdb.d
healthcheck:
test: 'not sure what to write in here as well'
interval: 1s
retries: 120
networks:
- mysern-app
ports:
- 3306:3306
container_name: my_mysql_app
networks:
mysern-app:
driver: bridge
volumes:
mysql-data:
driver: local
我最终想做这个序列:
启动 mysqldb > 从脚本填充表 > 启动express应用程序
您可以做几件事:
restart: always
添加到您的 api-server
。如果它因 MySQL 尚不可用而崩溃 - 它将重新启动,直到 MySQL 可用。我假设如果 MySQL 不可用,你的api-server
将会崩溃。docker-compose 是您的编排器,它可以帮助您并处理故障。在现实世界中,你的 MySQL 也可能有一秒钟不可用,你必须知道如何处理它。
这对我有用:
version: "3.7"
services:
acme-db:
image: mysql:5.7
command: mysqld --sql_mode="" --max_connections=1100 --general-log=1 --general-log-file=/tmp/mysql-general-log.log
container_name: eventhos-db
ports:
- "3306:3306"
volumes:
- ./database:/docker-entrypoint-initdb.d
environment:
MYSQL_ROOT_PASSWORD: changeme
MYSQL_PASSWORD: changeme
MYSQL_USER: "usr_acme"
MYSQL_DATABASE: "acme"
TZ: America/Lima
deploy:
resources:
limits:
memory: 512M
healthcheck:
test: 'cat /tmp/mysql-general-log.log | grep "root@localhost on using Socket"'
interval: 10s
retries: 120
没有一种本地方法可以询问 mysql dump 是否已完全导入。
研究时,我发现了一个名为 mysql General_log 的内部 mysql 日志文件,并在 dockerized mysql 中查看其内容,我发现了一种模式:
如果一切正常,最后会出现以下行:“root@localhost on using Socket”一次
因此,如果我们在 docker-compose 中使用 command: 启用此日志:
command: mysqld --sql_mode="" --max_connections=1100 --general-log=1 --general-log-file=/tmp/mysql-general-log.log
健康检查只是搜索这些行
cat /tmp/mysql-general-log.log | grep "root@localhost on using Socket"
注意:健康检查间隔小于10秒,不起作用!
mysql:
build: ...
...
healthcheck:
test: mysql ${DB_NAME} --user=${DB_USER} --password='${DB_PWD}' --silent --execute "SELECT 1;"
interval: 30s
timeout: 10s
retries: 5
示例 .env 文件
DB_HOST=...
DB_NAME=...
DB_USER=...
DB_PWD=...