我有以下docker-compose.yml
文件:
version: '2'
services:
db:
image: mysql
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
volumes:
- sql_data:/var/lib/mysql
httpd:
build: docker/httpd
ports:
- "80:80"
volumes_from:
- php-fpm
php-fpm:
build: docker/php-fpm
depends_on:
- db
volumes:
sql_data:
external: true
容器php-fpm
应该运行一些脚本来创建架构并仅在启动db
并且已成功创建数据库时加载虚假数据。目前docker-compose up -d --build --force-recreate
正在执行以下操作:
dockerpyrocms_default
php-fpm
httpd
dockerpyrocms_db_1
dockerpyrocms_php-fpm_1
dockerpyrocms_httpd_1
但是因为DB没有被创建为这样的点,所以dockerpyrocms_php-fpm_1
正在退出代码`,原因是它可以连接到DB:
php-fpm_1 | [Illuminate\Database\QueryException]
php-fpm_1 | SQLSTATE[HY000] [2002] Connection refused (SQL: select * from information_schema.tables where table_schema = pyrocms and table_name = default_migrations)
php-fpm_1 | [Doctrine\DBAL\Driver\PDOException]
php-fpm_1 | SQLSTATE[HY000] [2002] Connection refused
显然"依赖"有点无用,因为Docker不知道容器什么时候准备就绪,它只知道它什么时候开始。
我可以就此得到一些建议吗?有关如何解决此问题的任何想法?
以下是the repo的文件和说明。
注意:只有在已经拉出MySQL图像并且没有任何更改的情况下才会出现此类问题。如果您是第一次运行它,那么如果您第二次运行它将会失败。
答案 0 :(得分:4)
我在Docker Compose中发现了它:
使用Compose 1.10,现在可以指示您想要一个 依赖等待另一个容器“健康”(即它的 healthcheck在开始之前宣传一个成功的州。
例如:
version: '2.1'
services:
web:
build: .
depends_on:
db:
condition: service_healthy
redis:
condition: service_started
redis:
image: redis
db:
image: redis
healthcheck:
test: "exit 0"
现在我的docker-compose.yml
看起来像是:
version: '2.1'
services:
db:
image: mysql
healthcheck:
test: "exit 0"
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
volumes:
- sql_data:/var/lib/mysql
httpd:
build: docker/httpd
ports:
- "80:80"
volumes_from:
- php-fpm
php-fpm:
build: docker/php-fpm
depends_on:
db:
condition: service_healthy
volumes:
sql_data:
external: true
答案 1 :(得分:1)
您可以使用wait for it。
wait-for-it.sh是一个纯bash脚本,它将等待主机和TCP端口的可用性。它可用于同步相互依赖的服务的启动,例如链接的docker容器。由于它是纯粹的bash脚本,因此它没有任何外部依赖关系。
如何使用?
在php-fpm容器中添加etntrypoint。
entrypoint
看起来像这个脚本:
wait-for-it.sh db:3306 -t 60
# some code interacted with database
# will executed only when database is started up