【docker】大小仅3GB的Oracle21c的docker镜像,含apex和oml4py

前言

之前在【ORACLE】从安装ORACLE LINUX 8开始构建一个ORACLE21C的docker镜像这篇文章中,最后构建出来的docker镜像有15GB,上传阿里云压缩后也有9GB,我怎么算都不对劲,系统100M,数据库也就几个GB,加上APEX,怎么也应该也不会超过10GB,有没有办法把大小压一压呢?

问题分析

于是我运行了一下

docker history imageid

image.png

发现有些层的数据大小出现了重复,有个3GB大小的额外出现了2次,所以导致整个镜像很大。于是我又仔细看了下Tim Hall的dockefile,发现写得很整齐规范,根据执行内容的不同,把代码分成了很多个阶段,并标有注释。

但是,对于dockerfile来说,每执行一条指令,它就会构建一个新的层。如果某条指令有修改现有的文件,那么它就会把数据都复制出一个新的层,这样大小就翻倍了。就算在本层把无用大文件删掉,上一层的大小还是不会变,因为上一层还有这个大文件。

所以,有时候会发现,常见的dockerfile都是用"&&\"把代码合并成一条来执行的,但本次的dockerfile代码量有点多,全合成一行不方便查看和修改,所以此时就要引入多阶段构建的概念。

Docker Engine 17.05 中引入了多阶段构建语法。
docker官方关于多阶段构建的说明https://docs.docker.com/develop/develop-images/multistage-build/

关于这个多阶段构建,我看了不少国内的文章介绍,但是大部分都是复制了一次官方的例子,或者稍做修改,完全没有找到我想要的用法。绝大部分能搜到的例子都是使用前一阶段的构建作为后一阶段构建的部分文件,而我需要的是只保留最后一个指令执行后的数据,前面不管有多少层都不要了。

于是我开始在github上搜“dockerfile”,看别人是怎么写的,果然绝大多数都是把指令都用"&&\"合并成了一条,然后我继续找,直到看到zabix的一个dockerfile,瞬间得到了启发,
https://github.com/zabbix/zabbix-docker/blob/5.4/Dockerfiles/server-pgsql/ol/Dockerfilez

COPY --from=builder ["/tmp/zabbix-${ZBX_VERSION}/src/zabbix_server/zabbix_server", "/usr/sbin/zabbix_server"]

因为我搜到的其他例子大多都是这么写的

COPY --from=builder /go/src/github.com/helloworld/app .
COPY --from=builder /build/server /

搜不到一例复制所有文件的,所以不清楚这个语法应该是 “/ /” 还是 “. .”,是复制文件夹还是复制文件夹中的所有文件?但是有了zabix的这个例子,它是使用了一个包含两个元素的list,前面和后面都是一个文件夹,且末尾没有"/",类型是一样的,那么理论上,它是支持同名文件夹直接覆盖的。

解决方案

所以,我的想法是,无论一个dockerfile前面执行了多少条指令,我只要在最后,再执行一次构建,构建的源镜像和第一阶段的源镜像保持一致(理论上,空镜像也行?),然后把第一阶段最终构建的所有文件都复制到第二阶段构建中去,那么第二阶段的镜像就只有一层了,而且这种方法是通用的。

就像这样:

FROM oraclelinux:8 as builder
...
#一堆命令
...

FROM oraclelinux:8
COPY --from=builder ["/", "/"]

于是开始实测,首先我把第二次构建加在了CMD命令的后面,发现以这个镜像创建容器并启动后,它并不会执行CMD中的内容,于是我就把第二次构建向上移动一条,结果又发现,构建的环境变量不会被继承,于是我又把第一阶段声明的环境变量在第二阶段又复制粘贴了一次。最终果然成功了。
原始版本结构是这个样子

FROM oraclelinux:8 
ENV ORACLE_BASE=/u01/app/oracle 

...
#一堆命令
...

CMD exec ${SCRIPTS_DIR}/start.sh

改之后结构为这个样子

FROM oraclelinux:8 as builder
ENV ORACLE_BASE=/u01/app/oracle 

...
#一堆命令
...

FROM oraclelinux:8
COPY --from=builder ["/", "/"]
ENV ORACLE_BASE=/u01/app/oracle 
CMD exec ${SCRIPTS_DIR}/start.sh

可以看到并不用修改多少代码,即可把所有无用的层都干掉,每个文件只留一份数据。

成品

按这个方案构建后,最终的镜像大小只有9GB了
image.png

然后上传阿里云
image.png

阿里云压缩后只有3G了
image.png

项目地址:https://github.com/Dark-Athena/dockerfile/tree/main/ol8_21_oml4py

docker pull及run:

docker pull registry.cn-shanghai.aliyuncs.com/darkathena/ol8_21_oml4py:2.0
docker run -dit --name ol8_21_con -p 1521:1521 -p 5500:5500 --shm-size="1G"  registry.cn-shanghai.aliyuncs.com/darkathena/ol8_21_oml4py:2.0

补充

其实Tim Hall也说了,这是他用来玩的,有些地方写得不是很好,不过我倒是通过这次亲自尝试,对docker又多了一点经验,要是一开始他的dockerfile构建的镜像很小,我又怎么会想到要去优化它呢?
https://github.com/oraclebase/dockerfiles

Just some Dockerfiles I’m playing around with. Some will be simple and stupid. Others might be a bit more useful to look at if you are learning about Docker.
Feel free to copy or fork this stuff. It’s unlikely I’ll accept pull requests as it’s just my playground.

要在Linux上安装Oracle Database 21c,可以使用Docker容器化技术进行安装。下面是一些基本步骤: 1. 首先,确保你已经在Linux上安装了Docker。如果没有安装,请根据你的Linux发行版文档进行安装。 2. 在终端中运行以下命令,从Docker Hub下载Oracle Database 21c镜像: ``` docker pull store/oracle/database-enterprise:21.3.0.0 ``` 3. 下载Oracle Database 21c的安装文件。你需要前往Oracle官方网站(https://www.oracle.com/database/technologies/oracle21c-linux-downloads.html)并获取适用于Linux的安装文件。 4. 将下载的安装文件复制到一个目录中,比如 `/opt/oracle21c` 5. 使用以下命令启动Docker容器并安装Oracle Database 21c: ``` docker run -d -it --name oracle21c \ -p 1521:1521 -p 5500:5500 \ -e ORACLE_SID=ORCLCDB \ -e ORACLE_PDB=ORCLPDB1 \ -e ORACLE_PWD=your_password \ -v /opt/oracle21c:/install \ store/oracle/database-enterprise:21.3.0.0 ``` 这个命令会创建一个名为 `oracle21c` 的Docker容器,并将它与主机的1521端口和5500端口进行映射。你需要将 `your_password` 替换为你自己的密码。 6. 运行以下命令进入容器的Bash终端: ``` docker exec -it oracle21c bash ``` 7. 在容器中,将安装文件解压缩到 `/install` 目录: ``` cd /install unzip oracle-database-21c-*.zip ``` 8. 运行安装脚本: ``` ./runInstaller ``` 根据提示进行安装,选择相应的选项和配置。 9. 安装完成后,可以使用Oracle Database 21c了。你可以使用SQL*Plus等工具连接到数据库。 这些是基本的安装步骤,你可以根据实际需要进行调整。请注意,在安装Oracle Database 21c之前,确保你的Linux系统满足Oracle的硬件和软件要求。此外,根据你的需求,你可能需要进行其他配置和调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DarkAthena

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值