Dockerfile容器镜像构建技术
文章目录
- 1、容器回顾
- 1_容器与容器镜像之间的关系
- 2_容器镜像分类
- 3_容器镜像获取的方法
- 2、其他容器镜像获取方法演示
- 1_在DockerHub直接下载
- 2_把操作系统的文件系统打包为容器镜像
- 3_把正在运行的容器打包为容器镜像
- 3、Dockerfile介绍
- 4、Dockerfile指令
- 1_FROM
- 2_RUN
- 3_CMD
- 4_EXPOSE
- 5_ENV
- 6_ADD
- 7_COPY
- 8_ENTRYPOINT
- 9_VOLUME
- 10_USER
- 11_WORKDIR
- 5、Dockerfile基本构成
- 6、Dockerfile生成容器镜像方法
- 7、Dockerfile生成容器镜像案例
- 1_使用Dockerfile生成容器镜像步骤
- 2_使用Dockerfile生成Nginx容器镜像
- 3_使用Dockerfile生成Tomcat容器镜像
- 8、使用Dockerfile生成容器镜像优化
- 1_减少镜像分层
- 2_清理无用数据
- 3_多阶段构建镜像
- 4_构建出现问题
1、容器回顾
1_容器与容器镜像之间的关系
说到Docker管理的容器不得不说容器镜像,主要因为容器镜像是容器模板,通过容器镜像我们才能快速创建容器。
如下图所示:
Docker Daemon 通过容器镜像创建容器。
2_容器镜像分类
操作系统类
-
CentOS
-
Ubuntu
-
在 Docker Hub下载或自行制作
应用类
-
Tomcat
-
Nginx
-
MySQL
-
Redis
3_容器镜像获取的方法
主要有以下几种:
1、在 DockerHub 直接下载
2、把操作系统中的文件系统打包为容器镜像
3、把正在运行的容器打包为容器镜像,即docker commit
4、通过Dockerfile实现容器镜像的自定义及生成
2、其他容器镜像获取方法演示
1_在DockerHub直接下载
拉取系统镜像
docker pull centos:latest
拉取应用镜像
docker pull nginx:latest
2_把操作系统的文件系统打包为容器镜像
1.安装一个最化的操作系统
系统1核1g内存20g就行,只是用来做镜像不需要太高配置,最小安装也可以不创建其他用户,只设个root密码就行。
2.把操作系统中文件系统进行打包
在无图形化操作系统中输入如下命令
tar --numeric-owner --exclude=/proc --exclude=/sys -cvf centos7u6.tar /
--numeric-owner
:这个选项让 tar
在归档时使用用户和组的数字 ID(UID 和 GID),而不是使用用户名和组名。
3.把打包后文件加载至本地文件系统生成本地容器镜像
传输到另一主机中
[root@localhost ~]# scp centos7u6.tar 192.168.150.145:/root
The authenticity of host '192.168.150.145 (192.168.150.145)' can't be established.
ECDSA key fingerprint is SHA256:AZAtK8Y0RYrW8aImRua0toxovVYNzIxo/vwF55SNq4Y.
ECDSA key fingerprint is MD5:25:78:36:4f:e3:8f:20:a4:03:2b:b2:47:d8:39:e5:f6.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.150.145' (ECDSA) to the list of known hosts.
root@192.168.150.145's password:
centos7u6.tar
查看打包的文件大小
[root@localhost ~]# ls -lh
总用量 1.3G
-rw-r--r--. 1 root root 1.3G 12月 6 10:58 centos7u6.tar
导入自定义镜像
docker import centos7u6.tar centos7u6:v1
查看自定义镜像
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos7u6 v1 b533c3b8dd48 28 seconds ago 1.34GB
使用自定义镜像运行容器
[root@localhost ~]# docker run -it centos7u6:v1 bash
[root@44b68ccd0b89 /]# ip route
default via 172.17.0.1 dev eth0
172.17.0.0/16 dev eth0 proto kernel scope link src 172.17.0.2
3_把正在运行的容器打包为容器镜像
1.运行一个容器
运行之前创建的容器并进入其内部
docker start 44b68ccd0b89
docker exec -it 44b68ccd0b89 /bin/bash
2.在容器中安装应用
由于 CentOS7 官方 yum 源不维护了,先导入阿里镜像源再安装软件
[root@44b68ccd0b89 /]# curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
[root@44b68ccd0b89 /]# yum -y install httpd
3.把正在运行的容器打包为容器镜像
使用让容器继续运行的方式退出
[root@44b68ccd0b89 /]# ctrl + p +q
将容器提交为镜像
docker commit 44b68ccd0b89 centos7u6-httpd:v1
查看创建的镜像
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos7u6-httpd v1 bb155ef55e50 22 seconds ago 1.91GB
发现使用该镜像创建的容器中有我们下载的软件
[root@localhost ~]# docker run -it centos7u6-httpd:v1 bash
[root@a54843b01bb0 /]# rpm -qa | grep httpd
httpd-tools-2.4.6-99.el7.centos.1.x86_64
httpd-2.4.6-99.el7.centos.1.x86_64
3、Dockerfile介绍
Dockerfile 是一种能够被 Docker 程序解释的剧本。
Dockerfile 由一条一条的指令组成,并且有自己的书写格式和支持的命令。
当我们需要在容器镜像中指定自己额外的需求时,只需在 Dockerfile 上添加或修改指令,然后通过docker build
生成我们自定义的容器镜像(image)。
4、Dockerfile指令
构建类指令
- 用于构建
image
- 其指定的操作不会在运行
image
的容器上执行(FROM、MAINTAINER、RUN、ENV、ADD、COPY)
设置类指令
- 用于设置
image
的属性 - 其指定的操作将在运行
image
的容器中执行(CMD、ENTRYPOINT、USER 、EXPOSE、VOLUME、WORKDIR、ONBUILD)
每一个指令都会形成一层Layer,指令说明:
指令 | 描述 |
---|---|
FROM | 构建新镜像基于的基础镜像 |
LABEL | 标签 |
RUN | 构建镜像时运行的 Shell 命令 |
COPY | 拷贝文件或目录到镜像中 |
ADD | 解压压缩包并拷贝 |
ENV | 设置环境变量 |
USER | 为 RUN、CMD 和 ENTRYPOINT 执行命令指定运行用户 |
EXPOSE | 声明容器运行的服务端口 |
CMD | 运行容器时默认执行,如果有多个CMD指令,最后一个生效 |
ENTRYPOINT | 镜像中应用的启动命令,容器运行时调用 |
WORKDIR | 为 RUN、CMD、ENTRYPOINT、COPY 和 ADD 设置工作目录 |
VOLUME | 创建一个挂载点(mount point),并将其作为一个持久化数据卷(volume)来使用 |
MAINTAINER | 指定镜像的维护者信息,已经被废弃,推荐使用LABEL。 |
指令详细解释,参考官网:https://docs.docker.com/reference/dockerfile/
通过man dockerfile
也可以查看到详细的说明,这里简单的翻译并列出常用的指令
1_FROM
FROM 指令用于指定其后构建新镜像所使用的基础镜像。
FROM 指令必是 Dockerfile 文件中的首条命令。
FROM 指令指定的基础image
可以是官方远程仓库中的,也可以位于本地仓库,优先本地仓库。
- 格式:
FROM <image>:<tag>
例:
FROM centos:latest
2_RUN
RUN 指令用于在构建镜像中执行命令,有以下两种格式:
- shell 格式:
RUN <命令>
例:
RUN echo 'run duration' > /var/www/html/index.html
- exec 格式:
RUN ["可执行文件", "参数1", "参数2"]
例:
RUN ["/bin/bash", "-c", "echo hello world > /var/www/html/index.html"]
注意:
按优化的角度来讲,当有多条要执行的命令,不要使用多条 RUN,尽量使用&&
符号与\
符号连接成一行。
因为多条 RUN 命令会让镜像建立多层(总之就是会变得臃肿了😃)
RUN yum install httpd httpd-devel -y
RUN echo test > /var/www/html/index.html
可以改成
RUN yum install httpd httpd-devel -y && echo test > /var/www/html/index.html
或者改成
RUN yum install httpd httpd-devel -y \&& echo test > /var/www/html/index.html
3_CMD
CMD与RUN不同,CMD用于指定在容器启动时所要执行的命令,而RUN用于指定镜像构建时所要执行的命令。
格式有三种:
CMD ["executable","param1","param2"]
CMD ["param1","param2"]
CMD command param1 param2
每个 Dockerfile 只能有一条 CMD 命令,如果指定了多条命令,只有最后一条会被执行。
如果用户启动容器时候指定了运行的命令,则会覆盖掉CMD指定的命令。
什么是启动容器时指定运行的命令?
docker run -d -p 80:80 image_name commond_run
4_EXPOSE
EXPOSE 指令用于指定容器在运行时监听的端口
- 格式:
EXPOSE <port> [<port>...]
例:
EXPOSE 80 3306 8080
上述运行的端口还需要使用docker run
运行容器时通过-p
参数映射到宿主机的端口。
5_ENV
ENV 指令用于指定一个环境变量
- 格式:
ENV <key> <value>
或者ENV <key>=<value>
例:
ENV JAVA_HOME /usr/local/jdkxxxx/
6_ADD
ADD 指令用于把宿主机上的文件拷贝到镜像中
- 格式:
ADD <src> <dest>
<src>
可以是一个本地文件或本地压缩文件,还可以是一个url
,如果把<src>
写成一个url
,那么ADD就类似于wget
命令,<dest>
路径的填写可以是容器内的绝对路径,也可以是相对于工作目录的相对路径。
7_COPY
COPY 指令与 ADD 指令类似,但 COPY 的源文件只能是本地文件
格式:
COPY <src> <dest>
8_ENTRYPOINT
ENTRYPOINT 与 CMD 非常类似
相同点:
- 都是容器启动时才运行
- 一个 Dockerfile 只写一条,如果写了多条,那么只有最后一条生效
不同点:
- 如果用户启动容器时候指定了运行的命令,ENTRYPOINT 不会被运行的命令覆盖,而 CMD 则会被覆盖
格式有两种:
ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2
9_VOLUME
VOLUME 指令用于把宿主机里的目录与容器里的目录映射
只指定挂载点,docker 宿主机映射的目录为自动生成的。
格式:
VOLUME ["<mountpoint>"]
10_USER
USER 指令设置启动容器的用户(像hadoop需要hadoop用户操作,oracle需要oracle用户操作)
可以是用户名或 UID
USER daemon
USER 1001
注意:
如果设置了容器以daemon
用户去运行,那么 RUN、CMD 和 ENTRYPOINT 都会以这个用户去运行
镜像构建完成后,通过docker run
运行容器时,可以通过-u
参数来覆盖所指定的用户
11_WORKDIR
WORKDIR 指令设置工作目录,类似于cd
命令。不建议使用RUN cd /root
,建议使用 WORKDIR
WORKDIR /root
Docker 镜像的每一层的默认工作目录是/
(根目录),除非通过 WORKDIR 指令显式改变,cd
不能跨层级生效。
5、Dockerfile基本构成
组成 | 说明 | 示例 |
---|---|---|
基础镜像信息 | 定义容器的基础镜像,通常使用 FROM 指令指定。基础镜像可以是官方的镜像,或者自定义的镜像。 | FROM centos:7 |
维护者信息 | 通过 LABEL 或 MAINTAINER 指令定义镜像的维护者信息,通常包括姓名和联系方式。 | LABEL maintainer="sy@163.com" MAINTAINER "sy@163.com" |
镜像操作指令 | 用来安装软件、配置环境等。 常见指令有 RUN 、COPY 、ADD 、WORKDIR 、ENV 等。 | RUN yum install -y wget COPY ./app /usr/local/app WORKDIR /usr/local/app |
容器启动时执行指令 | 定义容器启动后执行的命令。 通常使用 CMD 或 ENTRYPOINT 指令,CMD 是默认命令,ENTRYPOINT 可以提供可执行文件及其参数。 | CMD ["java", "-jar", "app.jar"] ENTRYPOINT ["python3", "app.py"] |
6、Dockerfile生成容器镜像方法
7、Dockerfile生成容器镜像案例
1_使用Dockerfile生成容器镜像步骤
第一步:创建一个文件夹(目录)
第二步:在文件夹(目录)中创建 Dockerfile 文件(并编写)及其它文件
第三步:使用docker build
命令构建镜像
第四步:使用构建的镜像启动容器
2_使用Dockerfile生成Nginx容器镜像
在新的目录下进行操作
mkdir nginxroot
cd nginxroot
配置 nginx 首页的内容
echo "nginx's running" >> index.html
编写 Dockerfile 文件,就叫这个名字,不然需要单独指定
vim Dockerfile
并添加如下内容
# 指定基础镜像
FROM centos:centos7
# 指定镜像维护者信息,等于MAINTAINER "sy<sy@163.com>"已被弃用
LABEL maintainer="sy<sy@163.com>"
# 由于centos7官方不再维护yum源,所以设置阿里仓库地址,CentOSBase提供CentOS系统基础的包
RUN curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
# 下载wget命令
RUN yum -y install wget
# 设置 EPEL 源, EPEL 提供额外的社区支持的包
RUN wget -O /etc/yum.repos.d/epel.repo https://mirrors.aliyun.com/repo/epel-7.repo
# 安装 nginx
RUN yum -y install nginx
# 设置主页内容
ADD index.html /usr/share/nginx/html/
# 使nginx不以守护进程(后台)模式运行,这样容器才不会立刻退出
RUN echo "daemon off;" >> /etc/nginx/nginx.conf
# 暴露容器的 80 端口
EXPOSE 80
# 启动 nginx,等同于CMD /usr/sbin/nginx,推荐使用
CMD ["/usr/sbin/nginx"]
使用docker build
命令构建镜像
-t
:全称是tag
,表示版本- 镜像组成格式:
repository:version
.
:表示当前目录下的Dockerfile文件,不这么写则使用-f
指定Dockerfile文件
docker build -t centos7-nginx:v1 .
输出:
=> [internal] load build definition from Dockerfile 0.0s=> => transferring dockerfile: 986B 0.0s=> [internal] load metadata for docker.io/library/centos:centos7 4.4s=> [internal] load .dockerignore 0.0s=> => transferring context: 2B 0.0s=> [1/7] FROM docker.io/library/centos:centos7@sha256:be65f488b7764ad3638f236b7b515b3678369a5124c47b8d32916d6487418ea4 0.0s=> [internal] load build context 0.0s=> => transferring context: 91B 0.0s=> CACHED [2/7] RUN curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo 0.0s=> CACHED [3/7] RUN yum -y install wget 0.0s=> CACHED [4/7] RUN wget -O /etc/yum.repos.d/epel.repo https://mirrors.aliyun.com/repo/epel-7.repo 0.0s=> CACHED [5/7] RUN yum -y install nginx 0.0s=> CACHED [6/7] ADD index.html /usr/share/nginx/html/ 0.0s=> CACHED [7/7] RUN echo "daemon off;" >> /etc/nginx/nginx.conf 0.0s=> exporting to image 0.0s=> => exporting layers 0.0s=> => writing image sha256:16b8feb631a0952739150342851e9244b34383c7c39f17d93d985b352e47fc78 0.0s=> => naming to docker.io/library/centos7-nginx:v1
查看构建的镜像
[root@localhost nginxroot]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos7-nginx v1 16b8feb631a0 9 minutes ago 757MB
运行容器
docker run -d -p 8081:80 centos7-nginx:v1
测试
[root@localhost nginxroot]# curl http://localhost:8081
nginx's running
3_使用Dockerfile生成Tomcat容器镜像
创建工作目录
mkdir tomcatdir
cd tomcatdir/
配置 tomcat 首页内容
echo "tomcat is running" >> index.html
准备存放jdk
的文件目录(root
目录有一个jdk11
的安装包)
tar xf /root/jdk-11.0.25_linux-x64_bin.tar.gz -C /root/tomcatdir/
mv /root/tomcatdir/jdk-11.0.25 /root/tomcatdir/jdk
编写 Dockerfile 文件
vim Dockerfile
添加如下内容,如果 tomcat 无法下载,在此链接中查看存在的 Tomcat 版本,替换下方 BIG_VERSION 和 VERSION 对应的值即可
# 容器的基础镜像
FROM centos:centos7
# 指定镜像维护者信息
LABEL maintainer="sy<sy@163.com>"
# 设置相关的环境变量
ENV BIG_VERSION=9
ENV VERSION=9.0.97
ENV JAVA_HOME=/usr/local/jdk
ENV TOMCAT_HOME=/usr/local/tomcat
# 设置阿里yum源
RUN curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
# 安装wget
RUN yum -y install wget
# 下载tomcat
RUN wget https://dlcdn.apache.org/tomcat/tomcat-${BIG_VERSION}/v${VERSION}/bin/apache-tomcat-${VERSION}.tar.gz
# 解压
RUN tar xf apache-tomcat-${VERSION}.tar.gz
# 重命名
RUN mv apache-tomcat-${VERSION} /usr/local/tomcat
# 删除tomcat的安装包,节省空间
RUN rm -rf apache-tomcat-${VERSION}.tar.gz /usr/local/tomcat/webapps/*
# 创建根目录
RUN mkdir /usr/local/tomcat/webapps/ROOT
# 添加tomcat访问首页
ADD ./index.html /usr/local/tomcat/webapps/ROOT/
# 添加jdk
ADD ./jdk /usr/local/jdk
# 配置相关环境变量
RUN echo "export TOMCAT_HOME=/usr/local/tomcat" >> /etc/profile
RUN echo "export JAVA_HOME=/usr/local/jdk" >> /etc/profile
RUN echo "export PATH=${TOMCAT_HOME}/bin:${JAVA_HOME}/bin:$PATH" >> /etc/profile
RUN echo "export CLASSPATH=.:${JAVA_HOME}/lib/dt.jar:${JAVA_HOME}/lib/tools.jar" >> /etc/profile
# 生效环境变量
RUN source /etc/profile
# 暴露容器端口
EXPOSE 8080
# 启动tomcat
CMD ["/usr/local/tomcat/bin/catalina.sh","run"]
tomcatdir 目录最终会包含两个文件一个文件夹:
[root@localhost tomcatdir]# ls
Dockerfile index.html jdk
使用docker build
命令构建镜像
docker build -t centos-tomcat:v1 .
输出:
[+] Building 29.9s (20/20) FINISHED docker:default=> [internal] load build definition from Dockerfile 0.0s=> => transferring dockerfile: 1.48kB 0.0s=> [internal] load metadata for docker.io/library/centos:centos7 1.5s=> [internal] load .dockerignore 0.0s=> => transferring context: 2B 0.0s=> CACHED [ 1/15] FROM docker.io/library/centos:centos7@sha256:be65f488b7764ad3638f236b7b515b3678369a5124c47b8d32916d6487418ea4 0.0s=> [internal] load build context 2.4s=> => transferring context: 283.27MB 2.4s=> [ 2/15] RUN curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo 0.8s=> [ 3/15] RUN yum -y install wget 18.7s=> [ 4/15] RUN wget https://dlcdn.apache.org/tomcat/tomcat-9/v9.0.97/bin/apache-tomcat-9.0.97.tar.gz 3.5s => [ 5/15] RUN tar xf apache-tomcat-9.0.97.tar.gz 0.6s => [ 6/15] RUN mv apache-tomcat-9.0.97 /usr/local/tomcat 0.8s => [ 7/15] RUN rm -rf apache-tomcat-9.0.97.tar.gz /usr/local/tomcat/webapps/* 0.4s => [ 8/15] RUN mkdir /usr/local/tomcat/webapps/ROOT 0.3s => [ 9/15] ADD ./index.html /usr/local/tomcat/webapps/ROOT/ 0.0s => [10/15] ADD ./jdk /usr/local/jdk 0.6s => [11/15] RUN echo "export TOMCAT_HOME=/usr/local/tomcat" >> /etc/profile 0.3s=> [12/15] RUN echo "export JAVA_HOME=/usr/local/jdk" >> /etc/profile 0.5s=> [13/15] RUN echo "export PATH=/usr/local/tomcat/bin:/usr/local/jdk/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" >> /etc/profile 0.3s=> [14/15] RUN echo "export CLASSPATH=.:/usr/local/jdk/lib/dt.jar:/usr/local/jdk/lib/tools.jar" >> /etc/profile 0.4s=> [15/15] RUN source /etc/profile 0.5s=> exporting to image 0.7s=> => exporting layers 0.6s=> => writing image sha256:c1e152369fa64e4bc2594d9d0f0e7b049b1e5ed776ceb0b8fa3273b63007b4f5 0.0s=> => naming to docker.io/library/centos-tomcat:v1
查看当前镜像
[root@localhost tomcatdir]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos-tomcat v1 c1e152369fa6 33 seconds ago 792MB
创建 Tomcat 容器
docker run -d -p 8080:8080 centos-tomcat:v1
测试:
[root@localhost tomcatdir]# curl http://localhost:8080
tomcat is running
8、使用Dockerfile生成容器镜像优化
1_减少镜像分层
Dockerfile 中包含多种指令,如果涉及到部署最多使用的算是 RUN 命令了,使用 RUN 命令时,不建议每次安装都使用一条单独的 RUN 命令,可以把能够合并安装指令合并为一条,这样就可以减少镜像分层。
FROM centos:centos7
LABEL maintainer="sy@163.com"
RUN curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
RUN yum -y update
RUN yum -y install gcc make wget
RUN wget http://download.redis.io/releases/redis-6.2.6.tar.gz
RUN tar xzf redis-6.2.6.tar.gz
WORKDIR /redis-6.2.6
RUN make -j 4
RUN make install
RUN mkdir -p /etc/redis
COPY redis.conf /etc/redis/
EXPOSE 6379
VOLUME ["/data"]
CMD ["redis-server", "/etc/redis/redis.conf"]
优化内容如下:
FROM centos:centos7
LABEL maintainer="sy@163.com"
RUN curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
RUN yum -y update && \yum -y install gcc make wget
RUN wget http://download.redis.io/releases/redis-6.2.6.tar.gz && \tar xzf redis-6.2.6.tar.gz && \cd redis-6.2.6 && \make -j 4 && \make install
RUN mkdir -p /etc/redis
COPY redis.conf /etc/redis/
EXPOSE 6379
VOLUME ["/data"]
CMD ["redis-server", "/etc/redis/redis.conf"]
2_清理无用数据
- 一次RUN形成新的一层,如果没有在同一层删除,无论文件是否最后删除,都会带到下一层,所以要在每一层清理对应的残留数据,减小镜像大小。
- 把生成容器镜像过程中部署的应用软件包做删除处理
FROM centos:centos7
LABEL maintainer="sy@163.com"
RUN curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
RUN yum -y update && \yum -y install gcc make wget && \yum clean all
RUN wget http://download.redis.io/releases/redis-6.2.6.tar.gz && \tar xzf redis-6.2.6.tar.gz && \cd redis-6.2.6 && \make -j 4 && \make install && \cd .. && \rm -rf redis-6.2.6.tar.gz redis-6.2.6
RUN mkdir -p /etc/redis
COPY redis.conf /etc/redis/
EXPOSE 6379
VOLUME ["/data"]
CMD ["redis-server", "/etc/redis/redis.conf"]
三次大小对比:
[root@localhost redisdir]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos-redis v3 bba7ae421d35 8 seconds ago 434MB
centos-redis v2 6f6f12c2b48a 2 minutes ago 801MB
centos-redis v1 4d6274008dbb 5 minutes ago 1.02GB
3_多阶段构建镜像
项目容器镜像有两种,一种直接把项目代码复制到容器镜像中,下次使用容器镜像时即可直接启动;另一种把需要对项目源码进行编译,再复制到容器镜像中使用。
不论是哪种方法都会让制作镜像复杂了些,并也会让容器镜像比较大,建议采用分阶段构建镜像的方法实现。
# 第一阶段:构建应用
FROM maven:3.8-jdk-11 AS build
ADD ./pom.xml pom.xml
ADD ./src src/
RUN mvn clean package# 第二阶段:运行时镜像
FROM tomcat:9
COPY --from=build target/*.war /usr/local/tomcat/webapps/ROOT.war
第一个 FROM 后边多了个 AS 关键字,可以给这个阶段起个名字
第二个 FROM 使用上面构建的 Tomcat 镜像,COPY 关键字增加了 --from
参数,用于拷贝某个阶段的文件到当前阶段。
4_构建出现问题
如果构建出现错误,可以使用如下命令清除相关缓存
docker builder prune # 删除没有任何标签或没有被引用的构建缓存文件
docker builder prune -a # 删除所有的构建缓存
docker system prune -f # 清理所有未使用的镜像、容器和构建缓存