Closed4

マルチステージビルドでDockerイメージサイズを小さく保つ

chamachama

動機

bot動作環境に安いVPSを利用しているのでイメージサイズをできるだけ小さくしたい

chamachama

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"]
chamachama

イメージサイズの比較

準備

以下のような簡単な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ヶ月前にクローズされました