简体   繁体   English

Docker重启入口点

[英]Docker restart entrypoint

I've started using docker about a month ago now and cannot find a satisfying solution to the following situation. 我大约一个月前开始使用docker,但是找不到满足以下情况的解决方案。

I want to deploy a NodeJS application and since using ENTRYPOINT is a best practice I'd prefer to use this command: ENTRYPOINT ["node", "src/start.js"] . 我想部署一个ENTRYPOINT应用程序,因为使用ENTRYPOINT是一种最佳实践,我更喜欢使用这个命令: ENTRYPOINT ["node", "src/start.js"]

However I have not found a way to restart the entrypoint process within the container, which means that everytime I change something inside the nodejs app I have to restart the whole container which is mildly annoying in a development environment with a shared volume. 但是我还没有找到一种方法来重新启动容器内的入口点进程,这意味着每次我在nodejs app中更改一些内容时,我必须重新启动整个容器,这在具有共享卷的开发环境中有点烦人。

A solution I thought of would be to use a process manager for this, and do something like ENTRYPOINT ["pm2", "src/start.js"] but using a process manager for a single process seems wrong to me. 我想到的一个解决方案就是使用流程管理器,并执行类似ENTRYPOINT ["pm2", "src/start.js"]但是使用流程管理器进行单个流程对我来说似乎不对。

I'd like to ask for an approach that gets me as close to hot-swapping as possible without changing the Dockerfile at all between my "Development Docker" and the "Production Docker". 我想问一个让我尽可能接近热插拔的方法,而不需要在我的“开发Docker”和“Production Docker”之间更改Dockerfile。

TL;DR : It should be possible to NOT have NodeJS or anything the app requires installed on my development machine but run everything from within a docker container while being able to restart the node process in said container without having to restart the container itself. TL; DR :应该可以不在我的开发机器上安装NodeJS或应用程序需要的任何东西,而是从docker容器中运行所有内容,同时能够在所述容器中重新启动节点进程而无需重新启动容器本身。 It is not an option for me to change the Dockerfile and I'd like to use ENTRYPOINT . 我不能选择更改Dockerfile,我想使用ENTRYPOINT

EDIT : 编辑
Dockerfile 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"]

Building the image with 使用构建图像

docker build -t app .

Running the container on my workstation with 用我的工作站运行容器

docker run -dit -p 53017:3000 --name app -v c:/Users/hesxenon/Projects/app:/srv/app app:latest

There is a great npm module for this pm2 . 这个pm2有一个很棒的npm模块。 Install it as a global package in your nodejs base image. 在nodejs基础映像中将其作为全局包安装。

Start your app with ENTRYPOINT ["pm2-docker", "src/start.js"] 使用ENTRYPOINT ["pm2-docker", "src/start.js"]启动你的应用程序

You can then enter the docker image with docker exec -ti <containerid> <shell> and stop app using pm2 stop 0 , then reconfigure, and start it again with pm2 start 0 . 然后,您可以使用docker exec -ti <containerid> <shell>输入docker镜像,并使用pm2 stop 0停止应用程序,然后重新配置,并使用pm2 start 0再次启动它。 Whitout killing the container thus to pid1 dying. Whitout杀死容器因此pid1死亡。

Try handling the SIGTERM and SIGINT signals in Node.js. 尝试在Node.js中处理SIGTERMSIGINT信号。

A docker stop and docker restart sends a SIGTERM to your process. docker stopdocker restart向您的进程发送SIGTERM If there is no SIGTERM handler, docker will wait the default 10 second timeout until it sends a SIGKILL and your process restarts. 如果没有SIGTERM处理程序,docker将等待默认的10秒超时,直到它发送SIGKILL并且您的进程重新启动。 This could be the bulk of your restart delay. 这可能是您重启延迟的主要原因。

While you are dealing with signals, a ctrl - c sends a SIGINT so handle that too. 在处理信号时, ctrl -c也会发送一个SIGINT处理SIGINT

process.on('SIGTERM', function () {
  console.log('SIGTERM');
  process.exit(0);
}
process.on('SIGINT', function () {
  console.log('SIGINT');
  process.exit(0);
}

On Dockers Overhead 在码头工人的头顶上

Here is some info on the overhead a container requires on top of the process you are launching. 以下是有关容器在您启动的进程之上所需的开销的一些信息 It is pretty minimal, so a quick test: 这是非常小的,所以快速测试:

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

So a VM on my laptop takes about 0.64s longer to launch a process in a container compared to a plain process. 因此,与普通进程相比,我的笔记本电脑上的VM需要大约0.64秒才能在容器中启动进程。

docker stop takes 10 seconds by default - you can adjust this with a -t arg, but docker restart should be nearly instant and should be the same thing as restarting node. 默认情况下, docker stop 需要10秒 - 您可以使用-t arg进行调整,但docker restart几乎是即时的,应该与重启节点相同。

I'm not quite sure what you mean by underlying "system" , it's not a VM and as long as you aren't restarting the Docker host, restarting the container (if it's set up properly) shouldn't take much longer than restarting the process itself. 我不太清楚底层“系统”是什么意思,它不是虚拟机,只要你没有重启Docker主机,重新启动容器(如果设置正确)不应该花费比重启更长的时间过程本身。

I think the best option is to use nodemon: https://www.npmjs.com/package/nodemon 我认为最好的选择是使用nodemon: https ://www.npmjs.com/package/nodemon

It monitors the source directories you specify and restarts if anything changes. 它监视您指定的源目录,如果有任何更改,则重新启动。

Also as a added bonus to increase the startup time of the container, if you copy the package.json over then run npm install on the container it will use the cached package json, will probably cut it down to a second or two as the node_modules will be your biggest folder to copy: How to cache the RUN npm install instruction when docker build a Dockerfile 另外作为增加容器启动时间的额外好处,如果你复制package.json然后在容器上运行npm install它将使用缓存包json,可能会将其缩减为一两秒作为node_modules将是您要复制的最大文件夹: 当docker构建Dockerfile时,如何缓存RUN npm install指令

COPY package.json .
RUN npm install
COPY src ./src/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM