Docker:Dockerfile 中 RUN, CMD, ENTRYPOINT 的区别

 ================Dockerfile 中 RUN, CMD, ENTRYPOINT 的区别==============

原文:https://www.cnblogs.com/klvchen/p/9238410.html

RUN 指令:用于指定 docker build 过程中要运行的命令。
    语法格式:
     RUN <command> 或
     RUN ["<executeable>","<param1>","param2",...]
     RUN ["/bin/bash","-c","<executeable>","param1","param2",...]
            
    例如:
        RUN yum install iproute nginx && yum clean all

CMD 指令:类似于 RUN 指令,用于运行程序,但二者运行的时间点不同;CMD 在docker run 时运行,而非docker build;
CMD 指令的首要目的在于为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束;注意: CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。
    语法格式:
    CMD <command> 或
    CMD ["<executeable>","<param1>","<param2>",...] 
    CMD ["<param1>","<param2>",...] 该写法是为 ENTRYPOINT 指令指定的程序提供默认参数;
注意:如果 dockerfile 中如果存在多个CMD指令,仅最后一个生效;
        
    例如:     
            CMD ["/usr/sbin/httpd","-c","/etc/httpd/conf/httpd.conf"]

ENTRYPOINT 指令:类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序;但是, 如果运行 docker run 时使用了 --entrypoint 选项,此选项的参数可当作要运行的程序覆盖 ENTRYPOINT 指令指定的程序;
    语法格式:
    ENTRYPOINT <command> 或
    ENTRYPOINT ["<executeable>","<param1>","<param2>",...]
            
    例如:
        CMD ["-c"]
        ENTRYPOINT ["top","-b"]

ENTRYPOINT 与 CMD 区别

如:
FROM ubuntu:14.10  
ENTRYPOINT ["top", "-b"]   
CMD ["-c"]  
    
把可能需要变动的参数写到 CMD 里面。然后你可以在 docker run 里指定参数,这样 CMD 里的参数(这里是-c) 就会被覆盖掉而 ENTRYPOINT 里的不被覆盖。

注意:
ENTRYPOINT有两种写法,第二种(shell form)会屏蔽掉 docker run 时后面加的命令和 CMD 里的参数。

 ================Dockerfile中ENTRYPOINT 和 CMD的区别============== 

原文:https://blog.csdn.net/allocator/article/details/70490218

CMD 指令

CMD 指令指定容器启动时需要运行的程序。一般用最简单的方式启动一个容器时使用docker run 会传递参数给docker指令

docker run -it image /bin/bash

后面的/bin/bash 其实是传递参数,告知容器启动时运行一个shell。这个过程可以用CMD 指令等效的替换

CMD ['/bin/bash']

因此在Dockerfile中存在这个CMD指令指定的命令时,启动容器就可以不进行参数传递。

docker run -it image

执行效果一致。

[root@MiWiFi-R3L-srv test]# docker run --name test -it test_image
[root@3a1bb0c9e35c /]#

如果dockerfile中已经指定了容器启动时运行的程序,同时在使用docker run 启动容器时使用了命令行参数,那么dockerfile 中的cmd 指令将无效

docker run -it image /bin/ps

发现启动容器后没有shell ,只是打印出了当前容器中的进程状态,cmd 指令效果被覆盖。

  PID TTY          TIME CMD
    1 ?        00:00:00 ps
[root@MiWiFi-R3L-srv test]#

此时可以看到cmd 效果被覆盖。在一个dockerfile中只有最后一个cmd 指令有效,因此一个dockerfile中只写一个cmd 指令。
ENTRYPOINT 指令

ENTRYPOINT 指令效果与CMD 非常的类似,比较容易混淆两者的功能。最大的区别在于使用的方式,ENTRYPOINT 指定的命令需要与docker run 启动容器进行搭配,将docker run 指令后面跟的内容当做参数作为ENTRYPOINT指令指定的运行命令的参数,ENTRYPOINT 指定的linux命令一般是不会被覆盖的。以nginx 镜像为例说明
首先构建一个nginx镜像,并且指定容器运行时执行的程序为nginx。

FROM centos
MAINTAINER allocator
RUN yum install -y nginx
RUN echo 'hello world' > /usr/share/nginx/html/index.html
EXPOSE 80
ENTRYPOINT ["/usr/sbin/nginx"]

然后启动镜像

docker run --name test -p 5000:80 -it test_nginx -g "daemon off"

后面两个是作为参数传递给nginx启动程序运行,此时nginx作为前台程序运行,是一个web服务器,可以根据外部绑定的端口,通过浏览器正常看到hello world
两者联合使用技巧

已经明白了两者的区别,可以利用两者的特点构建一个含有默认启动运行程序的镜像,并且支持docker run 启动时人为指定启动程序运行的参数。
举个例子。利用ENTRYPOINT 指定启动时运行启动nginx程序,并给定默认的运行参数为显示帮助信息,dockerfile 构建如下:

ENTRYPOINT ["/usr/sbin/nginx"]
CMD ["-h"]

当使用docker run --name test -it test_nginx 不传递任何参数时,此时启动容器会使用cmd 指令后的命令作为默认参数,打印nginx的帮助信息。此时cmd 后的内容并不是一个完整的指令,而是参数,如果其内容是一个完整的指令,那么它将覆盖掉ENTRYPOINT 中的内容。

如果使用docker run --name test -it test_nginx -g "daemon off" 启动时,此时给定的运行参数会覆盖掉CMD 指令对应的内容,此时nginx将作为前台进程运行,作为一个web服务器使用,通过browser可以看到hello world
 

参考文档

Docker Dockerfile 定制镜像

docker之Dockerfile实践

猜你喜欢

转载自blog.csdn.net/netyeaxi/article/details/89091026