我正在使用CircleCI和docker进行CI / CD管道。 基本上,每次我将新代码推送到GitHub时,我都会将(python)应用程序和环境包装在一个新的docker镜像中。 然后我将图像推送到我用Nexus托管的私有Docker注册表,并通过从此注册表中提取最新图像并运行容器来部署我的应用程序。
我的问题是这些码头图像占用了大量的空间:
REPOSITORY TAG IMAGE ID CREATED SIZE
my-app 0.1.23 6f13476770c2 3 minutes ago 1.99GB
my-app 0.1.22 7ff62dddb50a 10 minutes ago 1.99GB
my-app 0.1.21 55af2d3235c7 3 hours ago 1.99GB
my-app 0.1.20 304543b7fc71 5 hours ago 1.99GB
my-app 0.1.17 fddcef3f262b 2 weeks ago 1.99GB
my-app 0.1.16 a62c9ba1f997 2 weeks ago 1.99GB
my-app 0.1.12 a8d87d86699a 2 weeks ago 1.99GB
由于运行环境在图像中占用了大量空间并且不会频繁更改(不像更改代码那样频繁),我认为通过一遍又一遍地构建相同的依赖关系/环境来浪费大量空间。 所以问题是我是以正确的方式做到的吗? 如果不是最佳做法。 提前致谢!
PS我正在使用的环境需要一些需要GCC的依赖项(numpy,tensorflow等),因此如果我没有弄错的话,我无法使用python alpine图像。
我的Dockerfile:
FROM python:3.6-stretch
# Install app dependencies
RUN apt-get update && apt-get install -y \
python3-dev \
python3-pip
RUN mkdir /opt/working_dir/
WORKDIR /opt/working_dir/
# Copy the entire project into the current directory
COPY . ./
RUN pip install --upgrade pip
RUN pip install -r requirements.txt
一些码头图像历史:
$ docker image history my-app:0.1.23
6f13476770c2 19 hours ago /bin/sh -c pip install -r requirements.txt 955MB
<missing> 19 hours ago /bin/sh -c pip install --upgrade pip 4.97MB
<missing> 19 hours ago /bin/sh -c #(nop) COPY dir:5bb6533618d16964c… 16.5MB
<missing> 19 hours ago /bin/sh -c #(nop) WORKDIR /opt/reco_engine/ 0B
<missing> 19 hours ago /bin/sh -c mkdir /opt/reco_engine/ 0B
<missing> 19 hours ago /bin/sh -c apt-get update && apt-get install… 90.6MB
<missing> 6 days ago /bin/sh -c #(nop) CMD ["python3"] 0B
<missing> 6 days ago /bin/sh -c set -ex; wget -O get-pip.py 'ht… 6.04MB
<missing> 6 days ago /bin/sh -c #(nop) ENV PYTHON_PIP_VERSION=19… 0B
<missing> 6 days ago /bin/sh -c cd /usr/local/bin && ln -s idle3… 32B
<missing> 6 days ago /bin/sh -c set -ex && wget -O python.tar.x… 65.3MB
<missing> 6 days ago /bin/sh -c #(nop) ENV PYTHON_VERSION=3.6.8 0B
<missing> 6 days ago /bin/sh -c #(nop) ENV GPG_KEY=0D96DF4D4110E… 0B
<missing> 6 days ago /bin/sh -c apt-get update && apt-get install… 16.9MB
<missing> 6 days ago /bin/sh -c #(nop) ENV LANG=C.UTF-8 0B
<missing> 6 days ago /bin/sh -c #(nop) ENV PATH=/usr/local/bin:/… 0B
<missing> 6 days ago /bin/sh -c set -ex; apt-get update; apt-ge… 562MB
<missing> 6 days ago /bin/sh -c apt-get update && apt-get install… 142MB
<missing> 6 days ago /bin/sh -c set -ex; if ! command -v gpg > /… 7.81MB
<missing> 6 days ago /bin/sh -c apt-get update && apt-get install… 23.2MB
<missing> 6 days ago /bin/sh -c #(nop) CMD ["bash"] 0B
<missing> 6 days ago /bin/sh -c #(nop) ADD file:843b8a2a9df1a0730… 101MB
$ docker image history my-app:0.1.22
IMAGE CREATED CREATED BY SIZE COMMENT
7ff62dddb50a 19 hours ago /bin/sh -c pip install -r requirements.txt 955MB
<missing> 19 hours ago /bin/sh -c pip install --upgrade pip 4.97MB
<missing> 19 hours ago /bin/sh -c #(nop) COPY dir:f054e43f5766a4738… 16.5MB
<missing> 19 hours ago /bin/sh -c #(nop) WORKDIR /opt/reco_engine/ 0B
<missing> 19 hours ago /bin/sh -c mkdir /opt/reco_engine/ 0B
<missing> 19 hours ago /bin/sh -c apt-get update && apt-get install… 90.6MB
<missing> 6 days ago /bin/sh -c #(nop) CMD ["python3"] 0B
<missing> 6 days ago /bin/sh -c set -ex; wget -O get-pip.py 'ht… 6.04MB
<missing> 6 days ago /bin/sh -c #(nop) ENV PYTHON_PIP_VERSION=19… 0B
<missing> 6 days ago /bin/sh -c cd /usr/local/bin && ln -s idle3… 32B
<missing> 6 days ago /bin/sh -c set -ex && wget -O python.tar.x… 65.3MB
<missing> 6 days ago /bin/sh -c #(nop) ENV PYTHON_VERSION=3.6.8 0B
<missing> 6 days ago /bin/sh -c #(nop) ENV GPG_KEY=0D96DF4D4110E… 0B
<missing> 6 days ago /bin/sh -c apt-get update && apt-get install… 16.9MB
<missing> 6 days ago /bin/sh -c #(nop) ENV LANG=C.UTF-8 0B
<missing> 6 days ago /bin/sh -c #(nop) ENV PATH=/usr/local/bin:/… 0B
<missing> 6 days ago /bin/sh -c set -ex; apt-get update; apt-ge… 562MB
<missing> 6 days ago /bin/sh -c apt-get update && apt-get install… 142MB
<missing> 6 days ago /bin/sh -c set -ex; if ! command -v gpg > /… 7.81MB
<missing> 6 days ago /bin/sh -c apt-get update && apt-get install… 23.2MB
<missing> 6 days ago /bin/sh -c #(nop) CMD ["bash"] 0B
<missing> 6 days ago /bin/sh -c #(nop) ADD file:843b8a2a9df1a0730… 101MB
app-base
。 app-base
图像绝对是您可以制作的小图像。 它不包括VM所做的事情。 你从一个小的基础图像开始,你工作,工作,工作,使它非常小。 app-base
。 您的应用程序大小取决于您但不应提供开发工具。 我假设你运行python。 例如,您的图像为2GB。 Alpine Linux Python docker镜像为80MB。 您的应用可能会添加说法,另外100MB。 如果您有许多本机依赖项,那么可能很难将其分解或使用Alpine(比如说您需要GCC)。
如果一切都很幸运,您的应用程序基础映像将为80MB,您将部署的CI构建的应用程序映像将为100MB。 80MB将不会被反复使用,因为您的Nexus服务器将重用其中包含Python的app-base
(来自Alpine Python或您自己的自定义)。 采用这种方法可能会为您节省大量空间(转化为速度)。
但这取决于您的应用程序及其遗产方式。
“最好”的做法(没有这样的东西,但这里有一些提示):
大多数python Dockerfile示例都将requirements.txt文件与其余的python代码分开处理,如:
FROM python:3.6-stretch
# Install app dependencies
RUN apt-get update && apt-get install -y \
python3-dev \
python3-pip
RUN mkdir /opt/working_dir/
WORKDIR /opt/working_dir/
# Copy the entire project into the current directory
RUN pip install --upgrade pip
COPY requirements.txt ./
RUN pip install -r requirements.txt
COPY . ./
通过这样做,您的构建将更快,并重用除最后一层之外的所有构建,除非requirements.txt文件得到更新。 您仍会在image ls
输出中看到大图像,但如果您检查图层,您会发现几乎所有图像之间的图像都是相同的。
有许多方法可以优化图像。 如果你发布你的Dockerfile,我可以给你提示。
您还可以检查图像的历史记录:
docker image history my-app:0.1.23
这会告诉您每个命令在其构建的特定层中添加了多少空间。
您还可以检查图像并查看共用的层数:
docker inspect my-app:0.1.23
将docker_layer_caching
添加到配置文件中:
jobs:
jobName:
machine:
enabled: true
docker_layer_caching: true
在此之后,所有旧图层都缓存在CircleCI上。