Docker-compose检查mysql连接是否准备就绪
我试图确保我的应用程序容器在数据库容器启动且准备接受连接之前不运行迁移/启动。
因此,我决定使用运行状况检查,并取决于docker compose文件v2中的选项。
在应用程序中,我有以下内容
app:
...
depends_on:
db:
condition: service_healthy
另一方面,数据库具有以下运行状况检查
db:
...
healthcheck:
test: TEST_GOES_HERE
timeout: 20s
retries: 10
我尝试了几种方法,例如:
确保已创建数据库DIRtest: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"]
获取mysql版本:test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"]
对管理员执行ping操作(将db容器标记为运行状况良好,但似乎不是有效的测试)test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"]
有人对此有解决方案吗?
6个解决方案
60 votes
version: "2.1"
services:
api:
build: .
container_name: api
ports:
- "8080:8080"
depends_on:
db:
condition: service_healthy
db:
container_name: db
image: mysql
ports:
- "3306"
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
MYSQL_USER: "user"
MYSQL_PASSWORD: "password"
MYSQL_DATABASE: "database"
healthcheck:
test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"]
timeout: 20s
retries: 10
直到db容器运行正常(基本上直到mysqladmin启动并接受连接),api容器才会启动。
John Kariuki answered 2019-12-28T00:20:26Z
8 votes
如果可以更改容器以等待mysql准备就绪,请执行此操作。
如果您无法控制要将数据库连接到的容器,则可以尝试等待特定的端口。
为此,我使用一个小脚本来等待另一个容器公开的特定端口。
在此示例中,myserver将等待mydb容器的端口3306可以访问。
# Your database
mydb:
image: mysql
ports:
- "3306:3306"
volumes:
- yourDataDir:/var/lib/mysql
# Your server
myserver:
image: myserver
ports:
- "....:...."
entrypoint: ./wait-for-it.sh mydb:3306 -- ./yourEntryPoint.sh
您可以在这里找到脚本脚本文档
nono answered 2019-12-28T00:21:04Z
7 votes
如果使用docker-compose v3 +,则已删除wget的选项sh。
推荐的路径是使用wget、wget或wget。在wget文件中,将命令更改为:
command: sh -c 'bin/wait-for db:3306 -- bundle exec rails s'
我个人更喜欢wget,因为它可以在Alpine容器中运行(兼容sh,不依赖于bash)。 缺点是它取决于netcat,因此,如果决定使用它,请确保已在容器中安装netcat,或将其安装在Dockerfile中,例如使用:
RUN apt-get -q update && apt-get -qy install netcat
我还分叉了wget项目,以便它可以检查健康的HTTP状态(它使用wget)。 然后,您可以执行以下操作:
command: sh -c 'bin/wait-for http://api/ping -- jest test'
Capripot answered 2019-12-28T00:21:38Z
5 votes
您好,我使用docker-compose v2.1进行了简单的健康检查,我使用了:
/usr/bin/mysql --user=root --password=rootpasswd --execute \"SHOW DATABASES;\"
基本上,它运行一个简单的mysql命令docker-compose.yaml,以数据库中密码为rootpasswd的用户root为例。
如果命令成功执行,则数据库已启动且已准备就绪,因此运行状况检查路径。 您可以使用docker-compose.yaml,以便每隔一段时间进行测试。
删除其他字段以提高可见性,这就是您的docker-compose.yaml中的样子。
version: '2.1'
services:
db:
...
healthcheck:
test: "/usr/bin/mysql --user=root --password=rootpasswd --execute \"SHOW DATABASES;\""
interval: 2s
timeout: 20s
retries: 10
app:
...
depends_on:
db:
condition: service_healthy
Sylhare answered 2019-12-28T00:22:12Z
4 votes
我按照以下示例修改了docker-compose.yml,它可以正常工作。
mysql:
image: mysql:5.6
ports:
- "3306:3306"
volumes:
# Preload files for data
- ../schemaAndSeedData:/docker-entrypoint-initdb.d
environment:
MYSQL_ROOT_PASSWORD: rootPass
MYSQL_DATABASE: DefaultDB
MYSQL_USER: usr
MYSQL_PASSWORD: usr
healthcheck:
test: mysql --user=root --password=rootPass -e 'Design your own check script ' LastSchema
就我而言,../schemaAndSeedData包含多个架构和数据种子sql文件。 Design your own check script可以类似于以下select * from LastSchema.LastDBInsert。
虽然网络依赖的容器代码是
depends_on:
mysql:
condition: service_healthy
Mukesh Agarwal answered 2019-12-28T00:22:41Z
4 votes
这样就足够了
version: '2.1'
services:
mysql:
image: mysql
ports: ['3306:3306']
environment:
MYSQL_USER: myuser
MYSQL_PASSWORD: mypassword
healthcheck:
test: mysqladmin ping -h 127.0.0.1 -u $$MYSQL_USER --password=$$MYSQL_PASSWORD
Maksim Kostromin answered 2019-12-28T00:23:01Z