通过Dockerfile构建nginx镜像,启动失败的原因

通过Dockerfile构建nginx的一些思考。

刚开始接触docker,在利用dockerfile通过centos7的镜像构建nginx镜像时,最后的启动命令上面遇到很多启动失败。然后想了4种启动方法,有两种能正常运行。当时是想不明白为什么,继续深入学习后发现了其中的一些知识没学习到。作记录,分享相互学习。

构建nginxDockerfile上部分的内容为:

FROM centos:centos7
MAINTAINER zyy 123@qq.com
RUN yum -y install gcc gcc-c++ pcre-devel openssl-devel make
ADD http://nginx.org/download/nginx-1.16.1.tar.gz . 
RUN useradd -s /sbin/nologin nginx && cd nginx-1.16.1 && ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_stub_status_module --with-http_ssl_module && make && make install
EXPOSE 80
ENV PATH /usr/local/nginx/sbin:$PATH

Dockerfile的最后启动命令上纠结过4种启动方式:

Dockerfile 启动命令
1 CMD nginx
2 CMD nginx -g ‘daemon off;’
3 CMD [“nginx”]
4 CMD [“nginx”, “-g”,“daemon off;”]

运行方式都是一样,并得出以下4种结果:

docker run -p 80:80 --name nginx1 -v /data/html:/usr/local/nginx/html  -v /data/conf/nginx.conf:/usr/local/nginx/conf/nginx.conf -v /data/logs:/usr/local/nginx/logs -d nginx:v1
Dockerfile 启动命令 docker run 启动结果
1 CMD nginx 端口无映射
2 CMD nginx -g ‘daemon off;’ 端口正常映射
3 CMD [“nginx”] 端口无映射
4 CMD [“nginx”, “-g”,“daemon off;”] 端口正常映射

经过继续深入的学习后发现了其中的问题。
第一种运行失败,是因为使用的是shell格式。使用shell的话,实际的命令会被包装为sh -c的参数的形式进行执行。比如:

CMD echo $HOME

在实际执行中,会将其变更为:

CMD [ "sh", "-c", "echo $HOME" ]

那么当我用第一种的时候,就相当于执行:

CMD [ "sh", "-c", "nginx"] 

所以和第三种类似,经过查阅资料,执行没有运行起来是因为:

  • 执行失败是因为docker容器默认会把容器内部第一个进程,也就是pid=1的程序作为docker容器是否正在运行的依据,如果docker容器里pid=1的进程结束了,那么docker容器便会直接退出。
  • docker run的时候把command为容器内部命令,如果使用nginx,那么nginx程序将后台运行,这个时候nginx并不是pid为1的程序,而是执行bash,这个bash执行了nginx指令后就结束了,所以容器也就退出,端口没有进行映射。

所以就需要加-g 'daemon off;'的启动参数。daemon的作用是否让nginx运行后台;默认为on,调试时可以设置为off,使得nginx运行在前台,所有信息直接输出控制台。