6
10

dockerfileのダイエット

Last updated at Posted at 2024-05-08

はじめに

他社案件で、docker環境を構築されてましたが、イメージ容量が大きかったので、ダイエットした際の備忘録となります

前提

ruby:3.3.0
rails:7.1.3
css , js: jsbundling-rails + cssbundling-rails 構成

作業内容

初期状態

FROM ruby:3.3.0

# 必要パッケージ
RUN apt-get update \
  && apt-get install -y curl

# install node
RUN curl -fsSL https://deb.nodesource.com/setup_21.x | bash - \
  && apt-get install -y nodejs \
  && apt-get install -y ffmpeg \
  && apt-get install -y tzdata

# install yarn
RUN npm install --global yarn

ENV TZ Asia/Tokyo

# コンテナの作業ディレクトリ
WORKDIR /workspaces

# コンテナの作業ディレクトリにコピー
COPY Gemfile /workspaces
COPY Gemfile.lock /workspaces

# 依存関係をインストール
RUN gem update --system \
  && bundle install -j 4

# yarnインストール
COPY package.json /workspaces
RUN yarn install

COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]

EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0" "-p" "3000"]
$ docker images
REPOSITORY       TAG       IMAGE ID       CREATED      SIZE
workspaces-web   latest    6030e6770b2c   6 days ago   2.32GB

初期の状態ですが、容量が2.32GB!

bullseyeにイメージ変更

FROM public.ecr.aws/docker/library/ruby:3.3.0-bullseye

# 必要パッケージ
RUN apt-get update \
  && apt-get install -y curl

# install node
RUN curl -fsSL https://deb.nodesource.com/setup_21.x | bash - \
  && apt-get install -y nodejs \
  && apt-get install -y ffmpeg \
  && apt-get install -y tzdata

# install yarn
RUN npm install --global yarn

ENV TZ Asia/Tokyo

# コンテナの作業ディレクトリ
WORKDIR /workspaces

# コンテナの作業ディレクトリにコピー
COPY Gemfile /workspaces
COPY Gemfile.lock /workspaces

# 依存関係をインストール
RUN gem update --system \
  && bundle install -j 4

# yarnインストール
COPY package.json /workspaces
RUN yarn install

COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]

EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0" "-p" "3000"]
$ docker images
REPOSITORY       TAG       IMAGE ID       CREATED              SIZE
workspaces-web   latest    9f65c361d72a   11 seconds ago       2.13GB
<none>           <none>    6030e6770b2c   About an hour ago    2.32GB

約200M削減!

slimにイメージ変更

FROM public.ecr.aws/docker/library/ruby:3.3.0-slim

# 必要パッケージ
RUN apt-get update -qq && \
  apt-get install --no-install-recommends -y curl build-essential default-libmysqlclient-dev

# install node
RUN curl -fsSL https://deb.nodesource.com/setup_21.x | bash - \
  && apt-get install -y nodejs \
  && apt-get install -y ffmpeg \
  && apt-get install -y tzdata

# install yarn
RUN npm install --global yarn

ENV TZ Asia/Tokyo

# コンテナの作業ディレクトリ
WORKDIR /workspaces

# コンテナの作業ディレクトリにコピー
COPY Gemfile /workspaces
COPY Gemfile.lock /workspaces

# 依存関係をインストール
RUN gem update --system \
  && bundle install -j 4

# yarnインストール
COPY package.json /workspaces
RUN yarn install

COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]

EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0" "-p" "3000"]
$ docker images
REPOSITORY       TAG       IMAGE ID       CREATED              SIZE
workspaces-web   latest    351fa94c4348   17 seconds ago       1.89GB
<none>           <none>    9f65c361d72a   About an hour ago    2.13GB
<none>           <none>    6030e6770b2c   About an hour ago    2.32GB

さらに約200M削減!

nodeをコピー(マルチステージビルド)

FROM public.ecr.aws/docker/library/node:21.7-slim as node
FROM public.ecr.aws/docker/library/ruby:3.3.0-slim

