Dockerized nginx无法启动

时间:2014-06-16 10:11:39

标签: nginx docker

我尝试过关于对我的网络服务器进行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;"

5 个答案:

答案 0 :(得分:68)

截至目前,官方nginx图像使用它来运行nginx(参见the Dockerfile):

CMD ["nginx", "-g", "daemon off;"]

就我而言,这足以让它正常启动。网上有教程提示更难实现的方法,但上面看起来很干净。

答案 1 :(得分:23)

只要您使用CMDENTRTYPOINT或通过命令行指定的命令正在运行,

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