docker 容器启动后运行自定义脚本

我有以下nodejs dockerfile:

# pull image
FROM node:13.12.0-alpine

# set working directory
WORKDIR /app

# add `/app/node_modules/.bin` to $PATH
ENV PATH /app/node_modules/.bin:$PATH

# install app dependencies
COPY package.json ./
COPY package-lock.json ./
RUN npm install

# add app
COPY . ./

# start app
CMD node server dev

启动后,我需要在容器内动态运行自定义 JS 脚本。我怎样才能做到这一点?

更新:我尝试在 CMD 之后添加以下入口点,但 CMD 和 ENTRYPOINT 均未执行:

ENTRYPOINT node customScript.js

添加了一个包装外壳脚本 (startup.sh) 以包含这两个命令:

#!/bin/sh

nohup node server dev > startup.log && node data/scripts/custom.js > custom.log

将 CMD 替换为:

CMD ["./startup.sh"]

这只会执行 shell 中的第一个命令,而不是第二个。我也没有看到在容器中创建的输出重定向日志文件。

stack overflow Run custom script after docker container startup
原文答案

答案:

作者头像

理想情况下,您应该在后台运行 nohup 进程

由于 CMDENTRYPOINT 没有问题

#!/bin/sh

nohup node server dev > startup.log && node data/scripts/custom.js > custom.log

在您的 nohup 命令中使用 & last 将进程启动为背景模式

nohup ./yourscript &

或者

nohup command &

在此之后,您可以运行 node 命令

示例

nohup nice "$0" "calling_myself" "$@" > $nohup_out &
node index.js
sleep 1
tail -f $nohup_out
作者头像

如果您需要在 docker 启动时运行两条命令,一条应该是非阻塞的,另一条可以是阻塞调用的。

如果两个调用都阻塞,那么您需要在单独的线程/进程中启动一个命令,然后运行另一个命令。

这可以在父脚本(sh)中实现,该脚本可以为一个命令启动一个进程并调用当前进程中的最后一个命令。

https://www.linuxtopia.org/online_books/advanced_bash_scripting_guide/internal.html https://tldp.org/LDP/Bash-Beginners-Guide/html/sect_01_04.html

作者头像

您应该使用主管在单个容器中运行多个进程。他们将/可能还会再次自动重启死亡进程。如果没有主管,您的流程可能会一团糟。

前任:

就我而言,我在项目 s6 中使用 alpine-s6-nginx-php 在单个容器中运行进程。该项目有一个类似 OOP 的继承模型:

  • 基于图像 alpine-s6-base
  • alpine-s6-nginx
  • alpine-s6-nginx-php

基础镜像准备 s6 设置,nginx 镜像添加 nginx 进程,最终 alpine-s6-nginx-php 镜像添加 php-fpm7 进程。你可以查看这些 repos 和 s6 supervisor。不需要为每个进程分离层,所有进程都可以添加到单个 Dockerfile 中。您也可以使用 s6 替代品,如系统等。

TLDR;您可以使用 s6-overlay 轻松构建 s6 监督容器映像。

作者头像

您可以在脚本末尾添加入口点关键字和脚本名称,例如 ENTRYPOINT[“sh”, “Abc.sh”]