# 必要パッケージ
RUN apt-get update -qq \
  && apt-get install --no-install-recommends -y curl build-essential default-libmysqlclient-dev \
  && rm -rf /var/lib/apt/lists/*

# install node
COPY --from=node /opt/yarn-* /opt/yarn
COPY --from=node /usr/local/bin/node /usr/local/bin/
COPY --from=node /usr/local/lib/node_modules/ /usr/local/lib/node_modules/
RUN ln -fs /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm \
  && ln -fs /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npx \
  && ln -fs /opt/yarn/bin/yarn /usr/local/bin/yarn \
  && ln -fs /opt/yarn/bin/yarnpkg /usr/local/bin/yarnpkg

ENV TZ Asia/Tokyo

# コンテナの作業ディレクトリ
WORKDIR /workspaces

# コンテナの作業ディレクトリにコピー
COPY Gemfile /workspaces
COPY Gemfile.lock /workspaces

# 依存関係をインストール
RUN gem update --system \
  && bundle install -j 4

# yarnインストール
COPY package.json /workspaces
RUN yarn install

COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]

EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0" "-p" "3000"]
$ docker images
REPOSITORY       TAG        IMAGE ID       CREATED             SIZE
workspaces-web   latest     66ae3fe16408   11 seconds ago      1.2GB
<none>           <none>     351fa94c4348   13 minutes ago      1.89GB
<none>           <none>     9f65c361d72a   47 minutes ago      2.13GB
<none>           <none>     6030e6770b2c   About an hour ago   2.32GB

約700M削減!

gemを切り分けコピー(マルチステージビルド)

FROM public.ecr.aws/docker/library/node:21.7-slim AS node
FROM public.ecr.aws/docker/library/ruby:3.3.0-slim as base

ENV TZ Asia/Tokyo

# 必要パッケージ
RUN apt-get update -qq \
  && apt-get install --no-install-recommends -y curl build-essential default-libmysqlclient-dev \
  && rm -rf /var/lib/apt/lists/*

# コンテナの作業ディレクトリ
WORKDIR /workspaces

FROM base as bundler

COPY Gemfile Gemfile.lock /workspaces

# 依存関係をインストール
RUN gem update --system \
  && bundle install -j 4

FROM base as dev
# install node
COPY --from=node /opt/yarn-* /opt/yarn
COPY --from=node /usr/local/bin/node /usr/local/bin/
COPY --from=node /usr/local/lib/node_modules/ /usr/local/lib/node_modules/
RUN ln -fs /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm \
  && ln -fs /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npx \
  && ln -fs /opt/yarn/bin/yarn /usr/local/bin/yarn \
  && ln -fs /opt/yarn/bin/yarnpkg /usr/local/bin/yarnpkg

# yarnインストール
COPY package.json /workspaces
RUN yarn install

COPY --from=bundler /usr/local/bundle /usr/local/bundle
COPY . .

# entrypoint
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]

EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0" "-p" "3000"]
$ docker images
REPOSITORY       TAG        IMAGE ID       CREATED             SIZE
workspaces-web   latest     8da8f4c14f78   2 minutes ago       1.19GB
<none>           <none>     66ae3fe16408   About an hour ago   1.2GB
<none>           <none>     351fa94c4348   About an hour ago   1.89GB
<none>           <none>     9f65c361d72a   About an hour ago   2.13GB
<none>           <none>     6030e6770b2c   About an hour ago   2.32GB

約10M削減

node_moduleを切り分けコピー(マルチステージビルド)

FROM public.ecr.aws/docker/library/node:21.7-slim AS node
FROM public.ecr.aws/docker/library/ruby:3.3.0-slim as base
ENV TZ Asia/Tokyo
# 必要パッケージ
RUN apt-get update -qq \
  && apt-get install --no-install-recommends -y curl build-essential default-libmysqlclient-dev \
  && rm -rf /var/lib/apt/lists/*
# コンテナの作業ディレクトリ
WORKDIR /workspaces

FROM base as bundler
COPY Gemfile Gemfile.lock /workspaces
RUN gem update --system \
  && bundle install -j 4

FROM base as yarn-installer
# install node
COPY --from=node /opt/yarn-* /opt/yarn
COPY --from=node /usr/local/bin/node /usr/local/bin/
COPY --from=node /usr/local/lib/node_modules/ /usr/local/lib/node_modules/
RUN ln -fs /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm \
  && ln -fs /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npx \
  && ln -fs /opt/yarn/bin/yarn /usr/local/bin/yarn \
  && ln -fs /opt/yarn/bin/yarnpkg /usr/local/bin/yarnpkg
COPY package.json yarn.lock /workspaces
RUN yarn install

FROM base as development
COPY --from=node /opt/yarn-* /opt/yarn
COPY --from=node /usr/local/bin/node /usr/local/bin/
COPY --from=node /usr/local/lib/node_modules/ /usr/local/lib/node_modules/
RUN ln -fs /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm \
  && ln -fs /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npx \
  && ln -fs /opt/yarn/bin/yarn /usr/local/bin/yarn \
  && ln -fs /opt/yarn/bin/yarnpkg /usr/local/bin/yarnpkg
COPY --from=bundler /usr/local/bundle /usr/local/bundle
COPY --from=yarn-installer /workspaces/node_modules node_modules
COPY . .

# entrypoint
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]

EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0" "-p" "3000"]
$ docker images
REPOSITORY       TAG        IMAGE ID       CREATED             SIZE
workspaces-web   latest     3dc2bec63248   8 minutes ago       820MB
<none>           <none>     8da8f4c14f78   About an hour ago   1.19GB
<none>           <none>     66ae3fe16408   About an hour ago   1.2GB
<none>           <none>     351fa94c4348   About an hour ago   1.89GB
<none>           <none>     9f65c361d72a   About an hour ago   2.13GB
<none>           <none>     6030e6770b2c   About an hour ago   2.32GB

約300M削減!

まとめ

状態 容量
初期状態 2.32GB
bullseyeにイメージ変更 2.13GB
slimにイメージ変更 1.89GB
nodeをコピー(マルチステージビルド) 1.2GB
gemを切り分けコピー(マルチステージビルド) 1.19GB
node_moduleを切り分けコピー(マルチステージビルド) 820MB

さいごに

イメージ変更でも結構容量が減ることが分かり、今後は注意が必要と感じました。
また、(当たり前だが)マルチステージビルドだとさらに削れることが再認識できました。
今回の件で見ると、node関係が容量食ってるのが分かったので、ここも注意が必要です。
今回は、初期状態から半分以下に容量削減ができたので、良しとします。
他にもこんな方法もあるよ!という方がいらっしゃれば、ご教授頂けますと幸いです。

6
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
10