はじめに
他社案件で、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関係が容量食ってるのが分かったので、ここも注意が必要です。
今回は、初期状態から半分以下に容量削減ができたので、良しとします。
他にもこんな方法もあるよ!という方がいらっしゃれば、ご教授頂けますと幸いです。