【问题标题】:Wait for a docker container to be ready with command in docker-compose.yml使用 docker-compose.yml 中的命令等待 docker 容器准备就绪
【发布时间】:2019-07-09 12:19:34
【问题描述】:

我的 docker-compose.yml 中有一个 mysql-db 和 prisma 映像。我希望 prisma 等待数据库准备好,否则 prisma 会不断重新启动并且它根本无法工作。我从here知道,我可以使用./wait-for-it,但搜索了一段时间后无法连接。

version: '3'
services:
  prisma:
    image: prismagraphql/prisma:1.25
    restart: unless-stopped
    ports:
    - "4001:4466"
    depends_on:
    - db

    # I added this command
    command: ["./wait-for-it.sh", "db:33061", "--"] 

    environment:
      PRISMA_CONFIG: |
        managementApiSecret: server.secret.123
        port: 4466
        databases:
          default:
            connector: mysql
            active: true
            host: db
            port: 3306
            user: ***
            password: ***
  db:
    image: mysql:5.7
    restart: unless-stopped
    command: --default-authentication-plugin=mysql_native_password
    environment:
      MYSQL_USER: ***
      MYSQL_ROOT_PASSWORD: ***
    ports:
      - "33061:3306"
    volumes:
      - /docker/mysql:/var/lib/mysql

我添加了上面的命令,但没有任何改变,甚至日志中没有错误,但据我了解,该命令在容器内运行。

  1. 如何将 ./wait-for-it.sh 放入容器中?
  2. 这甚至可以与命令一起以这种方式工作还是取决于 在棱镜图像上?
  3. 否则,我将如何实现等待?

我只有 docker-compose 文件并想做docker-compose up -d

【问题讨论】:

    标签: docker docker-compose startup


    【解决方案1】:

    现在我发现了如何将wait-for-it.sh 包含到容器中。

    我将 wait-for-it.sh 下载到项目文件夹中,然后创建了一个名为 Dockerfile 的文件,其内容为:

    FROM prismagraphql/prisma:1.25
    COPY ./wait-for-it.sh /app/wait-for-it.sh
    RUN chmod +x /app/wait-for-it.sh
    ENTRYPOINT ["/bin/sh","-c","/app/wait-for-it.sh db:3306 -t 30 -- /app/start.sh"]
    

    在我的 docker-compose.yml 中,我替换了 image: prismagraphql/prisma:1.25build: . 会导致从我的项目路径中的 Dockerfile 进行新构建。

    现在新镜像将从 prisma 镜像构建,wait-for-it.sh 将被复制到新镜像中。然后 ENTRYPOINT 被覆盖,prisma 将等待数据库准备好。

    【讨论】:

      【解决方案2】:

      您混淆了内部和外部端口。数据库在网络内的端口3306 上可见,因此您必须等待db:3306 而不是33061

      端口暴露在用户定义的桥接网络中无效,默认由docker-compose创建。默认情况下,所有端口对网络内的容器都是可见的。当您公开端口时,您会使其在外部网络可见。

      另外,请确保图像 prismagraphql/prisma:1.25ENTRYPOINT 是什么。如果不是/bin/sh -c 或其他类型的shell,您的command 将不会被执行。

      更新

      如果您在与/bin/sh -c 不同的基本映像中获得ENTRYPOINT,您可以覆盖它。假设你有/bin/sh -c /app/start.sh,你可以做以下魔法:

      docker-compose.yml

      ...
      services:
        prisma:
          entrypoint: ["/bin/sh", "-c", "'./wait-for-it.sh db:3306 && /app/start.sh'"] 
      

      【讨论】:

      • 好的,谢谢。我通过搬运工发现/bin/sh -c /app/start.sh 是图像的入口点。那么我的命令会被执行吗?
      • 视情况而定。您将获得整体命令为/bin/sh -c /app/start.sh ./wait-for-it.sh db:33061 --。因此,取决于start.sh 的内容 - 您可以执行或不执行脚本
      • 好的,它似乎覆盖了入口点。我现在的问题是,我不知道如何让wait-for-it.sh 工作,因为我不知道如何将它放入容器中以便可以在那里执行。
      • 不应该将./wait-for-it.sh db:33061 改为./wait-for-it.sh db:3306 吗?
      • 当然,谢谢,我的错 :) 那是我帖子前半部分的主题)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-11-10
      • 2023-04-01
      • 2014-03-29
      • 1970-01-01
      • 2021-08-09
      • 1970-01-01
      • 2022-10-23
      相关资源
      最近更新 更多