docker-compose:有没有办法阻止`php-fpm`开始直到`db`结束?

我有以下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应该运行一些脚本来创build模式,并且只有在db已经启动并且数据库已经成功创build时才加载伪造的数据。 目前docker-compose up -d --build --force-recreate正在执行以下操作:

  • 使用默认驱动程序创buildnetworkingdockerpyrocms_default
  • 构buildphp-fpm
  • build设httpd
  • 创builddockerpyrocms_db_1
  • 创builddockerpyrocms_php-fpm_1
  • 创builddockerpyrocms_httpd_1

但是因为数据库没有被创build为这样的点,那么dockerpyrocms_php-fpm_1正在退出代码`和原因是它可以连接到数据库:

 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 

显然,“depends_on”是有用的,因为Docker不知道容器何时“准备就绪”,只知道它何时启动。

我可以得到一些build议吗? 任何想法如何解决这个问题?

这里是文件和说明的回购 。

注意:这样的问题只发生在MySQL图像已经被拉出而没有任何改变的情况下。 如果你第一次运行它,那么它会运行,如果你在第二次运行将失败。

我在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 

它按预期工作。 更多信息在这里和这里 。

您可以使用等待 。

wait-for-it.sh是一个纯粹的bash脚本,它将等待主机和TCP端口的可用性。 这对于同步相互依赖的服务(如链接的泊坞窗容器)的启动非常有用。 由于它是一个纯粹的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