# 使用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
,其后的命令都将会将此目录当作当前路径。