通过Dockerfile构建nginx镜像,启动失败的原因
通过Dockerfile构建nginx的一些思考。
刚开始接触docker,在利用dockerfile通过centos7的镜像构建nginx镜像时,最后的启动命令上面遇到很多启动失败。然后想了4种启动方法,有两种能正常运行。当时是想不明白为什么,继续深入学习后发现了其中的一些知识没学习到。作记录,分享相互学习。
构建nginx
的Dockerfile
上部分的内容为:
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
运行在前台,所有信息直接输出控制台。