【问题标题】:How to use wait-for-it in docker-compose file?如何在 docker-compose 文件中使用 wait-for-it?
【发布时间】:2020-11-21 16:58:56
【问题描述】:

我是否必须首先克隆 wait-for-it 存储库并编辑 wait-for-it.sh 文件的部分内容?

https://github.com/vishnubob/wait-for-it/blob/master/wait-for-it.sh

我正在尝试在我的客户服务连接并运行其服务器后 5 秒后触发我的主文件。 (或者只要客户服务正确连接服务器)。

我知道在 Dockerfile 中,我们需要将这些命令添加到其中(将文件复制到 workdir,并将 shell 脚本作为可执行文件运行。)

...
COPY wait-for-it.sh . 
RUN chmod +x /wait-for-it.sh
...

这是我当前的 Docker-Compose 文件

version: '3'
services:
  books:
    build: './books'
    container_name: "horus-books"
    ports:
      - "30043:30043"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"

  customers:
    depends_on:
      - books
    build: './customers'
    container_name: "horus-customers"
    ports:
      - "6000:6000"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"

  main:
    depends_on: 
      - customers
    build: './main'
    container_name: "horus-main"
    ports:
      - "4555:4555"
    command: ["./wait-for-it.sh", "customers:6000", "--", "node", "main.js"]
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
    

主要服务 Dockerfile

FROM node:12.14.0
WORKDIR /usr/src/app
COPY package*.json ./
COPY . /usr/src/app
COPY wait-for-it.sh . 
RUN chmod +x /wait-for-it.sh
RUN npm install
EXPOSE 4555
CMD ["node", "main.js"]

【问题讨论】:

  • 是在构建容器时等待,还是在运行容器时等待?
  • @tadman 我想在客户服务器运行时等待(所以在运行容器时)。
  • RUN 命令在构建阶段执行一次,它们不会影响正在运行的容器。您需要更改您的CMDENTRYPOINT

标签: docker docker-compose dockerfile docker-registry


【解决方案1】:

通常你根本不会把它放在你的docker-compose.yml 文件中。脚本需要内置到镜像中,并且需要知道它的标准启动顺序才能运行它。

有一种相当常见的模式是使用入口点脚本进行一些初始设置,然后使用exec "$@" 将容器的命令作为主进程运行。例如,这使您可以使用wait-for-it.sh 脚本等待后端启动,然后运行任何主命令。例如,docker-entrypoint.sh 脚本可能如下所示:

#!/bin/sh

# Abort on any error (including if wait-for-it fails).
set -e

# Wait for the backend to be up, if we know where it is.
if [ -n "$CUSTOMERS_HOST" ]; then
  /usr/src/app/wait-for-it.sh "$CUSTOMERS_HOST:${CUSTOMERS_PORT:-6000}"
fi

# Run the main container command.
exec "$@"

您需要确保此脚本是可执行的,并将其设为映像的ENTRYPOINT,否则您可以让 Dockerfile 保持几乎不变。

FROM node:12.14.0
WORKDIR /usr/src/app
COPY package*.json ./
# Do this _before_ copying the entire application in
# to avoid repeating it on rebuild
RUN npm install
# Includes wait-for-it.sh and docker-entrypoint.sh
COPY . ./
RUN chmod +x ./wait-for-it.sh ./docker-entrypoint.sh
EXPOSE 4555
# Add this line
# It _must_ use the JSON-array syntax
ENTRYPOINT ["./docker-entrypoint.sh"]
CMD ["node", "main.js"]

在您的docker-compose.yml 中,您需要添加配置来说明后端在哪里,但您不需要覆盖command:

main:
  depends_on: 
    - customers
  build: './main'
  ports:
    - "4555:4555"
  environment:
    - CUSTOMERS_HOST=customers

【讨论】:

  • 这太棒了,谢谢大卫!几个问题:对于 CUSTOMERS_PORT,我是否必须创建它或将其添加到 docker-compose 'environment' 字典中并将其等同于正确的端口?另外,您提供了一个等待它的脚本示例,但我想知道 ./docker-entrypoint.sh 脚本的外观(抱歉,我以前从未使用过 shell 脚本!)
  • 第一个脚本是入口点。 Bourne shell 构造 ${CUSTOMERS_PORT:-6000} 如果在环境中设置则使用 $CUSTOMERS_PORT 的值,如果未在环境中设置,则使用 6000,因此您无需手动设置。
  • # Run the main container command. 是什么意思?就我而言,我有一个 .jar 我想在等待另一项服务后执行。它位于容器内的/app.jar 下。
  • 没关系,我刚刚在docker-entrypoint.sh 里面做了exec java -jar ./app.jar,这完全没问题!
  • 在你的 Dockerfile 中你应该设置CMD java -jar ./app.jar,当exec "$@" 行运行时,这将是“主容器命令”。
猜你喜欢
  • 1970-01-01
  • 2018-12-16
  • 2018-08-07
  • 2023-01-17
  • 2022-06-17
  • 2021-06-02
  • 2021-10-05
  • 2018-08-29
  • 2021-07-02
相关资源
最近更新 更多