美文网首页
Dockerfile 指令 功能 三 (CMD)

Dockerfile 指令 功能 三 (CMD)

作者: 懒猫睡醒了 | 来源:发表于2021-08-03 10:09 被阅读0次

    CMD 指令的格式和 RUN 相似,也是两种格式:

    • shell 格式:CMD <命令>
    • exec 格式:CMD ["可执行文件", "参数1", "参数2"...]
    • 参数列表格式:CMD ["参数1", "参数2"...]。在指定了 ENTRYPOINT 指令后,用 CMD 指定具体的参数。

    容器是一个进程。那么在启动容器的时候,就需要指定所运行的程序及参数。
    CMD 指令是用于指定默认的容器主进程的启动命令的,CMD 类属于 RUN 命令,CMD 指令也可以用于运行任何命令或应用程序。

    在运行时可以指定新的命令来替代镜像设置中的这个默认命令,比如,ubuntu 镜像默认的 CMD 是 /bin/bash,如果我们直接 docker run -it ubuntu 的话,会直接进入 bash。我们也可以在运行时指定运行别的命令,如 docker run -it ubuntu cat /etc/os-release。这就是用 cat /etc/os-release 命令替换了默认的 /bin/bash 命令了,输出了系统版本信息。

    在指令格式上,一般推荐使用 exec 格式,这类格式在解析时会被解析为 JSON 数组,因此一定要使用双引号 ",而不要使用单引号。

    如果使用 shell 格式的话,实际的命令会被包装为 sh -c 的参数的形式进行执行。比如:

    CMD echo $HOME

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

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

    这就是为什么我们可以使用环境变量的原因,因为这些环境变量会被 shell 进行解析处理。

    提到 CMD 就不得不提容器中应用在前台执行和后台执行的问题。这是初学者常出现的一个混淆。
    Docker 不像虚拟机,在容器中的应用都应该以前台执行,不像虚拟机那样,用 systemd 去启动后台服务,容器内没有后台服务饿概念。

    如果 CMD 指令写成:

    CMD service nginx start

    然后发现容器执行后就立即退出了。甚至在容器内发现无法执行 systemctl 的指令。

    对于容器而言,启动程序就是容器应用进程,容器就是为了主进程而存在的,主进程退出,容器就失去了存在的意义。

    而使用 service nginx start 命令,则是希望 upstart 来以后台守护进程启动 nginx 服务。
    而刚才说了 CMD service nginx start 会被理解为 CMD [ "sh", "-c", "service nginx start"],因此主进程实际上是 sh。那么当 service nginx start 命令结束后,sh 也就结束了,sh 作为主进程退出了,自然就会令容器退出。
    正确的做法是直接执行 nginx 可执行文件,并且要求以前台形式运行。比如:

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

    该CMD 指令只能运行一个,如果存在多个,直留存一个,最后一条 CMD 是生效的。

    编写Dockerfile 文件

    [root@ip-10-1-0-142 mynginx]# cat Dockerfile
    FROM nginx:latest
    COPY hello.txt home/
    COPY html/index.html /usr/share/nginx/
    CMD ["nginx","-g","daemon off;"]

    构建镜像的步骤

    [root@ip-10-1-0-142 mynginx]# docker build -f Dockerfile -t nginx:v2 app
    Sending build context to Docker daemon 3.631kB
    Step 1/4 : FROM nginx:latest
    ---> 08b152afcfae
    Step 2/4 : COPY hello.txt home/
    ---> f471772839c9
    Step 3/4 : COPY html/index.html /usr/share/nginx/
    ---> c6c9239fc8a9
    Step 4/4 : CMD ["nginx","-g","daemon off;"]
    ---> Running in ef82c58b610d
    Removing intermediate container ef82c58b610d
    ---> 808dddfc65d6
    Successfully built 808dddfc65d6
    Successfully tagged nginx:v2

    相关文章

      网友评论

          本文标题:Dockerfile 指令 功能 三 (CMD)

          本文链接:https://www.haomeiwen.com/subject/ezdjvltx.html