我是目录😊
1 Dockerfile介绍
Dockerfile 就是我们用来构建Docker镜像的一些命令的集 合,一个Dockerfile里面包含了构建整个镜像(image
)的完整命令。Docker通过docker build
执行Dockerfile
中的一系列命令自动构建image。
简单来说,Dockerfile 就是可以让我们个性化定制Docker镜像,来满足实际工作中各式各样的需求。
2 Dockerfile文件说明
Dockerfile 由一行行命令语句组成, 以#
开头的注释行 Dockerfile分为四部分:基础镜像信息、维护者信息、 镜像操作指令和容器启动时执行指令。
2.1 定义运行jar包的镜像
Dockerfile
定义一个运行jar包的镜像
# 指定基础镜像
FROM openjdk:8-alpine3.9
# `RUN` 构建镜像时执行的命令,这里创建一个目录
RUN mkdir -p /docker-demo
# WORKDIR 工作目录,类似于cd命令
WORKDIR /docker-demo
# 用于指定传递给构建运行时的变量
ARG JAR_FILE=target/docker-demo.jar
# 把传过来的jar名称,重命名为app.jar
COPY ${JAR_FILE} app.jar
# 向外界暴露8080端口
EXPOSE 8080
# 设置两个环境变量,TZ=Asia/Shangha 修改时区。JAVA_OPTS="..." java运行时JVM参数
ENV TZ=Asia/Shanghai JAVA_OPTS="-Xms128m -Xmx256m -Djava.security.egd=file:/dev/./urandom"
#容器启动命令,在容器启动时才进行调用
CMD java -jar app.jar $JAVA_OPTS
构建镜像
把上面创建的Dockerfile
上传到服务器,使用docker build
构建
到Dockerfile
所在目录执行
docker build --rm -t dockerdemo:v1 --build-arg JAR_FILE=dockerdemo.jar .
--build-arg
设置镜像创建时的变量,也就是JAR_FILE
# 查看镜像
docker image ls
关于docker build命名请看下面👇的内容
2.2 Dockerfile常见命令
-
FROM
指定基础镜像,第一条指令必须是FROM。除了选择现有镜像为基础镜像外,Docker 还存在一个特殊的镜像,名为scratch
。这个镜像是虚拟的概念,并不实际存在,它表示一个空白的镜像。 -
MAINTAINER
定义作者的一些信息。 -
RUN
构建镜像时执行的命令,比如执行echo
命名。RUN echo '<h1>Hello, world!</h1>' > index.html
-
ENV
设置环境变,命名格式有如下两种:ENV <key> <value> ENV <key1>=<value1> <key2>=<value2>...
-
CMD
容器启动命令,在容器启动时才进行调用。命令格式有如下两种:# shell 格式 CMD <命令> # 例如运行jar,CMD sleep 30; java -jar app.jar # exec 格式 CMD ["可执行文件", "参数1", "参数2"...]
-
ENTRYPOINT
指定运行容器启动过程执行命令,覆盖CMD参数 ENTRYPOINT与CMD非常类似,不同的是通过docker run执行的命令不会覆盖 ENTRYPOINT,而docker run命令中指定的任何参数,都会被当做参数再次传递 给ENTRYPOINT。Dockerfile中只允许有一个ENTRYPOINT命令,多指定时会覆 盖前面的设置,而只执行最后的ENTRYPOINT指令。例如运行jar包:ENTRYPOINT ["java","-jar","/app.jar"]
详细介绍可以参考:https://yeasy.gitbook.io/docker_practice/image/dockerfile/entrypoint
-
ADD
将本地文件添加到容器中,tar类型文件会自动解压。 -
COPY
复制文件,功能类似ADD
,但是是不会自动解压文件。 -
WORKDIR
使用WORKDIR
指令可以来指定工作目录(或者称为当前目录),以后各层的当前目录就被改为指定的目录,如该目录不存在,WORKDIR
会帮你建立目录。 -
ARG
用于指定传递给构建运行时的变量。构建参数和ENV
的效果一样,都是设置环境变量。所不同的是,ARG
所设置的构建环境的环境变量,在将来容器运行时是不会存在这些环境变量的 -
VOLUMN
定义匿名卷,容器运行时应该尽量保持容器存储层不发生写操作,对于数据库类需要保存动态数据的应用,其数据库文件应该保存于卷(volume)中。其命名格式有如下两种方式:VOLUME ["<路径1>", "<路径2>"...] VOLUME <路径>
-
EXPOSE
指定于外界交互的端口 -
USER
指令和WORKDIR
相似,都是改变环境状态并影响以后的层。WORKDIR
是改变工作目录,USER
则是改变之后层的执行RUN
,CMD
以及ENTRYPOINT
这类命令的身份。注意,
USER
只是帮助你切换到指定用户而已,这个用户必须是事先建立好的,否则无法切换。
3 docker build 命令
docker build
命令用于使用 Dockerfile 创建镜像。
语法
docker build [OPTIONS] PATH | URL | -
常用OPTIONS说明:
- **–build-arg=[] 😗*设置镜像创建时的变量;
- **-f 😗*指定要使用的Dockerfile路径,如果在Dockerfile当前目录执行
docker build
,可以省略-f参数,使用.
(点) 代替; - **–rm 😗*设置镜像过程中删除中间容器;
- **-m 😗*设置内存最大值;
- **–quiet, -q 😗*安静模式,成功后只输出镜像 ID;
- –tag, -t: 镜像的名字及标签,通常 name:tag 或者 name 格式;可以在一次构建中为一个镜像设置多个标签。
上面我们在执行Dockerfile
定义一个运行jar包的镜像,已经使用过一次
docker build --rm -t dockerdemo:v1 --build-arg JAR_FILE=dockerdemo.jar .
4 小栗子🌰
4.1 自定义Mysql镜像
自定义Mysql镜像,修改时区,并自动执行初始化脚本。
FROM mysql:5.7.36
MAINTAINER warybee warybee@gmail.com
# 修改mysql时区
ENV TZ=Asia/Shanghai
RUN ln -sf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 自动执行初始化sql脚本。
COPY init.sql /docker-entrypoint-initdb.d
4.2 定义运行jar包的镜像
# 指定基础镜像
FROM openjdk:8-alpine3.9
# `RUN` 构建镜像时执行的命令,这里创建一个目录
RUN mkdir -p /docker-demo
# WORKDIR 工作目录,类似于cd命令
WORKDIR /docker-demo
# 用于指定传递给构建运行时的变量
ARG JAR_FILE=target/docker-demo.jar
# 把传过来的jar名称,重命名为app.jar
COPY ${JAR_FILE} app.jar
# 向外界暴露8080端口
EXPOSE 8080
# 设置两个环境变量,TZ=Asia/Shangha 修改时区。JAVA_OPTS="..." java运行时JVM参数
ENV TZ=Asia/Shanghai JAVA_OPTS="-Xms128m -Xmx256m -Djava.security.egd=file:/dev/./urandom"
#容器启动命令,在容器启动时才进行调用
CMD java -jar app.jar $JAVA_OPTS
https://docs.docker.com/engine/reference/builder/