我正在我的主机(MacOS、M2 Pro)上构建一个 docker 映像,我想将其部署到 EC2 实例。正常构建将使图像大小为 2GB,这很好。但部署在EC2上会导致系统兼容性问题:
WARNING: The requested image's platform (linux/arm64/v8) does not match the detected host platform (linux/amd64/v3) and no specific platform was requested
。所以我正在尝试使用 buildx
命令进行构建。然而,即使我更改的只是一个构建命令,它也会产生高达 13GB 的空间。我想知道为什么以及如何减小尺寸。
这是我的 Dockerfile:
FROM python:3.11-slim
# for -slim version (it breaks if you don't comment out && apt-get clean)
RUN apt-get update && apt-get install -y \
gfortran \
libopenblas-dev \
liblapack-dev \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Set environment variables to make Python and Poetry play nice
ENV POETRY_VERSION=1.7.1 \
PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
EXPERIMENT_ID=$EXPERIMENT_ID \
RUN_ID=$RUN_ID
## Install poetry
RUN pip install "poetry==$POETRY_VERSION"
## copy project requirement files here to ensure they will be cached.
WORKDIR /app
COPY poetry.lock pyproject.toml ./
RUN poetry config virtualenvs.create false \
&& poetry install --no-interaction --no-dev --no-ansi --verbose \
&& poetry cache clear pypi --all
# Copy the model directory to the Docker image
COPY mlartifacts/542535033067401306/2ba405d6d3144db6a5cd237509e53ef8 /app/mlartifacts/542535033067401306/2ba405d6d3144db6a5cd237509e53ef8/
# Copy the blacklist and whitelist data
COPY data/blacklist.txt data/whitelist.txt /app/data/
## Copy Python files
COPY *.py .
COPY utils/ ./utils/
COPY .env .
EXPOSE 7070
CMD ["poetry", "run", "flask", "run", "--host=0.0.0.0"]
我正在复制 ML 模型的目录,但它的大小只有 200KB。
这个命令将构建一个 2GB 的镜像。
docker build -f ./docker/Dockerfile \
-t makotomiyazaki1021/malicious-url-prediction-img:v4-amd64 .
这将生成一个 13GB 的图像
docker buildx build --platform linux/amd64 -f ./docker/Dockerfile \
-t makotomiyazaki1021/malicious-url-prediction-img:v4-amd64 .
我使用
/bin/bash
和 du
命令进入巨大的图像,我发现总使用空间约为 2MB。因此,这表明大型 Docker 映像大小问题可能与我添加到映像中的文件没有直接关系,而是与基础映像以及包安装和配置创建的层直接相关。
我还使用
dive
来调查空间使用情况,但并没有真正说明问题所在。
我有一种感觉,它来自
poetry
,但仅通过更改构建上下文而在大小上产生如此大的差异仍然很奇怪。有什么建议吗?
仅供参考,这就是我运行容器的方式。
docker run --rm -p 7070:5000 -v $(pwd)/logs:/app/logs makotomiyazaki1021/malicious-url-prediction-img:v4-amd64
问题在于构建。
当您运行 AMD64 时,可能已经有可以使用的预编译轮子,因此无需构建任何东西。当您使用 ARM64 时,可用的轮子通常会少很多,需要您构建项目。
构建占用空间 - 它们下载库、编译工件并将事物链接在一起。
您应该做的是使用多阶段构建。在构建过程的一个阶段运行安装,然后将创建的文件移至新容器中。
例如(这未经测试,但基于您的文件,并且应该进行一些调整):
FROM python:3.11-slim
# for -slim version (it breaks if you don't comment out && apt-get clean)
RUN apt-get update && apt-get install -y \
gfortran \
libopenblas-dev \
liblapack-dev \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Set environment variables to make Python and Poetry play nice
ENV POETRY_VERSION=1.7.1 \
PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
EXPERIMENT_ID=$EXPERIMENT_ID \
RUN_ID=$RUN_ID
## Install poetry
RUN pip install "poetry==$POETRY_VERSION"
## copy project requirement files here to ensure they will be cached.
WORKDIR /app
COPY poetry.lock pyproject.toml ./
RUN poetry config virtualenvs.create false \
&& poetry install --no-interaction --no-dev --no-ansi --verbose \
&& poetry cache clear pypi --all
# Build our actual container now.
FROM python:3.11-slim
ENV POETRY_VERSION=1.7.1 \
PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
EXPERIMENT_ID=$EXPERIMENT_ID \
RUN_ID=$RUN_ID
# Copy all of the python files built in the Builder container into this smaller container.
COPY --from=Builder /usr/local/lib/python3.11 /usr/local/lib/python3.11
# Copy the model directory to the Docker image
COPY mlartifacts/542535033067401306/2ba405d6d3144db6a5cd237509e53ef8 /app/mlartifacts/542535033067401306/2ba405d6d3144db6a5cd237509e53ef8/
# Copy the blacklist and whitelist data
COPY data/blacklist.txt data/whitelist.txt /app/data/
## Copy Python files
COPY *.py .
COPY utils/ ./utils/
COPY .env .
EXPOSE 7070
CMD ["poetry", "run", "flask", "run", "--host=0.0.0.0"]
此方法适用于所有 Multi-Py 项目,因此您可以在那里查找示例。