我尝试过关于对我的网络服务器进行docker化的一些教程和文档,但是我无法通过docker run命令运行该服务。
这是我的Dockerfile:
FROM ubuntu:trusty
#Update and install stuff
RUN apt-get update
RUN apt-get install -y python-software-properties aptitude screen htop nano nmap nginx
#Add files
ADD src/main/resources/ /usr/share/nginx/html
EXPOSE 80
CMD service nginx start
我创建了我的图片:
docker build -t myImage .
当我运行它时:
docker run -p 81:80 myImage
它似乎停止了:
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
90e54a254efa pms-gui:latest /bin/sh -c service n 3 seconds ago Exit 0 prickly_bohr
我希望这可以使用81-> 80端口运行,但事实并非如此。正在运行
docker start 90e
似乎没有做任何事情。
我也试过直接输入
docker run -t -i -p 81:80 myImage /bin/bash
从这里我可以开始服务
service nginx start
从另一个标签我可以看到它按预期工作(也在我的浏览器中):
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
408237a5e10b myImage:latest /bin/bash 12 seconds ago Up 11 seconds 0.0.0.0:81->80/tcp mad_turing
所以我认为我的Dockerfile出错了?任何人都可以帮我解决这个问题,我对Docker很陌生。谢谢!
解决方案:根据Ivant的回答,我找到了另一种在前台启动nginx的方法。我的Dockerfile CMD现在看起来像:
CMD /usr/sbin/nginx -g "daemon off;"
答案 0 :(得分:68)
截至目前,官方nginx图像使用它来运行nginx(参见the Dockerfile):
CMD ["nginx", "-g", "daemon off;"]
就我而言,这足以让它正常启动。网上有教程提示更难实现的方法,但上面看起来很干净。
答案 1 :(得分:23)
CMD
,ENTRTYPOINT
或通过命令行指定的命令正在运行, Docker容器就会运行。在您的情况下,service
命令立即完成,整个容器关闭。
解决此问题的一种方法是直接从命令行启动nginx(确保不要将其作为守护程序运行)。
另一种选择是创建一个小脚本,启动服务然后永远睡眠。类似的东西:
#!/bin/bash
service nginx start
while true; do sleep 1d; done
并运行此命令,而不是直接运行service
命令。
第三种选择是使用runit或类似程序,而不是正常服务。
答案 2 :(得分:7)
使用docker-compose:
要按照推荐的解决方案,请添加到docker-compose.yml:
command: nginx -g "daemon off"
我还发现我可以简单地添加到nginx.conf:
daemon off;
...并继续在docker-compose.yml中使用:
command: service nginx start
...虽然它会使配置文件在docker之外变得不那么便携。
答案 3 :(得分:4)
Docker是一个非常好的官方和用户图像索引。当你想做某事时,很可能有人已经做过了;)
只需搜索' nginx'在index.docker.io上,你会看到,有一个正式的nginx图像:https://registry.hub.docker.com/_/nginx/
您有完整的指南可帮助您启动网络服务器。
随意查看其他用户的nginx图片,看看变种:)
我们的想法是以前台模式启动nginx。
答案 4 :(得分:-1)
如果您运行“ service nginx start”,它将是一个父进程,它将启动nginx的子进程。如果在容器中以CMD运行“ service nginx start”,则该容器的进程ID 1将是“ service nginx start”或ServiceManager(SystemD),而实际的nginx将作为子进程运行。
如果运行“ service nginx start”,然后运行“ ps -ef”,则将得到以下输出。我已经在主机操作系统上运行它。
root@ip-172-31-85-74:/home/ubuntu# service nginx start
root@ip-172-31-85-74:/home/ubuntu#
root@ip-172-31-85-74:/home/ubuntu# ps -ef | grep nginx
root 18593 1 0 12:27 ? 00:00:00 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
www-data 18595 18593 0 12:27 ? 00:00:00 nginx: worker process
root 18599 17918 0 12:27 pts/0 00:00:00 grep --color=auto nginx
因此,这里的进程ID 18593是具有父进程1的子进程。
当容器的进程ID 1退出时,容器退出。在CMD“ service nginx start”的情况下,PID 1是进程管理器,可以是SystemD。它作为子进程启动nginx,然后退出自身,因此容器退出。
同样,如果您在CMD中运行Shell脚本(例如:start.sh),则脚本结束后,容器将退出。即使脚本在执行过程中启动了一些服务(例如-nginx),一旦脚本结束,容器也会退出,因为PID 1属于shell脚本。父进程将是“ ./start.sh”,脚本启动的服务将是子进程。如果您想在CMD中使用shell脚本,并希望容器无限期地运行,则在脚本的最后需要一个不允许其结束的命令。如下所示:
#!/bin/bash
service nginx start
while true; do sleep 1d; done