【问题标题】:Running bash script in a dockerfile在 dockerfile 中运行 bash 脚本
【发布时间】:2020-08-20 12:41:30
【问题描述】:

我正在尝试在这样的 bash 脚本中运行多个 js 文件。这行不通。容器出现但不运行脚本。但是,当我 ssh 到容器并运行此脚本时,脚本运行良好并且节点服务出现。谁能告诉我我做错了什么?

Dockerfile

FROM node:8.16

MAINTAINER Vivek

WORKDIR /a

ADD . /a
RUN cd /a && npm install

CMD ["./node.sh"]

脚本如下

node.sh

#!/bin/bash

set -e

node /a/b/c/d.js &

node /a/b/c/e.js &

【问题讨论】:

  • 如果在入口点脚本中使用& 将两个进程置于后台,脚本将执行此操作然后退出。你需要一个前台进程。你应该在前台留下一个,使用wait,使用supervisord等。见docs.docker.com/config/containers/multi-service_container
  • 谢谢。我已从上一个命令中删除 & 以使进程不退出。

标签: node.js bash docker docker-entrypoint


【解决方案1】:

正如@hmm 提到的,您的脚本可能已运行,但您的容器并未等待您的两个子进程完成。

您可以将node.sh 更改为:

#!/bin/bash

set -e

node /a/b/c/d.js &
pid1=$!

node /a/b/c/e.js &
pid2=$!

wait pid1
wait pid2

结帐https://stackoverflow.com/a/356154/1086545 以获得更通用的等待子流程完成的解决方案。

正如@DavidMaze 所提到的,一个容器通常应该运行一个“服务”。当然,您可以决定系统中服务的构成。正如docker官方描述的那样:

通常建议您通过每个容器使用一项服务来区分关注区域。该服务可能会分叉成多个进程(例如,Apache Web 服务器启动多个工作进程)。拥有多个进程是可以的,但要充分利用 Docker,请避免一个容器负责整个应用程序的多个方面。

更多详情请见https://docs.docker.com/config/containers/multi-service_container/

【讨论】:

    【解决方案2】:

    通常您应该在容器中只运行一个进程。但是,您可以从单个映像运行任意数量的容器,并且可以轻松设置容器在启动时将运行的命令。

    将图像的CMD 设置为您认为最常见的路径:

    CMD ["node", "b/c/d.js"]
    

    如果您为此使用 Docker Compose,则可以为两个容器指定 build: .,但在第二个容器中,指定备用 command:

    version: '3'
    services:
      node-d:
        build: .
      node-e:
        build: .
        command: node b/c/e.js
    

    使用裸docker run 可以在图像名称后指定备用命令

    docker build -t me/node-app .
    docker run -d --name node-d me/node-app
    docker run -d --name node-e me/node-app \
      node b/c/e.js
    

    这让您可以为每个容器独立设置重启策略;如果您在 Docker Swarm 或 Kubernetes 等集群环境中运行它,您也可以独立扩展这两个容器/pod/进程。

    【讨论】:

    • 乔恩给出的第一个解决方案对我有用。感谢您的提示。
    猜你喜欢
    • 2021-08-26
    • 2022-01-15
    • 2023-03-07
    • 2016-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-22
    • 1970-01-01
    相关资源
    最近更新 更多