開発者のためのDocker:イメージ、コンテナ、Compose

DevOps2026-10-07TryQuickToolBox

Dockerとコンテナについて聞いたことはあるけれど、いざ使ってみるとイメージ、コンテナ、ボリューム、Composeといった用語に圧倒されてしまう。あるいはすでにDockerを使っているけれど、イメージが巨大でビルドが遅く、複数サービスの管理が面倒に感じているかもしれない。このガイドはそんな混乱を解消します。開発者のためのDockerの要点を、コンテナ化アプリケーションを効率的に構築・実行・管理するために本当に必要な知識に絞って解説します。

なぜDockerなのか? 解決する課題

Docker以前、アプリのデプロイは特定のOSバージョン、ライブラリ、設定を正確に揃えることを意味していました。「私のマシンでは動く」がクリシェになったのは、それが真実だったからです。Dockerは、アプリケーションとその依存関係をコンテナと呼ばれる単一のポータブルな単位にパッケージ化することでこれを解決します。コンテナは軽量で分離されており、Dockerがインストールされたどこでも一貫して動作します。

イメージとコンテナ:核心的な違い

イメージは、アプリケーションコード、ランタイム、ライブラリ、設定を含む読み取り専用のテンプレートです。コンテナはイメージの実行インスタンスです。イメージをクラス、コンテナをオブジェクトと考えてください。同じイメージから複数のコンテナを実行でき、それぞれが他から分離されています。

イメージのビルド方法

イメージはDockerfileという命令を含むテキストファイルからビルドされます。以下はNode.jsアプリの最小例です:

FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]

各命令がレイヤーを作成します。レイヤーはキャッシュされるため、ソースコードだけを変更した場合、Dockerは依存関係のキャッシュされたレイヤーを再利用し、再ビルドが高速になります。

ビルドと実行

イメージをビルドし、コンテナを実行します:

docker build -t my-app .
docker run -p 3000:3000 my-app

-pフラグはホストのポート3000をコンテナのポート3000にマッピングします。

効率的なDockerイメージのベストプラクティス

大きなイメージはビルド、プッシュ、デプロイを遅くします。イメージをスリムに保つために以下のプラクティスに従ってください:

以下はGoアプリケーションのマルチステージDockerfileです:

# Build stage
FROM golang:1.21-alpine AS builder
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o /app/main .

# Final stage
FROM alpine:latest
COPY --from=builder /app/main /main
CMD ["/main"]

最終イメージにはコンパイル済みバイナリとAlpineのみが含まれ、Goツールチェーンは含まれません。

ボリュームによるデータ管理

コンテナは一時的です。削除されるとデータは失われます。ボリュームはコンテナのライフサイクル外でデータを永続化します。データベース、アップロード、再起動後も保持する必要がある状態に使用してください。

docker run -v my-data:/var/lib/postgresql/data postgres

これによりDockerが管理する名前付きボリュームmy-dataが作成されます。開発では、ソースコードをコンテナにバインドマウントしてライブリロードすることもできます:

docker run -v $(pwd):/app -p 3000:3000 my-app

Docker Compose:複数コンテナのオーケストレーション

実際のアプリケーションはしばしば複数のサービスを必要とします:Webサーバー、データベース、キャッシュ。それぞれをdocker runで起動するのは面倒でエラーが発生しやすいです。Docker Composeを使えば、単一のYAMLファイルでマルチコンテナアプリを定義して実行できます。

実践的なdocker-compose.yml

以下はPostgreSQLとRedisを備えたNode.jsアプリのComposeファイルです:

version: '3.8'
services:
  web:
    build: .
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgres://user:pass@db:5432/mydb
      - REDIS_URL=redis://cache:6379
    depends_on:
      - db
      - cache
  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
      POSTGRES_DB: mydb
    volumes:
      - postgres_data:/var/lib/postgresql/data
  cache:
    image: redis:7-alpine
volumes:
  postgres_data:

docker compose upを実行してすべてのサービスを起動します。Composeはデフォルトネットワークを作成するため、コンテナはサービス名(例:db、cache)で互いに到達できます。

よく使うComposeコマンド

Docker ComposeとKubernetesの使い分け

Docker Composeはローカル開発、テスト、小規模デプロイに最適です。Kubernetesは大規模な本番環境でクラスタ全体のコンテナをオーケストレーションするのに優れています。多くの開発者にとって、Composeは日常業務に十分であり、オートスケーリング、自己修復、高度なネットワーキングが必要になったときにKubernetesにステップアップできます。

機能Docker ComposeKubernetes
用途ローカル開発、小規模デプロイ本番クラスタ
複雑さ低高
スケーリング手動自動
学習曲線緩やか急峻

FAQ

イメージとコンテナの違いは何ですか?

イメージはアプリと依存関係を含む読み取り専用テンプレートです。コンテナはイメージの実行インスタンスです。1つのイメージから多数のコンテナを実行できます。

Dockerイメージのサイズを減らすには?

より小さなベースイメージ(Alpineなど)を使用し、マルチステージビルドを活用し、RUNコマンドをまとめ、.dockerignoreファイルで不要なファイルを除外します。

Docker Composeを本番環境で使えますか?

はい、小規模なデプロイでは可能です。より大規模で動的な環境では、KubernetesやDocker Swarmが適しています。

Dockerワークフローを最適化する準備はできましたか?コンテナ化されたWebサーバーをデバッグ・監視するには、Nginx Log Analyzerをチェックしてください。