MySQL-Docker镜像:如何等到填充表之后再启动下一个容器

时间:2019-09-15 10:19:18

标签: mysql docker docker-compose dockerfile

我正在尝试启动使用MySQL作为数据库的服务器的Docker容器。为了启动该服务器,我希望首先创建MySQL表,否则服务器退出并给出错误。我希望我的第二个容器等到MySQL docker映像完成创建表为止。

我不能从服务器端处理此问题,因为它不是我拥有的产品。我正在使用Docker-compose版本3,并使用wait-for-it.sh等待MySQL容器启动,然后再启动服务器容器。另外,我已将SQL脚本添加到“ /docker-entrypoint-initdb.d”中,以便在启动时创建表。但是,wait-for-it.sh只等到MySQL服务器准备开始通信时,直到所有表都被创建(MySQL服务器处于空闲状态)。因此,当我第一次启动容器时,由于尚未创建表,因此服务器退出并显示错误代码。

version: '3.7'
services:

  mysql:
    container_name: mysql
    image: mysql:5.7.24
    ports:
      - "3306"
    volumes:
      - "./mysql/scripts:/docker-entrypoint-initdb.d"
    command: [--ssl=0]
    healthcheck:
      test: ["CMD", "mysqladmin" ,"ping", "-uroot", "-proot"]
      interval: 10s
      timeout: 10s
      retries: 5
      start_period: 30s

  server:
    container_name: server
    image: server
    depends_on:
      - "mysql"
    volumes:
      - "./wait-for-it.sh:/home/wait-for-it.sh"
    entrypoint:
      - "/home/wait-for-it.sh"
      - "mysql:3306"
      - "-t"
      - "30"
      - "--"
      - "./docker-entrypoint.sh"

我不想增加第二个容器的启动时间,因为这只会在我第一次初始化容器时发生。在第一次创建表之后,这种情况就不会出现并且不会发生,如果我增加了第二个容器的启动时间,用户将不得不面对不必要的延迟。

2 个答案:

答案 0 :(得分:0)

您误解了wait-for-it的概念。无法按照您的期望运行。

它不会等待填充整个数据库,它只会等待主机和TCP端口的可用性,如果wait-for-it能够创建连接,那么它将标记容器已准备就绪。

您可以在应用程序端处理这种逻辑。

  

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

您可以尝试的其他选项

您可以使用-t or --timeout=选项设置自己的超时时间。将超时值设置为0将禁用超时:

答案 1 :(得分:0)

您无法使用wait-for-it.sh脚本等待数据库表填充。如Adii所述,wait-for-it.sh脚本等待主机和TCP端口的可用性,如果wait-for-it能够创建连接,则它将标记容器已准备就绪。

理想情况下,未填充表时,容器化的应用程序不应退出。它应该等到表完成填充为止。这应该由应用程序处理。

如果您无法控制在应用程序端进行处理,则有两种解决方法,但都不是理想选择。

  1. -t or --timeout=选项与wait-for-it.sh脚本一起使用,如Adii所述。但是,所需的超时值将随时间变化,并且您将不得不增加超出理想所需时间的额外时间。这将导致更长的启动时间。
  2. 另一个更复杂的解决方法是在创建所有必需的表以用作检查表是否已完成填充的标志之后,在数据库中创建表或条目。您可以在启动应用程序容器之前添加mysql客户端容器,并设置其运行状况检查以尝试从MySQL服务器读取标志表/条目。可以用于测试目的,但不建议用于生产环境。