docker专题

dockerfile命令详解

2020-02-17  本文已影响0人  深圳邱道长

from

定义基础镜像,比如你写官方定义的centos ubuntu等等,或者你用其它人的都OK,有基础镜像就是尽力减少基础环境的劳动。

eg

FROM ubuntu
image.png

我们看到命令都是大写的,约定俗成,遵守即可。

copy

复制 ,https://docs.docker.com/engine/reference/builder/#copy

最简单的

COPY src dst

src 是你宿主机路径,dst是这个容器里面的路径。

image.png

当然你可以写多个src,复制多个文件到容器。

image.png

ADD

和copy差不多,就是更强一点,比如,ADD一个tar.gz文件,不仅它会复制上去,它还会解压了。

FROM alpine
ADD jdk-13.0.2_linux-x64_bin.tar.gz /usr/local
ENV love nini
ENV me=qdc
image.png

不仅解压了,压缩的文件也干掉了,太方便了。

LABEL

定义一些镜像的元数据, 比如维护者是是谁。

ENV

定义环境变量

比如

FROM alpine
ENV love nini
ENV me=qdc

这两种都可以的。

image.png

比如将来我们转个JDK,maven,按需解压后,就可以了。

FROM ubuntu
ADD jdk-13.0.2_linux-x64_bin.tar.gz /usr/local
ENV JAVA_HOME /usr/local/jdk-13.0.2
ENV PATH=$PATH:$JAVA_HOME/bin
image.png

现在装个JDK是不是so easy。

CMD

CMD指令指定在启动容器时要运行的命令。它类似于RUN指令,但不是在构建容器时运行命令,而是在启动容器时指定要运行的命令,这与使用docker RUN命令启动容器时指定要运行的命令很相似,例如:

docker run -it  xx/yy /bin/bash

等效于

CMD ["/bin/bash"]

你还可以给命令传递参数

CMD ["/bin/bash",'-l']

注意到该命令包含在一个数组中。这告诉Docker以“原样”运行命令。还可以在不使用数组的情况下指定CMD指令,在这种情况下,Docker会在命令前加上/bin/sh -c。这可能会在执行命令时导致意外的行为。因此,建议始终使用数组语法。

最后,重要的是要理解我们可以使用docker run命令重写CMD指令。如果在Dockerfile和docker run命令行中分别指定一个CMD,那么命令行将覆盖Dockerfile的CMD指令。一会我们看ENTRYPOINT,它们也是有区别的。

我们看个案例

FROM alpine
CMD ["/bin/sh"]

如果运行命令里面没有传入其它命令则走 /bin/sh

docker build . 
docker run -it 1ca294e5b8d9

如果运行命令是

docker run -it 1ca294e5b8d9 ps
image.png

最后一点主意:
在Dockerfile中只能指定一条CMD指令。如果指定了多条指令,则将使用最后一条CMD指令。如果需要在启动容器时运行多个进程或命令,则应使用诸如Supervisor之类的服务管理工具。

ENTRYPOINT

ENTRYPOINT指令与CMD指令密切相关,常常与之混淆。那么两者有什么区别,为什么两者都需要呢?正如我们刚刚发现的,我们可以重写docker run命令行上的CMD指令。 有时候,当我们希望容器以某种方式运行时,这并不是很好。 ENTRYPOINT指令提供的命令不太容易被覆盖。 相反,我们在docker run命令行上指定的所有参数将作为参数传递给ENTRYPOINT中指定的命令。 我们来看一个ENTRYPOINT指令的示例。

FROM ubuntu:18.04
LABEL maintainer="singkingcho@gmail.com"
ADD sources.list /etc/apt/
RUN apt-get update ; apt-get install -y nginx
RUN echo "Hi,baby " > /var/www/html/index.html
ENTRYPOINT ["/usr/sbin/nginx"]
docker build -t="qiduaozhang/static_web" .
docker run -it -p 80:80  qiduaozhang/static_web -g "daemon off;"

我们重建了我们的镜像,然后启动了一个交互式容器。我们指定了参数-g “daemon off;”。此参数将传递给ENTRYPOINT指令中指定的命令,该命令将成为/usr/sbin/nginx -g "daemon off;"。这个命令将在前台启动Nginx守护进程,并让容器作为web服务器运行。为了让大家能看到,我们指定了端口映射方便外部访问得到。

image.png image.png

你可以使用等价写法。

FROM ubuntu:18.04
LABEL maintainer="singkingcho@gmail.com"
ADD sources.list /etc/apt/
RUN apt-get update ; apt-get install -y nginx
RUN echo "Hi,baby " > /var/www/html/index.html
ENTRYPOINT ["/usr/sbin/nginx","-g","daemon off;"]
docker build -t="qiudaozhang/static_web" .     
docker run -it -p 80:80  qiudaozhang/static_web

效果一样。

我们还可以结合ENTRYPOINT和CMD来做一些整洁的事情。例如,我们可能需要在Dockerfile中指定以下内容。

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

现在,当我们启动一个容器时,我们指定的任何选项都将传递给Nginx守护进程;例如,我们可以指定-g“daemon off”;就像我们在前面运行守护进程一样。如果我们没有指定要传递给容器的任何内容,那么-h将由CMD指令传递,并返回Nginx帮助文本/usr/sbin/Nginx -h。

FROM ubuntu:18.04
LABEL maintainer="singkingcho@gmail.com"
ADD sources.list /etc/apt/
RUN apt-get update ; apt-get install -y nginx
RUN echo "Hi,baby " > /var/www/html/index.html
ENTRYPOINT ["/usr/sbin/nginx"]
CMD ["-h"]

# 现在我们传递了参数
docker run -it -p 80:80  qiudaozhang/static_web -g "daemon off;"

依然以前端守护进程的方式跑动。
如果没传递参数,那么 CMD里面的 -h 传递给ENTRYPOINT,就成了nginx的求助命令了。

docker run -it -p 80:80  qiudaozhang/static_web    
image.png

这使我们可以构建默认命令,以在容器运行时结合docker run命令行上的可覆盖选项和标志来执行。

如果在运行时需要决定,则可以使用带有--entrypoint标志的docker run命令覆盖ENTRYPOINT指令。

WORKDIR

WORKDIR指令提供了一种方法,用于设置容器的工作目录以及从映像启动容器时要执行的ENTRYPOINT和/或CMD。

我们可以使用它来设置一系列指令或最终容器的工作目录。 例如,要为特定指令设置工作目录,我们可以:

WORKDIR /usr/local
RUN touch love.txt
WORKDIR /opt/
RUN mkdir baby
image.png
上一篇下一篇

猜你喜欢

热点阅读