docker-compose:有没有办法阻止`php-fpm`在`db`结束之前启动?

时间:2017-01-27 02:15:23

标签: docker docker-compose

我有以下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图像并且没有任何更改的情况下才会出现此类问题。如果您是第一次运行它,那么如果您第二次运行它将会失败。

2 个答案:

答案 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

它按预期工作。更多信息herehere

答案 1 :(得分:1)

您可以使用wait for it

  

wait-for-it.sh是一个纯bash脚本,它将等待主机和TCP端口的可用性。它可用于同步相互依赖的服务的启动,例如链接的docker容器。由于它是纯粹的bash脚本,因此它没有任何外部依赖关系。

如何使用? 在php-fpm容器中添加etntrypointentrypoint看起来像这个脚本:

wait-for-it.sh db:3306 -t 60
# some code interacted with database 
# will executed only when database is started up