Dockerfile语法、自定义镜像构建详解
Dockerfile的使用详解
Dockerfile语法、自定义镜像构建详解
简单的说Dockerfile就是一个文本文件。
Docker
使用它就可以帮助我们构建镜像。
大部分镜像都可以在DockerHub
上找到。
但是以后自己写的微服务,想要发布到Docker
上运行,就需要自己来构建镜像了。
一、镜像的结构
镜像是一个分层结构,每一层称为一个Layer
.
可以大致把这些层分为三部分:
1.1 基础镜像层(BaseImage)
应用依赖的函数库、环境变量、配置、文件系统等。
最底层的Layer
。
1.2 中间层(Layer)
在BaseImage
的基础上,添加安装包、依赖、配置等。
中间层并不是只单独的一层,而是基础镜像层和入口层之间的所有Layer
。
1.3 入口层(Entrypoint)
指镜像的运行入口,可以是程序的启动脚本。
是最顶层的Layer
。
1.4 镜像分层的好处
最直接的好处就是节省磁盘空间和共享资源。
比如有多个镜像都是从相同的BaseImage
构建来的。
那么Docker
只需要在磁盘上保持一份BaseImage
,并且内存也只需加载一份BaseImage
。
这样就实现了BaseImage
的复用。
1.5 注意点
Docker
镜像一旦制作完成,层级就不能够再去更改,这也是从安全性和可维护可拓展性考虑。
如果想要修改镜像,比如拓展镜像的功能,只能够在原来的层级上加一层,再统一打包成镜像。
如果不了解这个过程,自己制作镜像时,也可以从头开始打包。
1.6 镜像的概念
镜像就是在系统函数库、运行环境基础上,添加应用程序文件、配置文件、依赖文件等组合。
然后编写好启动脚本和上面的文件组合统统打包在一起形成的文件。
要自定义构建镜像,就是实现上述打包的过程。
二、Dockerfile及其相关命令
自己构建自定义的镜像时,并不需要把所有文件一个个拷贝,打包。
只要告诉Docke
r,镜像的组成,需要哪些BaseImage、需要拷贝什么文件、需要安装什么依赖、以及启动脚本。
Docker
会帮助我们构建镜像。
而描述上述信息的文件就是Dockerfile
文件,它相当于就是构建镜像的说明书。
因此,Dockerfile
就是一个文本文件,它提供了一种可以通过描述文件来构建镜像的一种方式。
用指令来说明Docker
要执行什么操作去构建镜像。
每一个指令都会形成一层Layer
。
2.1 Dockerfile常用命令
指令名称 | 说明 | 示例 |
---|---|---|
FROM | 指定基础镜像是什么 | FROM centos:7 |
ENV | 设置环境变量,可在后面指令使用 | ENV key value |
COPY | 拷贝本地文件到镜像的指定目录 | COPY <源路径> <目标路径> |
ADD | 将文件、目录或远程 URL 从源目录复制到镜像中的目标目录 | ADD <源路径> <目标路径> |
RUN | 执行Linux的shell命令,一般是当前应用安装过程的命令 | RUN yum install gcc |
EXPOSE | 指定容器运行时监听的端口 | EXPOSE 80 |
ENTRYPOINT | 镜像中应用的启动命令,容器运行时调用 | ENTRYPOINT java -jar xx.jar |
2)关于 ADD
和 COPY
:
ADD
和 COPY
都是用于将文件从主机复制到 Docker
镜像中的命令,但它们之间有一些区别。
ADD
命令的功能比 COPY
更强大。除了复制文件, ADD
命令还支持以下功能:
- 如果源路径是一个
URL
,它可以自动下载并将文件复制到镜像中。 - 如果源文件是一个归档文件(如
tar
文件),它会自动解压缩并将文件复制到镜像中。 - 如果目标路径不存在,
ADD
命令会自动创建目标路径。
而 COPY
命令相对简单,只能用于将本地文件或目录复制到镜像中,不支持自动解压缩和下载功能。
但是,由于 COPY
命令的行为更明确和可预测,所以在大多数情况下,建议使用 COPY
命令而不是 ADD
命令。
总结ADD
命令在功能上更丰富,而 COPY
命令更直观和可控。根据具体需求,选择适合的命令来复制文件到 Docker
镜像中。
2)关于EXPOSE
:
EXPOSE
监听的端口,一般也是在docker run
运行镜像生成容器时,需要把容器和宿主机相关联的端口。
如果上面的命令满足不了构建镜像的需要时。
可以查阅官方文档 :
https://docs.docker.com/engine/reference/builder/
文档里什么命令都有,但是有相当一部分是不常用的
三、使用Dockerfile一个JavaWeb程序构建为镜像
3.1 文件准备
- docker-demo.jar:需要制作成镜像的SpringBoot项目。
- Dockerfile:包含了镜像构建的全部步骤。
- jdk-8u171-linux-x64.tar.gz:jdk安装包。
先解压jdk-8u171-linux-x64.tar.gz,是因为我想知道解压出来的目录叫什么名字,在Dockerfile中有用。
3.2 编写Dockerfile文件
# 指定基础镜像
FROM ubuntu:16.04
# 配置环境变量,JDK的安装目录
ENV JAVA_DIR=/usr/local
# 拷贝jdk和java项目的包
COPY ./jdk-8u171-linux-x64.tar.gz $JAVA_DIR/ # 把jdk压缩包复制到/usr/local目录下
COPY ./docker-demo.jar /soft/app.jar # 把java程序移动到/soft目录下并重命令为app.jar
# 使用RUN命令执行Linux的shell命令
RUN cd $JAVA_DIR \ # 跳转到 到/usr/local目录下
&& tar -xf ./jdk-8u171-linux-x64.tar.gz \ # 解压缩jdk的安装包
&& mv ./jdk1.8.0_171 ./java8 # 把jdk解压出来的目录重命名为java8
# 其实重命名操作都是非必须的,只是用更短的名字更好操作一些
# 配置环境变量
ENV JAVA_HOME=$JAVA_DIR/java8 # 把jdk的安装目录配置成环境变量JAVA_HOME
ENV PATH=$PATH:$JAVA_HOME/bin # 最后再配置PATH变量为jdk的安装目录
# 暴露需要被监听端口,就是让被完全隔离的容器暴露出一个可以被外界访问的端口
# 一般就是application.yml中配置的端口号
EXPOSE 8999
# 程序运行入口,就是java项目的启动命令
# 这句话也是容器成功运行后,第一个执行的命令
ENTRYPOINT java -jar /soft/app.jar
3.3 构建镜像
运行构建镜像命令
# 写法一:默认文件名称必须叫Dockerfile
# -t 代表以' Name:tag'格式命名和可选的标记 (相当于就是-tag)
# . 代表构建镜像所需的文件都在Dockerfile文件所在的目录下
docker build -t javaapp:1.0 .
# 写法二:自己执行Dockerfile文件是谁
# -f 手动指定Dockerfile的文件名称
docker build -f mydockerfile -t javaapp:1.0
注意:
1)构建的镜像名称必须全部小写
2)没有特殊情况文件名称就用Dockerfile就行,容易记忆,更加直观,也符合习惯
可以看到Docker
在一步步执行Dockerfile
文件中的步骤。一共是9步。
最终构建成功!
构建成功后查看镜像:
docker images
确认镜像存在后运行镜像:
# --name myApp 定义容器名称为myApp
# -p 把主机的8999端口和容器的8999相关联
# -d 后台运行
# javaapp:1.0 需要运行的镜像名称
docker run --name myApp -p 8999:8999 -d javaapp:1.0
成功运行后查看正在运行的容器:
docker ps
确认java
程序在容器中正常运行后,就可以在浏览器中访问了。
四、使用java:8-alpine镜像去优化Dockerfile文件的编写
在微服务项目中,肯定不止一个镜像需要我们去构建。
如果每个微服务都是使用java
编写的话。
那么Dockerfile
文件中,选择基础镜像、安装jdk、配置环境变量的操作都是一致的。
我们没必要对每个微服务的镜像构建都做一次上面的操作。java:8-alpine
这个镜像就已经做了上面的操作。
所以我们只要选择java:8-alpine
,作为我们的基础镜像,就可以避免上面的重复操作了。
这也是Docker
镜像分层的体现。
如果对Docker
镜像分层机制不了解,可以查看我Docker
专栏下的Docker的概念、架构、安装详解
这篇博文。
了解了java:8-alpine
镜像的作用之后,就可以这么优化Dockerfile
文件了:
# 指定java:8-alpine作为基础镜像,它包含了java程序部署的基本环境依赖
FROM java:8-alpine
# 暴露需要被监听端口(一般就是application.yml中配置的端口号)
EXPOSE 8999
# 程序运行入口,就是java项目的启动命令
ENTRYPOINT java -jar /soft/app.jar
这样以后构建别的微服务的Dockerfile
文件就方便多了。
并且使用它构建镜像时,步骤也从9步变成了4步。
更多推荐
所有评论(0)