来自docker技术入门与实践啦
Docker不是虚拟机,容器就是进程;这就是说容器中的应用都应该以前台执行,而不是虚拟机里面那样,用systemd去启动后台服务,容器中没有后台服务的概念;就是说如果用shell格式命令的话会将命令包装为sh -c的参数进行执行,例如
CMD service nginx start
这会导致容器执行后立即退出,而且容器内也不能用systemctl这样的命令,对于容器来说,启动程序就是容器应用程序,容器就是为了主进程而存在的,主进程退出,容器就失去了存在的意义,service nginx start这种命令是希望upstart来以后台守护进程形式启动nginx服务,在容器中这个命令就是sh -c service nginx start ,主进程是sh,那么service nginx start命令结束后,sh也就结束了,sh作为主进程退出了,那么容器自然退出;正确方式是直接执行nginx可执行文件,并且要求以前台形式执行,如
nginx -g daemon off
指令格式一般推荐exec格式,在解析时会被解析为JSON数组,因此一定要用“双引号而不是单引号;
在docker build 命令的最后一行,会有一个 .
比如
docker build -t nginx:v3 .
虽然这个 . 的确表示当前目录,但是并不是指定Dockerfile的所在路径,而是指定上下文路径context,理解这个context
首先要理解docker build的工作原理,Docker在运行时分为Docker引擎(服务端的守护进程啦)和客户端工具;
Docker的引擎提供了REST API,称为Docker Remote API,如docker命令这样的客户端工具,就是通过这组API与Docker引擎
交互从而完成各种功能,表面上在本地执行的各种docker功能都是使用的远程调用形式在服务端(docker引擎)完成,这种
c/s设计,能够让我们轻易的远程操控远程服务器的Docker引擎;
所以啦,docker build命令构建镜像,其实并非在本地,而是在服务端,即Docker引擎中构建的;
在这种c/s服务架构中,用上下文context来让服务端获得本地文件,
构建的时候,用户指定构建镜像上下文的路径,docker build命令得知这个路径后,会将路径下的所有内容打包,然后上传到docker引擎,服务端的docker引擎收到上下文包后,打开就会得到构建镜像所需的一切文件,一把来说,应该将Dockerfile置于一个空目录下,或者项目根目录下,如果该目录下没有所需文件,那么应该把所需文件复制一份过来,可以用.dockerignore文件来提出不需要作为上下文传递给Docker引擎的;