一、Dockerfile简介
1、Dockerfile介绍
Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
2、Dockerfile基础知识
- 每条保留字指令必须为大写字母,后面要跟随至少一个参数
- 指令按照从上到下,顺序执行
- #表示注释
- 每条指令都会创建一个新的镜像层,并对镜像进行提交
二、Dockerfile常用命令
1、CMD指令
作用:用来定义容器运行时的默认命令,可以在使用docker run的时候覆盖掉CMD中定义的命令
用法:CMD ["命令1", "参数1", "参数2"]
示例:
- CMD echo "Hello World"
- CMD ["/usr/bin/wc","--help"]
注意:
- 一个Dockerfile只有顺序向下的最后一个CMD生效
- CMD运行结束后容器将终止,CMD可以被docker run后面的命令覆盖
2、FROM指令
作用:用来定义基础镜像
用法:FROM 镜像名:标签名
示例:FROM centos:7
注意:
- 标签是可选的,如果不使用这两个值时,会使用latest版本的基础镜像
- FROM命令是Dockerfile文件开篇第一个非注释行代码
案例1:结合CMD和FROM命令构建镜像
编写dockerfile文件,文件名为file1,内容如下:
通过docker build命令构建镜像:docker build -t redis:1.0 -f file1 .
查看构建出来的镜像: docker images
启动镜像: docker run redis:1.0
案例2:测试多个CMD命令是否覆盖
编写dockerfile文件,文件名为file2,内容如下:
通过docker build命令构建镜像:docker build -t redis:2.0 -f file2 .
查看构建出来的镜像: docker images
启动镜像: docker run redis:2.0
3、ENV指令
作用:设置环境变量
用法:ENV key=value
示例:
- ENV JAVA_HOME=/usr/local/jdk1.8.0_333
- ENV PATH=$JAVA_HOME/bin:$PATH
注意:可以通过该指令一次设置多个环境变量,例如:ENV key=value key=value ......
4、WORKDIR指令
作用:设置当前的工作目录,类似于cd命令的作用。如果目录不存在,就会自动创建目录;如果目录的父目录不存在,同样也会自动创建目录。
用法:WORKDIR 目录
示例:WORKDIR /root/data
注意:
- 通过 WORKDIR 命令设置工作目录后,Dockerfile 中其后的命令 RUN、CMD、ENTRYPOINT、ADD、COPY等命令都会在该目录下执行。
- 在使用 docker run 运行容器时,可以通过 -w 参数覆盖构建时所设置的工作目录。
- 一个Dockerfile中WORKDIR可以出现多次如下:
- WORKDIR /a (这时工作目录为/a)
- WORKDIR b (这时工作目录为/a/b)
- WORKDIR c (这时工作目录为/a/b/c)
案例3:在centos镜像中创建目录/a/b/c,并查看当前的路径
编写dockerfile,内容如下:
构建镜像:docker build -t centos:1.0 -f workdir_file .
启动容器:docker run centos:1.0
5、RUN指令
作用:构建镜像时执行的命令。
用法:RUN指令的执行有两种方式:
- 格式1:shell 形式
- RUN 命令1 && 命令2
- 格式2:exec 形式
- RUN [“可执行文件”,“参数1”,“参数2”]
示例:
- RUN echo 1 && echo 2
- RUN ["/bin/bash","-c","echo hello world"]
RUN和CMD的区别:
CMD 用于指定在容器启动时所要执行的命令,而 RUN 用于指定镜像构建时所要执行的命令
案例4:定义一个CONTENT变量,内容为:Hello CentOS,并在镜像的/app目录下创建一个fileDir目录,并在其中创建一个text.txt文件,将CONTENT变量的值输入到该文件中,在容器启动时打印test.txt中的内容
编写dockerfile文件,内容如下:
构建镜像:docker build -t centos:2.0 -f run_file .
启动容器:docker run centos:2.0
进入容器内,查看目录以及text.txt的内容:
- docker run -it centos:2.0 bash
- cd /app/fileDir/
- cat text.txt
6、ADD指令
作用:将本地文件添加到容器中,tar 类型的文件会自动解压(网络压缩资源不会被解压),可以访问网络资源,类似于 wget。
用法:ADD 宿主机文件位置 容器中文件位置
示例:
- ADD /opt/apache-tomcat-8.5.27.tar.gz /opt
- ADD hom* /mydir/ # 添加所有以"hom"开头的文件
- ADD hom?.txt /mydir/ # ? 替代一个单字符,例如:"home.txt"
- ADD test relativeDir/ # 添加 "test" 到 `WORKDIR`/relativeDir/
- ADD test /absoluteDir/ # 添加 "test" 到 /absoluteDir/
7、EXPOSE指令
作用:指定于外界交互的端口。
用法:EXPOSE 端口号
示例:EXPOSE 8080
注意:EXPOSE 并不会让容器的端口访问到主机。要使其可访问,需要在 docker run 运行容器时通过 -p 参数来发布这些端口。
8、COPY指令
作用:功能类似ADD,但是是不会自动解压文件,也不能访问网络资源。
用法:COPY 宿主机路径 容器内路径
示例:COPY /opt/apache-tomcat-8.5.27.tar.gz /opt
9、ENTRYPOINT指令
作用:配置容器,使其可执行化。指定容器启动时要运行的命令,可以追加命令。
用法:
- ENTRYPOINT [“可执行文件”,“参数1”,“参数2”]
- ENTRYPOINT 命令 参数1 参数2(shell内部命令)
示例:ENTRYPOINT ["top", "-b"]
注意:
- 通过 docker run 执行的命令不会覆盖 ENTRYPOINT,而 docker run 命令中指定的任何参数,都会被当做参数再次传递给 ENTRYPOINT 。
- Dockerfile 中可以有多个ENTRYPOINT,但只有最后一个生效。
- docker run命令的 --entrypoint选项可以覆盖ENTRYPOINT指令指定的程序
- ENTRYPOINT主要用于启动父进程,后面跟的参数被当做子进程来启动
10、MAINTAINER指令
作用:指定维护者信息
用法:MAINTAINER 维护者信息
示例:
- MAINTAINER tom
- MAINTAINER tom<tom@qq.com>
注意:维护者信息可为名字,也可为邮箱,也可为名字加邮箱
11、LABEL指令
作用:用于为镜像添加元数据
用法:LABEL <key>=<value> <key>=<value> <key>=<value> ...
示例:LABEL version="1.0" description="这是一个Tomcat服务器"
12、USER指令
作用:指定运行容器时的用户名或 UID,后续的 RUN 也会使用指定用户。使用USER指定用户时,可以使用用户名、UID或GID,或是两者的组合。当服务不需要管理员权限时,可以通过该命令指定运行用户。并且可以在之前创建所需要的用户
用法:
- USER user
- USER user:group
- USER uid
- USER uid:gid
- USER user:gid
- USER uid:group
示例:USER tom
13、ONBUILD指令
作用:帮助其他容器生成,即指令后的命令不在此次镜像构建中运行,会在其他继承此镜像的镜像中运行
用法:ONBUILD 其他指令
示例:ONBUILD RUN mkdir mydir
注意:该指令,对于使用该Dockerfile构建的镜像并不会生效,只有当其他Dockerfile以当前镜像作为基础镜像时被触发。例如:Dockfile A 构建了镜像A,Dockfile B中设置FROM A,此时构建镜像B是会运行ONBUILD设置的指令
三、Dockerfile实战
(1)描述
准备jdk和tomcat的安装包,并在/usr/local目录下创建java目录存放JDK、创建tomcat目录存放Tomcat,然后在centos中配置Java环境,并对外暴露8080端口
(2)实现
编写Dockerfile文件,内容如下:
# 指明构建的新镜像是来自于 centos:7 基础镜像
FROM centos:7
# 通过镜像标签声明了作者信息
LABEL maintainer="123tom.com"
# 设置工作目录
WORKDIR /usr/local
# 新镜像构建成功以后创建指定目录
RUN mkdir -p /usr/local/java && mkdir -p /usr/local/tomcat
# 拷贝文件到镜像中并解压
ADD jdk-8u161-linux-x64.tar.gz /usr/local/java
ADD apache-tomcat-8.5.78.tar.gz /usr/local/tomcat
# 暴露容器运行时的 8080 监听端口给外部
EXPOSE 8080
# 设置容器内 JAVA_HOME 环境变量
ENV JAVA_HOME /usr/local/java/jdk1.8.0_161/
ENV PATH $PATH:$JAVA_HOME/bin
# 启动容器时启动 tomcat
CMD ["/usr/local/tomcat/apache-tomcat-8.5.78/bin/catalina.sh", "run"]
构建镜像:docker build -t centos:4.0 -f learn_file_1 .
启动容器:docker run -d -p 8080:8080 --name=tomcat centos:4.0
验证是否成功:
方式一:通过curl访问
方式二:浏览器地址栏访问Tomcat