💨

開発環境のDockerのビルド時間が約50倍早くなった

に公開

私たちのチームでは、開発時に devcontainer を利用することで、開発環境構築の手間を大幅に軽減しています。
しかし、devcontainer 起動時に発生する Docker イメージのビルドに、長いときには 8 分以上かかってしまい、毎朝のちょっとしたストレスになっていました。

この記事では、このビルド時間を わずか 9 秒程度 に短縮した対応についてご紹介します。


前提

今回の改善は、開発環境用の Dockerfile に対して実施したものです。
本番環境用には別途 Dockerfile が存在しており、開発環境用とは構成・目的が明確に分離されていることが前提です。

規模感

対象となるプロジェクトは Ruby on Rails で構築されており、rails stats によるコード行数は以下の通りです:

アプリケーションコード:18,868行

テストコード:31,203行

課題

開発環境用の Dockerfile のビルドに、長いときで 510 秒(約 8 分半)かかっていました。

対応

Rails プロジェクトではよく見られる形の Dockerfile になっており、Gemfile および Gemfile.lock をコピー後、bundle install を実行し、その後ソースコード全体を COPY する構成でした。

元のDockerfile(抜粋)

ARG RUBY_VERSION

ENV LANG C.UTF-8

FROM ruby:${RUBY_VERSION}

ARG USERNAME=devuser
ARG USER_UID=1000
ARG USER_GID=$USER_UID

ENV TZ=Asia/Tokyo
ENV APP_HOME=/usr/src/app
ENV RUBY_YJIT_ENABLE=1

RUN mkdir -p $APP_HOME
RUN apt-get update && apt-get install -y libvips sudo

RUN groupadd --gid $USER_GID $USERNAME \
    && useradd -s /bin/bash --uid $USER_UID --gid $USER_GID -m $USERNAME \
    && echo "$USERNAME ALL=NOPASSWD: ALL" > /etc/sudoers.d/$USERNAME\
    && chmod 0440 /etc/sudoers.d/$USERNAME

WORKDIR $APP_HOME

COPY Gemfile Gemfile.lock ${APP_HOME}/

RUN gem install bundler --no-document && \
  bundle config jobs $(nproc) && \
  bundle config build.puma "--with-cflags='-D PUMA_QUERY_STRING_MAX_LENGTH=30720'" && \
  bundle install

COPY . $APP_HOME
USER $USERNAME

不要なステップの削除

開発環境ではソースコードをホスト側から Volume マウントして使用しているため、
COPY . . や bundle install はイメージビルド時に行う必要がないと判断し、これらのステップを削除しました。

対応後のDacokerfile(抜粋)

ARG RUBY_VERSION

ENV LANG C.UTF-8

FROM ruby:${RUBY_VERSION}

ARG USERNAME=devuser
ARG USER_UID=1000
ARG USER_GID=$USER_UID

ENV TZ=Asia/Tokyo
ENV APP_HOME=/usr/src/app
ENV RUBY_YJIT_ENABLE=1

RUN mkdir -p $APP_HOME
RUN apt-get update && apt-get install -y libvips sudo

RUN groupadd --gid $USER_GID $USERNAME \
    && useradd -s /bin/bash --uid $USER_UID --gid $USER_GID -m $USERNAME \
    && echo "$USERNAME ALL=NOPASSWD: ALL" > /etc/sudoers.d/$USERNAME\
    && chmod 0440 /etc/sudoers.d/$USERNAME

WORKDIR $APP_HOME

USER $USERNAME

結果

ビルド時間を定量的に比較するため、どちらも --no-cache オプションをつけて計測しています

状態 ビルド時間 コマンド
対応前 510.6秒 docker build --no-cache
対応後 8.9秒 docker build --no-cache

まとめ

Docker を使った開発環境では、Volume マウントを前提とする構成においては、ビルド時にソースコードのコピーや依存インストールを行わないことで、大幅な時間短縮が可能です。

普段あまり意識しない開発用 Dockerfile でも、少し見直すだけで日々の開発体験が大きく改善されることがあります。
この機会に、皆さんの環境も一度見直してみてはいかがでしょうか。

あしたのチーム Tech Blog

Discussion