我大约一个月前开始使用docker,但是找不到满足以下情况的解决方案。
我想部署NodeJS应用程序,因为使用ENTRYPOINT
是最佳做法,我更喜欢使用此命令:
ENTRYPOINT ["node", "src/start.js"]
。
但是我还没有找到一种方法来重新启动容器内的入口点进程,这意味着每次我在nodejs app中更改内容时,我都必须重新启动整个容器,这在具有共享卷的开发环境中有点烦人。
我想到的解决方案是使用流程管理器,并执行ENTRYPOINT ["pm2", "src/start.js"]
之类的操作,但是对于单个流程使用流程管理器似乎是错误的。
我想问一个让我尽可能接近热插拔的方法,而不需要在我的“开发Docker”和“Production Docker”之间更改Dockerfile。
TL; DR :应该可以不在我的开发机器上安装NodeJS或应用程序需要的任何东西,但是在能够重启节点进程的同时从docker容器中运行所有内容容器无需重启容器本身。我无法更改Dockerfile,我想使用ENTRYPOINT
。
修改:
Dockerfile
FROM mhart/alpine-node:4.4.7
# add curl and bash
RUN apk add --update curl bash
#Add user
RUN addgroup websites && adduser -s /bin/bash -D -G websites user-api
#Copy app
WORKDIR /srv/app
ADD src ./src/
ADD node_modules ./node_modules
#Expose port
EXPOSE 3000
ENTRYPOINT ["node", "src/start.js"]
使用
构建图像docker build -t app .
使用
在我的工作站上运行容器docker run -dit -p 53017:3000 --name app -v c:/Users/hesxenon/Projects/app:/srv/app app:latest
答案 0 :(得分:2)
这个pm2有一个很棒的npm模块。在nodejs基础映像中将其作为全局包安装。
使用ENTRYPOINT ["pm2-docker", "src/start.js"]
然后,您可以使用docker exec -ti <containerid> <shell>
输入泊坞窗图片
并使用pm2 stop 0
停止应用,然后重新配置,然后使用pm2 start 0
重新启动它。 Whitout杀死容器因此pid1死亡。
答案 1 :(得分:1)
尝试处理Node.js中的SIGTERM
和SIGINT
信号。
docker stop
和docker restart
向您的流程发送SIGTERM
。如果没有SIGTERM
处理程序,则docker将等待默认的10秒超时,直到它发送SIGKILL
并且您的进程重新启动。这可能是您重启延迟的主要原因。
在处理信号时, ctrl - c 也会发送SIGINT
句柄。
process.on('SIGTERM', function () {
console.log('SIGTERM');
process.exit(0);
}
process.on('SIGINT', function () {
console.log('SIGINT');
process.exit(0);
}
以下是您要启动的流程的some info on the overhead a container requires。这是非常小的,所以快速测试:
docker@default-docker:~$ time true
real 0m 0.00s
user 0m 0.00s
sys 0m 0.00s
docker@default-docker:~$ time docker run busybox true
real 0m 0.64s
user 0m 0.01s
sys 0m 0.00s
因此,与普通进程相比,我的笔记本电脑上的虚拟机在容器中启动进程所需的时间大约需要0.64秒。
答案 2 :(得分:0)
docker stop
takes 10 seconds by default - 您可以使用-t
arg进行调整,但docker restart
几乎应该是即时的,应该与重新启动节点相同。
我不太清楚底层“系统”是什么意思,它不是虚拟机,只要你没有重启Docker主机,重新启动容器(如果它已经设置好了)正确)不应该花费比重新启动过程本身更长的时间。
答案 3 :(得分:0)
我认为最好的选择是使用nodemon:https://www.npmjs.com/package/nodemon
它监视您指定的源目录,并在有任何更改时重新启动。
另外作为增加容器启动时间的额外好处,如果你复制package.json然后在容器上运行npm install它将使用缓存包json,可能会将其减少到一两秒因为node_modules将是您要复制的最大文件夹:How to cache the RUN npm install instruction when docker build a Dockerfile
COPY package.json .
RUN npm install
COPY src ./src/