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)
指令说明
| 指令 | 描述 |
|---|---|
| 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 wgetCOPY ./app /usr/local/appWORKDIR /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 # 清理所有未使用的镜像、容器和构建缓存
相关文章:
Dockerfile容器镜像构建技术
文章目录 1、容器回顾1_容器与容器镜像之间的关系2_容器镜像分类3_容器镜像获取的方法 2、其他容器镜像获取方法演示1_在DockerHub直接下载2_把操作系统的文件系统打包为容器镜像3_把正在运行的容器打包为容器镜像 3、Dockerfile介绍4、Dockerfile指令1_FROM2_RUN3_CMD4_EXPOSE…...
Github 2024-12-01 开源项目月报 Top20
根据Github Trendings的统计,本月(2024-12-01统计)共有20个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目10TypeScript项目9Go项目2HTML项目1Shell项目1Jupyter Notebook项目1屏幕截图转代码应用 创建周期:114 天开发语言:TypeScript, Py…...
Spring Boot 3项目集成Swagger3教程
Spring Boot 3项目集成Swagger3教程 ?? 前言 欢迎来到我的小天地,这里是我记录技术点滴、分享学习心得的地方。?? ?? 技能清单 编程语言:Java、C、C、Python、Go、前端技术:Jquery、Vue.js、React、uni-app、EchartsUI设计: Element-u…...
NISP信息安全一级考试200道;免费题库;大风车题库
下载链接:大风车题库-文件 大风车题库网站:大风车题库 大风车excel(试题转excel):大风车excel...
Android ConstraintLayout 约束布局的使用手册
目录 前言 一、ConstraintLayout基本介绍 二、ConstraintLayout使用步骤 1、引入库 2、基本使用,实现按钮居中。相对于父布局的约束。 3、A Button 居中展示,B Button展示在A Button正下方(距离A 46dp)。相对于兄弟控件的约束…...
在网安中什么是白帽子
在网络安全领域,白帽子是指那些专门从事网络安全研究,帮助企业或个人发现并修复安全漏洞的专家。以下是对白帽子的详细解释: 一、定义与角色 白帽子是网络安全领域的术语,通常指那些具备专业技能和知识的网络安全专家。他们的工作…...
软件专业科目难度分级 你输在了哪里?
感想: 我把我们现在软件专业学的东西分了个难度级别 级别描述视角服务对象例子0 基本软件的使用用户-Photoshop wps ssms等1 软件的原理开发者用户各种编程语言2软件的原理的原理开发者开发者各种函数的深层定义,数据结构等 0级就是咱们平时用的那些软…...
微信小程序实现图片拖拽调换位置效果 -- 开箱即用
在编写类似发布朋友圈功能的功能时,需要实现图片的拖拽排序,删除图片等功能。 博主的小程序首页也采用了该示例代码,可以在威信中搜索: 我的百宝工具箱 或者复制后面的🔗在手机打开: #小程序://百宝工具箱/…...
关于“浔川AI翻译”使用情况的调研报告
关于“浔川 AI 翻译”使用情况的调研报告 随着全球化进程加速及外语学习需求攀升,AI 翻译工具愈发普及。“浔川 AI 翻译”作为行业产品之一,为了解其市场表现与用户反馈,特开展本次问卷调查,现将关键结果汇报如下。 一、样本概…...
《芯片:科技之核,未来之路》
《芯片:科技之核,未来之路》 一、芯片的定义与重要性二、芯片的应用领域(一)新能源领域(二)信息通讯设备领域(三)4C 产业(四)智能电网领域(五&…...
️ 在 Windows WSL 上部署 Ollama 和大语言模型的完整指南20241206
🛠️ 在 Windows WSL 上部署 Ollama 和大语言模型的完整指南 📝 引言 随着大语言模型(LLM)和人工智能的飞速发展,越来越多的开发者尝试在本地环境中部署大模型进行实验。然而,由于资源需求高、网络限制多…...
使用Tomcat搭建简易文件服务器
创建服务器 1. 复制一个tomcat服务器,并命名为file-service(好区分即可) 2.在webapp里面新建一个文件夹 uploadfiles ,用于存储上传的文件 3. 修改conf/service.xml,配置文件服务器的端口与上传文件夹的访问 在Host标签之间加入一个Context标签 docBase"uploa…...
《C++赋能:构建智能工业控制系统优化算法新引擎》
在工业 4.0 的浪潮汹涌澎湃之际,传统工业控制系统正面临着前所未有的挑战与机遇。如何借助人工智能的强大力量,实现工业控制系统的深度优化,已成为工业领域乃至整个科技界关注的焦点。而 C语言,以其卓越的性能、高效的执行效率和对…...
node.js中跨域请求有几种实现方法
默认情况下,出于安全考虑,浏览器会实施同源策略,阻止网页向不同源的服务器发送请求或接收来自不同源的响应。 同源策略:协议、域名、端口三者必须保持一致 <!DOCTYPE html> <html lang"en"> <head>&l…...
Node.js新作《循序渐进Node.js企业级开发实践》简介
《循序渐进Node.js企业级开发实践》由清华大学出版社出版,已于近期上市。该书基于Node.js 22.3.0编写,提供26个实战案例43个上机练习,可谓是目前市面上最新的Node.js力作。 本文对《循序渐进Node.js企业级开发实践》一书做个大致的介绍。 封…...
常见排序算法总结 (四) - 快速排序与随机选择
快速排序 算法思想 每一轮在数组相应的范围上随机找一个元素进行划分,将不大于它的所有元素都放到左边,将大于它的元素都放到右边。在左右两个子数组上不断地递归,直到整个数组上有序。 注意:实现时选择的时参考荷兰国旗问题优化…...
Doris的基础架构
Doris的基础架构 Frontend(FE):主要负责用户请求的接入、查询解析规划、元数据的管理、节点管理相关工作。Backend(BE):主要负责数据存储、查询计划的执行。 我的Github地址,欢迎大家加入我的开…...
python录制鼠标键盘操作循环播放
依赖 pip install pynput 程序: from pynput import mouse, keyboard import time import threading# 用于存储录制的鼠标和键盘事件 mouse_events [] keyboard_events []# 定义事件处理函数# 处理鼠标事件 def on_move(x, y):mouse_events.append((move, x, y))def on_cl…...
标书里的“废标雷区”:你踩过几个?
在投标领域,标书的质量不仅决定了中标的可能性,更是体现企业专业度的关键。但即便是经验丰富的投标人,也难免会在标书编制过程中踩中“废标雷区”。这些雷区可能隐藏在技术方案的细节中,也可能是投标文件格式的规范问题。以下&…...
centos下使用acme来自动获取免费通配符ssl证书,并发布到nginx服务,(DNS服务为阿里云)
参考链接: 官方文档 acme.sh获取证书 # 下载acme的项目 git clone https://gitee.com/neilpang/acme.sh.git # 执行安装脚本 cd acme.sh ./acme.sh --install -m myexample.com # 安装脚本会新增一个定时任务,这个命令可以检查 crontab -l # 从阿里云获取ks,写入 export Ali_…...
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...
CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...
Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...
Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...
重启Eureka集群中的节点,对已经注册的服务有什么影响
先看答案,如果正确地操作,重启Eureka集群中的节点,对已经注册的服务影响非常小,甚至可以做到无感知。 但如果操作不当,可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...
智能AI电话机器人系统的识别能力现状与发展水平
一、引言 随着人工智能技术的飞速发展,AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术,在客户服务、营销推广、信息查询等领域发挥着越来越重要…...
Linux 中如何提取压缩文件 ?
Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...
