0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

個人的備忘録:Golangアプリのマルチステージビルドを活用した、マイグレーション対応の効率的なDockerfileについて解説してみた

0
Last updated at Posted at 2025-02-21

はじめに

GolangアプリケーションをDockerで運用する際、適切なDockerfileの設計はパフォーマンスやセキュリティに大きく影響します。

本記事では、マルチステージビルドを活用した効率的なDockerfile について解説し、コンテナサイズの削減や最適化のポイント を紹介します。

書こうと思ったきっかけ

GolangアプリケーションのDocker化を行う中で、ビルド環境の分離やコンテナサイズの最適化が重要 だと感じました。

特に、シンプルかつ軽量な構成を実現するためのポイント を整理し、他の開発者にも役立つ情報を共有したいと思い、本記事を書くことにしました。

実際に作成したDockerfileについて

実際のDockerfileについて

このDockerfileは、Golangアプリケーションを効率的にコンテナ化するためのものです。

FROM golang:1.23.5-alpine3.21 AS builder
WORKDIR /usr/src/app

# go.mod と go.sum を先にコピーし、依存関係をダウンロード
COPY go.mod go.sum ./
RUN go mod download

# アプリケーションのソースコードをコピー
COPY . .

# メインアプリケーションのビルド
RUN CGO_ENABLED=0 GOOS=linux go build -o server .

# マイグレーション用のバイナリを作成
RUN CGO_ENABLED=0 GOOS=linux go build -o migrate_app migrate/migrate.go

# 軽量なAlpineベースのイメージを使用
FROM alpine:3.21
WORKDIR /app

# 必要なバイナリをコピー
COPY --from=builder /usr/src/app/server .
COPY --from=builder /usr/src/app/migrate_app .

# マイグレーションを実行してからアプリケーションを起動
CMD ["/bin/sh", "-c", "/app/migrate_app && /app/server"]

マルチステージビルドを利用して、軽量なコンテナイメージを作成し、アプリケーションのパフォーマンスやセキュリティを向上させています。

1. ビルドステージ (builder)

まず、Golangの公式イメージ(Alpine Linuxベース)を使い、ビルド用の環境を構築します。

FROM golang:1.23.5-alpine3.21 AS builder
WORKDIR /usr/src/app
  • golang:1.23.5-alpine3.21 を使用して、軽量なビルド環境を用意
  • WORKDIR /usr/src/app で作業ディレクトリを /usr/src/app に設定

次に、依存関係のインストールを行います。

COPY go.mod go.sum ./
RUN go mod download
  • go.modgo.sum をコピーし、go mod download を実行
  • これにより、依存パッケージを事前にダウンロードし、キャッシュを活用して不要な再インストールを防ぐ

続いて、アプリケーションのソースコードをコピーし、ビルドを行います。

COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o server .
  • CGO_ENABLED=0 を設定して、C言語の依存を無効化し、静的リンクされたバイナリを作成
  • GOOS=linux を指定し、Linux向けのバイナリを生成
  • -o server で出力ファイル名を server に指定

また、データベースマイグレーション用のバイナリも作成します。

RUN CGO_ENABLED=0 GOOS=linux go build -o migrate_app migrate/migrate.go
  • migrate/migrate.go をビルドし、マイグレーション実行用の migrate_app バイナリを作成

この段階で、アプリケーション本体 (server) と、マイグレーションツール (migrate_app) の2つのバイナリが完成しました。

2. ランタイムステージ

アプリケーションの実行環境として、軽量な Alpine イメージを使います。

FROM alpine:3.21
WORKDIR /app
  • Alpine Linux 3.21 をベースイメージとして使用し、実行環境を構築
  • WORKDIR /app で作業ディレクトリを /app に設定

次に、ビルドステージで作成したバイナリをコピーします。

COPY --from=builder /usr/src/app/server .
COPY --from=builder /usr/src/app/migrate_app .
  • COPY --from=builder により、ビルド済みのバイナリ (servermigrate_app) を取得し、実行環境へコピー
  • Golangの開発環境 (約1GB) を削減し、数MBの軽量なコンテナを実現

最後に、マイグレーションを実行してからアプリケーションを起動するよう設定します。

CMD ["/bin/sh", "-c", "/app/migrate_app && /app/server"]
  • /app/migrate_app を実行し、データベースのマイグレーションを適用
  • マイグレーションが完了したら /app/server を起動

3. 最適化ポイント

このDockerfileには、パフォーマンス向上やイメージの軽量化を考慮した工夫がいくつか含まれています。

マルチステージビルドの活用

  • Golangのビルド環境 (golang:1.23.5-alpine3.21) はサイズが大きいため、本番環境に不要なものは含めず、軽量な Alpine イメージに最小限のバイナリのみを配置
  • これにより、最終的なコンテナサイズを数MB程度に抑えられる

依存関係のキャッシュを活用

  • go.mod を先にコピーし、go mod download を実行することで、ソースコードの変更がない限り、依存関係の再インストールを回避

CGO無効化 & 静的リンク

  • CGO_ENABLED=0 を設定することで、C言語の依存をなくし、シンプルなスタンドアロンバイナリを作成
  • GOOS=linux を指定することで、Linux環境でも動作するバイナリを生成

軽量なAlpineイメージの採用

  • Alpine Linux は、公式のGolangイメージよりも数百MBも軽量
  • 余分なパッケージがなく、セキュリティリスクも低減

まとめ

このDockerfileでは、Golangアプリケーションのビルドとデプロイの最適化を行っています。特に、以下のポイントが重要です。

  • マルチステージビルドにより、ビルド環境を分離し、最終的なコンテナを軽量化
  • go.mod を先にコピーし、キャッシュを活用してビルドの高速化
  • CGO_ENABLED=0 による静的バイナリ化で、余計なライブラリを削減
  • Alpine Linux を利用して、最小限のランタイム環境を構築

このような工夫を取り入れることで、効率的でセキュアなDockerコンテナを作成できます。

Golangアプリケーションをコンテナ化する際の参考にしてください。

0
2
1

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?