前言

上篇说到我们可以基于 exec 进入容器内部并更改部分配置,然后通过 commit 打包成一个新的镜像发布到我们自己的 docker 仓库。这种情况只适用于针对此容器做一些简单的修改,如果我们要修改的内容过于复杂,比如在镜像运行前后增加一些指令等情况,就需要用 Dockerfile 来实现。

定义

Dockerfile 是用来构建Docker镜像的文本文件,是由一条条构建镜像所需的指令和参数构成的脚本。实际上我们从dockerhub 拉取下来的各个镜像,都是由 Dockerfile 编写并打包成一个个镜像供我们下载。

docker build指定dockerfile和文件的路径 dockerfile的workdir_jar

Dockerfile保留字指令

实际上Dockerfile 就是由一条条保留字指令构成,所以我们详细来说下各个保留字指令。

保留字

作用

FROM

当前镜像是基于哪个镜像的第一个指令必须是FROM

MAINTAINER

镜像维护者的姓名和邮箱地址

RUN

构建镜像时需要运行的指令

EXPOSE

当前容器对外暴露出的端口号

WORKDIR

指定在创建容器后,终端默认登录进来的工作目录,一个落脚点

ENV

用来在构建镜像过程中设置环境变量

ADD

将宿主机目录下的文件拷贝进镜像且ADD命令会自动处理URL和解压tar包

COPY

类似于ADD,拷贝文件和目录到镜像中
将从构建上下文目录中<原路径>的文件/目录复制到新的一层的镜像内的<目标路径>位置

VOLUME

容器数据卷,用于数据保存和持久化工作

CMD

指定一个容器启动时要运行的命令
Dockerfile中可以有多个CMD指令,但只有最后一个生效,CMD会被docker run之后的参数替换

ENTRYPOINT

指定一个容器启动时要运行的命令
ENTRYPOINT的目的和CMD一样,都是在指定容器启动程序及其参数

FROM

  • 基于哪个镜像进行构建新的镜像,在构建时会自动从docker hub拉取base镜像 必须作为Dockerfile的第一个指令出现
  • 语法:
FROM  <image>
FROM  <image>[:<tag>]     使用版本不写为latest
FROM  <image>[@<digest>]  使用摘要

MAINTAINER

  • 镜像维护者的姓名和邮箱地址[废弃]
  • 语法:
MAINTAINER <name>

RUN

  • 在容器构建的时候就会执行run 后面的命令。
  • 语法:
# 1. RUN <命令行命令> 等同于直接在终端写入的shell命令
RUN java -jar app.jar
# 2. RUN ["可执行文件", "参数1", "参数2", "参数..."]
RUN ["java", "-jar", "app.jar"]

EXPOSE

  • 用来指定构建的镜像在运行为容器时对外暴露的端口
  • 语法:
EXPOSE 80/tcp  如果没有显示指定则默认暴露都是tcp
EXPOSE 80/udp

CMD

  • 用来为启动的容器指定执行的命令,在Dockerfile中只能有一条CMD指令。如果列出多个命令,则只有最后一个命令才会生效。
  • 注意:Dockerfile中只能有一条CMD指令。如果列出多个命令,则只有最后一个命令才会生效。
  • 语法:
CMD ["executable","param1","param2"] (exec form, this is the preferred form)
CMD ["param1","param2"] (as default parameters to ENTRYPOINT)
CMD command param1 param2 (shell form)

WORKDIR

  • 用来为Dockerfile中的任何RUN、CMD、ENTRYPOINT、COPY和ADD指令设置工作目录。如果WORKDIR不存在,即使它没有在任何后续Dockerfile指令中使用,它也将被创建。
  • 语法:
WORKDIR /path/to/workdir
WORKDIR /a
WORKDIR b
WORKDIR c
`注意:WORKDIR指令可以在Dockerfile中多次使用。如果提供了相对路径,则该路径将与先前WORKDIR指令的路径相对`

ENV

  • 用来为构建镜像设置环境变量。这个值将出现在构建阶段中所有后续指令的环境中。
  • 语法:
ENV <key> <value>
ENV <key>=<value> ...
# 例如:
ENV MY_PATH  /usr/local
WORKDIR $MY_PATH

ADD

  • 将宿主机目录下的文件拷贝进镜像且会自动处理URL和解压tar压缩包,也可以从远程文件url进行复制。
  • 语法:
ADD hom* /mydir/       通配符添加多个文件
ADD hom?.txt /mydir/   通配符添加
ADD test.txt relativeDir/  可以指定相对路径
ADD test.txt /absoluteDir/ 也可以指定绝对路径
ADD url

COPY

  • 类似ADD,拷贝文件和目录到镜像中。但不会自动解压。
  • 语法:
COPY src dest
COPY ["<src>",... "<dest>"]
# src:源文件或源目录
# dest: 容器内的路径,不需要提前创建

VOLUME

  • 用来定义容器运行时可以挂在到宿主机的目录
  • 语法:
VOLUME ["/data"]

ENTRYPOINT

  • 用来指定容器启动时执行的命令和CMD类似
  • 语法:
ENTRYPOINT ["executable", "param1", "param2"]
  • ENTRYPOINT后面可以跟CMD指令,此时 CMD不再作为容器启动时的执行命令,而是将 CMD作为参数传递到 ENTRYPOINT 治理中。 例如:
FROM java:8
ENTRYPOINT ["java","-jar"]
CMD ["app.jar"]
# 等同于在终端中写:java -jar app.jar

Dockerfile构建springboot项目部署

1、准备springboot可运行项目,并且最终通过maven打成jar包。

docker build指定dockerfile和文件的路径 dockerfile的workdir_运维_02

2、将可运行项目放入linux虚拟机或服务器中

docker build指定dockerfile和文件的路径 dockerfile的workdir_Dockerfile_03

3、编写Dockerfile

跟jar包同目录下,新建 Dockerfile 文件

# 基础镜像使用java8
FROM openjdk:8
# 创建并设置容器的工作目录
WORKDIR /ems
# 将jar包添加到容器中
ADD ems_pink-0.0.1-SHAPSHOT.jar /ems
# 暴露端口
EXPOSE 8989
# 运行 jar包
ENTRYPOINT ["java","-jar"]
CMD ["ems_pink-0.0.1-SHAPSHOT.jar"]

4、构建镜像

# 后面不要漏了 .
[root@localhost ems]# docker build -t ems .

5、运行镜像

[root@localhost ems]# docker run -p 8989:8989 ems