# 使用Dockerfile
Dockerfile是一个文本文件,其中包含了一些描述镜像构建细节的命令。
运行命令
sudo docker run -d -p 91:80 nginx
先下载nginx镜像,然后如下演示一个最简单的使用Dockerfile的例子。使用如下Dockerfile可以修改镜像的首页。
FROM nginx
RUN echo '<h1>Hello Docker</h1>' > /usr/share/nginx/html/index.html
文件中的FROM/RUN都是Dockerfile的命令。
From用于指定基础镜像,RUN用于执行命令。
在Dockerfile所在路径下执行
sudo docker build -t nginx:my .
# Sending build context to Docker daemon 2.048kB
# Step 1/2 : FROM nginx
# ---> 448a08f1d2f9
# Step 2/2 : RUN echo '<h1>Hello Docker</h1>' > /usr/share/nginx/html/index.html
# ---> Running in 56cc7bd387df
# Removing intermediate container 56cc7bd387df
# ---> bbde20bd1613
# Successfully built bbde20bd1613
# Successfully tagged nginx:my
.表示的是路径传递参数,当前路径。
使用新build的镜像启动一个Docker,
sudo run -d 92:80 nginx:my
修改之前访问localhost:91页面

修改之后访问localhost:92页面

可以看到仅仅通过几行代码就改变了镜像的行为。
# Dockerfile中常用命令
Dockerfile 功能很强大,它提供了十多个指令。
# COPY复制文件
格式:
COPY [--chown=<user>:<group>] <源路径>... <目标路径>COPY [--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"]
有两种格式,一种类似于命令行,一种类似于函数调用。
COPY 指令将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的 <目标路径>中,如
COPY package.json /usr/src/app/
在使用该指令的时候还可以加上 --chown=<user>:<group> 选项来改变文件的所属用户及所属组。
COPY --chown=55:mygroup files* /mydir/
# ADD复制文件
格式:
ADD <src>...<dest>ADD ["<src>",...,"<dest>"]
ADD命令从src目录复制文件到容器的dst。其中,src可以是Dockerfile所在目录的相对路径,也可以是一个URL,还可以是压缩包。
如下命令使用ADD解压文件:
ADD xxxx.tar.gz /
# ARG设置构建参数
ARG指令用于设置构建参数,类似ENV。和ENV不同的是,ARG设置的是构建时的环境变量,在容器运行时是不会存在这些变量的。
格式
ARG <name>[=<default value>]
例如
ARG user1=xxx
# CMD启动容器的命令
Docker 不是虚拟机,容器就是进程,在启动容器的时候,需要指定所运行的程序及参数。CMD 指令就是用于指定默认的容器主进程的启动命令的。
每个Dockerfile只有一个CMD命令,如果指定多了CMD命令,只有最后一条会执行,如果启动容器时指定了容器的命令,则会覆盖CMD指定的命令。
格式
CMD ["executable", "param1", "param2"]CMD ["param1", "param2"]CMD command param1 param2
例如
CMD echo "This is a tes" | wc -
# ENTRYPOINT入口点
ENTRYPOINT 的目的和 CMD 一样,都是在指定容器启动程序及参数。当指定了 ENTRYPOINT 后,CMD 的含义就发生了改变,不再是直接的运行其命令,而是将 CMD 的内容作为参数传给 ENTRYPOINT 指令。
格式
ENTRYPOINT ["executable", "param1", "param2"]ENTRYPOINT command param1 param2
# ENV设置环境变量
ENV指令用于设置环境变量。
格式
ENV <key> <value>ENV <key>=<value>
例如
ENV JAVA_HOME /path/to/java
后面的其它指令和运行时的应用,都可以直接使用这里定义的环境变量。
# EXPOSE声明暴露的端口
格式
EXPOSE <端口1> [<端口2>...]
EXPOSE 指令用于声明容器运行时提供服务的端口,这只是一个声明,在容器运行时并不会因为这个声明应用就会开启这个端口的服务。
在 Dockerfile 中写入这样的声明有两个好处,一个是帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射;另一个用处则是在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。
和在运行时使用 -p <宿主端口>:<容器端口>的区分,-p是映射宿主端口和容器端口,换句话说,就是将容器的对应端口服务公开给外界访问,而 EXPOSE 仅仅是声明容器打算使用什么端口而已,并不会自动在宿主进行端口映射。
# VOLUME指定挂载点
格式
VOLUME <路径>
该命令使得容器中的一个目录具有持久化存储的功能,该目录可被容器本身使用,也可共享给其他容器。当容器中的应用有持久化数据的需要时可以在Dockerfile中使用该命令。
示例
VOLUME /data
# FROM指定基础镜像
FROM指令指定基础镜像,有点类似面向对象中的继承关系,FROM指令必须指定且需要写在其他指令之前,FROM指令后的其他指令都依赖该指令所指向的对象。
格式
FROM <image>FROM <image>:<tag>FROM <image>@<digest>
# LABEL为镜像添加元数据
LABEL命令用于为镜像添加元数据。
格式
LABEL <key>=<value> <key>=<value>...
使用"和\转换命令行。
示例
LABEL version="1.0"
LABEL description="This \
text is a test."
# RUN执行命令
格式
RUN <command>RUN ["executable", "param1", "param2"]
RUN <command>在shell终端中运行,在linux中默认是/bin/sh -c,使用这种格式就像是在终端中输入命令一样。
# WORKDIR指定工作目录
格式
WORKDIR /path/to/workdir
切换到workdir路径的命令,类似cd,其后的命令都将会将此目录当作当前路径。