前言
上篇说到我们可以基于 exec
进入容器内部并更改部分配置,然后通过 commit
打包成一个新的镜像发布到我们自己的 docker 仓库。这种情况只适用于针对此容器做一些简单的修改,如果我们要修改的内容过于复杂,比如在镜像运行前后增加一些指令等情况,就需要用 Dockerfile
来实现。
定义
Dockerfile 是用来构建Docker镜像的文本文件,是由一条条构建镜像所需的指令和参数构成的脚本。实际上我们从dockerhub 拉取下来的各个镜像,都是由 Dockerfile 编写并打包成一个个镜像供我们下载。
Dockerfile保留字指令
实际上Dockerfile 就是由一条条保留字指令构成,所以我们详细来说下各个保留字指令。
保留字 | 作用 |
FROM | 当前镜像是基于哪个镜像的 |
MAINTAINER | 镜像维护者的姓名和邮箱地址 |
RUN | 构建镜像时需要运行的指令 |
EXPOSE | 当前容器对外暴露出的端口号 |
WORKDIR | 指定在创建容器后,终端默认登录进来的工作目录,一个落脚点 |
ENV | 用来在构建镜像过程中设置环境变量 |
ADD | 将宿主机目录下的文件拷贝进镜像且ADD命令会自动处理URL和解压tar包 |
COPY | 类似于ADD,拷贝文件和目录到镜像中 |
VOLUME | 容器数据卷,用于数据保存和持久化工作 |
CMD | 指定一个容器启动时要运行的命令 |
ENTRYPOINT | 指定一个容器启动时要运行的命令 |
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包。
2、将可运行项目放入linux虚拟机或服务器中
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