2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Docker】マルチステージビルドでイメージを軽量化する

Posted at

はじめに

この記事では、Dockerのマルチステージビルドを使って、軽量なイメージを作成する方法を解説します。

マルチステージビルドとは

マルチステージビルドとは、一つのDockerfileでビルドと実行のプロセスを分ける手法です。
これを使うことで、最終的なDockerイメージのサイズを縮小することが可能になります。

マルチステージビルドの仕組み

マルチステージビルドは、ビルドステージと実行ステージの2つのステージを作成します。

ビルドステージ

コンパイルや依存パッケージのインストールなどのビルドに必要な作業をここで行います。ビルドが完了すると、このステージは破棄されます。

実行ステージ

ビルドステージで生成された実行ファイルだけを実行ステージのイメージにコピーして実行します。
すでに実行ファイルが生成されているため、このステージでは軽量なイメージのみを使用することが可能になります。

マルチステージビルドの例

この例では、マルチステージビルドを活用し、最終的なDockerイメージのサイズを縮小しています。
/usr/appにはTypeScriptのソースコードがあると仮定します。

# ビルドステージ
FROM node AS build
WORKDIR /usr/app

COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

# 実行ステージ
FROM node
WORKDIR /usr/app
COPY package*.json ./
RUN npm install --production

COPY --from=build /usr/app/dist ./dist

EXPOSE 4000
CMD node dist/src/index.js

上記例では、
① ビルドステージにて/usr/appの内容をビルド
② ①でビルドされた./usr/app/distのファイルのみをコピーし実行
のマルチステージによる処理が行われています。

--from=buildbuildは、ビルドステージにてFROMで指定したエイリアスです。
実行ステージの--from=buildにて、ビルドしたイメージを使用する指示を行なっています。
このbuild部分は好きな名称に設定が可能です。

エイリアスを指定しない場合は、--from=buildの代わりに--from=0のようにステージ番号で参照することも可能です。

比較例

実際に上記のDockerfileと、マルチステージにしていない(シングルステージの)Dockerfileでのイメージのサイズを比較します。

以下のようなdependencieswebDependenciesを使用します。

{
// ...省略
  "dependencies": {
    "express": "^5.1.0"
  },
  "devDependencies": {
    "@types/express": "^5.0.3",
    "@types/node": "^24.2.1",
    "babel-loader": "^10.0.0",
    "cypress": "^14.5.4",
    "eslint": "^9.33.0",
    "jest": "^30.0.5",
    "typescript": "^5.9.2",
    "webpack": "^5.101.1"
  }
}

マルチステージビルドのDockerfileは先ほどの例のものを使用し、シングルステージビルドのDockerfileは以下を使用します。

FROM node
WORKDIR /usr/app

COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
RUN npm install --production

EXPOSE 4000
CMD node dist/src/index.js

両者をビルドすると、以下の結果となりました。

シングルステージ   1.89GB
マルチステージ    1.14GB

マルチステージの方が0.75GB小さいと確認できます。

これは、シングルステージのイメージには、ビルドに必要な開発用の依存関係やツールがすべて含まれていますが、マルチステージビルドでは、最終イメージからこれらが排除されているため、サイズが大幅に削減されているためです。

おわりに

このように、マルチステージビルドは、ビルド環境と実行環境を分離することで、最終的なDockerイメージを大幅に軽量化します。
ビルドに必要なツールや開発用の依存関係を最終イメージから除外することで、デプロイや管理がより効率的になります。

参考資料

2
1
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
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?