Dockerビルド時間の改善: 外部ツールを使わないアプローチ
普段の業務で使用するDockerですが、ビルド時間がかかったりするケースもありますよね。
今回はDocker内の機能だけでビルド時間が早まる方法は以下のようなものかなと調べて考えてみました。
準備
まず、サンプルプロジェクトをセットアップしましょう。このプロジェクトは簡単なNode.jsアプリケーションです。
mkdir docker-optimization-demo
cd docker-optimization-demo
npm init -y
npm install express
`app.js`ファイルを作成し、以下の内容を追加します:
const express = require('express');
const app = express();
const port = 3000;
app.get('/', (req, res) => {
res.send('Hello Docker!');
});
app.listen(port, () => {
console.log(`App listening at http://localhost:${port}`);
});
1. .dockerignoreファイルの使用
`.dockerignore`ファイルを作成し、以下の内容を追加します:
.git
*.md
*.log
node_modules
test
効果測定:
ビルド前後のコンテキストサイズを比較します。
# Before
du -sh .
# After
du -sh . --exclude=node_modules --exclude=.git
2. レイヤーキャッシングの最適化
最適化前の`Dockerfile`:
FROM node:14
WORKDIR /app
COPY . .
RUN npm install
CMD ["node", "app.js"]
最適化後の`Dockerfile`:
FROM node:14
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
CMD ["node", "app.js"]
効果測定:
両方のDockerfileでビルドを実行し、時間を比較します。
time docker build -t app:before -f Dockerfile.before .
time docker build -t app:after -f Dockerfile.after .
3. マルチステージビルドの活用
`Dockerfile.multistage`を作成:
# ビルドステージ
FROM node:14 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
# 実行ステージ
FROM node:14-alpine
WORKDIR /app
COPY --from=builder /app .
CMD ["node", "app.js"]
効果測定:
イメージサイズと
ビルド時間を比較します。
docker build -t app:single -f Dockerfile.after .
docker build -t app:multi -f Dockerfile.multistage .
docker images | grep app
4. 軽量ベースイメージの選択
`Dockerfile.alpine`を作成:
FROM node:14-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
CMD ["node", "app.js"]
効果測定:
イメージサイズを比較します。
docker build -t app:regular -f Dockerfile.after .
docker build -t app:alpine -f Dockerfile.alpine .
docker images | grep app
5. RUN命令の最適化
複数のパッケージをインストールする場合の例:
FROM node:14-alpine
WORKDIR /app
# 最適化前
RUN apk update
RUN apk add python3
RUN apk add make
RUN apk add g++
# 最適化後
RUN apk update && apk add --no-cache \
python3 \
make \
g++
COPY package*.json ./
RUN npm install
COPY . .
CMD ["node", "app.js"]
効果測定:
ビルド時間を比較します。
6. ビルドキットの有効化
DOCKER_BUILDKIT=1 docker build -t app:buildkit .
効果測定:
通常のビルドとBuildKitを使用したビルドの時間を比較します。
time docker build -t app:normal .
time DOCKER_BUILDKIT=1 docker build -t app:buildkit .
トラブルシューティング
キャッシュが効かない場合:
`.dockerignore`ファイルを確認し、必要なファイルが除外されていないか確認する。
Dockerfileの順序を見直し、頻繁に変更されるファイルを後ろに配置する。
ビルドが遅い場合:
`docker build --progress=plain`を使用して詳細なビルドログを確認する。
ネットワーク接続を確認し、必要に応じてミラーサーバーを使用する。
イメージサイズが大きい場合:
`docker history <image>`を使用して、どのレイヤーが大きいかを特定する。
不要なファイルやパッケージを削除し、マルチステージビルドを検討する。
まとめ
これらの最適化手法を適用することで、Dockerのビルド時間を大幅に短縮し、開発効率を向上させることができます。プロジェクトの特性に応じて最適な手法を選択し、定期的にビルドプロセスを見直すことが重要です。
演習
提供されたサンプルプロジェクトを使用して、各最適化手法を順番に適用してください。
各ステップでビルド時間とイメージサイズを記録し、グラフ化してください。
あなたの実際のプロジェクトで同様の最適化を試み、結果を比較してください。