Closed4
マルチステージビルドでDockerイメージサイズを小さく保つ
ピン留めされたアイテム
結論
マルチステージビルド[1]を活用することでDockerイメージをかなり小さく保つことが可能
今回の環境では以下の差異となった
通常(single stage)のDockerイメージ: 533MB
マルチステージビルドでのDockerイメージ:132MB
動機
bot動作環境に安いVPSを利用しているのでイメージサイズをできるだけ小さくしたい
Dockerfileのサンプル
サンプルはPython用のイメージを作成する想定で記述
まずは通常の書き方
FROM python:3.12-slim
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONBUFFERED=1 \
WORK_DIR=/app \
PATH="${PATH}:/opt/poetry/bin"
ARG POETRY_VIRTUALENVS_IN_PROJECT=false \
POETRY_NO_INTERACTION=1 \
POETRY_HOME=/opt/poetry \
POETRY_VERSION=1.8.3
WORKDIR ${WORK_DIR}
COPY pyproject.toml poetry.lock ./
RUN apt-get update \
&& apt-get install --no-install-recommends -y \
build-essential \
curl \
&& curl -sSL https://install.python-poetry.org | python3 - \
&& poetry config virtualenvs.create false \
&& poetry install --no-dev
RUN poetry export -f requirements.txt --output requirements.txt \
&& pip install --no-cache-dir -r requirements.txt
COPY main.py main.py
CMD ["python", "main.py"]
マルチステージビルド
Dockerfile内に複数のFROMを記述する形になる
FROM python:3.12-slim AS builder
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONBUFFERED=1 \
WORK_DIR=/app \
PATH="${PATH}:/opt/poetry/bin"
ARG POETRY_VIRTUALENVS_IN_PROJECT=false \
POETRY_NO_INTERACTION=1 \
POETRY_HOME=/opt/poetry \
POETRY_VERSION=1.8.3
WORKDIR ${WORK_DIR}
RUN apt-get update \
&& apt-get install --no-install-recommends -y \
build-essential \
curl \
&& curl -sSL https://install.python-poetry.org | python3 -
COPY pyproject.toml poetry.lock ./
RUN poetry export -f requirements.txt --output requirements.txt
FROM python:3.12-slim
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONBUFFERED=1 \
WORK_DIR=/app
# copy from builder stage
COPY --from=builder ${WORK_DIR}/requirements.txt ${WORK_DIR}/requirements.txt
WORKDIR ${WORK_DIR}
RUN pip install --no-cache-dir -r requirements.txt
COPY main.py main.py
CMD ["python", "main.py"]
イメージサイズの比較
準備
以下のような簡単なscriptを用意
import requests
res = requests.get("https://api.github.com")
print(res.status_code)
poetry環境を用意して以下のようなファイル構成に
.
├── Dockerfile_multi
├── Dockerfile_single
├── README.md
├── main.py
├── poetry.lock
└── pyproject.toml
比較
それぞれのイメージをビルド
$ docker build -t multi-stage-sample . -f ./Dockerfile_multi
$ docker build -t single-stage-sample . -f ./Dockerfile_single
比較
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
single-stage-sample latest xxxxxxxxxxxx 1 minutes ago 533MB
multi-stage-sample latest yyyyyyyyyyyy 1 minutes ago 132MB
このスクラップは4ヶ月前にクローズされました