Back

Docker イメージとコンテナの初心者ガイド

Docker イメージとコンテナの初心者ガイド

フロントエンドチームに参加したばかりで、周りのメンバーが「コンテナを起動する」や「イメージをプルする」といった話をしています。あなたの React アプリはローカルマシンでは完璧に動作しますが、デプロイは謎に包まれているように感じます。Docker はまさにこの問題を解決します。そして、Docker イメージの基本を理解することは、思っているよりもシンプルです。

このガイドでは、Docker イメージとコンテナが実際に何であるか、それらがどのように関連しているか、そしてローカル開発、テスト、シンプルなデプロイのためにフロントエンドワークフローでどのように使用するかを説明します。

重要なポイント

  • Docker イメージは読み取り専用の設計図であり、コンテナはそのイメージの実行中のインスタンスです。
  • 予測可能で再現性のあるビルドのために、latest の代わりに node:20-alpine のような明示的なタグを使用しましょう。
  • マルチステージビルドは、本番環境のイメージを小さく安全に保ちます。
  • 永続的なデータをコンテナ内に保存しないでください。代わりにボリュームを使用しましょう。
  • コンテナを非 root ユーザーとして実行し、定期的にイメージの脆弱性をスキャンしましょう。

Docker イメージとコンテナとは?

Docker イメージは、アプリケーションを実行するために必要なすべてを含む読み取り専用のパッケージです:コード、ランタイム、ライブラリ、設定。オブジェクト指向プログラミングのクラスのようなものと考えてください。構造を定義する設計図ですが、それ自体では何も実行しません。

コンテナは、そのイメージの実行中のインスタンスです。docker run を実行すると、Docker はイメージから分離された環境を作成し、そこでアプリケーションが実際に実行されます。同じイメージから複数のコンテナを起動でき、それぞれが独立して動作します。

この Docker イメージとコンテナの違いは重要です:イメージはディスクに保存された静的なテンプレートであり、コンテナは独自のファイルシステムとネットワークを持つ実行中のプロセスです。

Docker イメージは OCI(Open Container Initiative)仕様に従っているため、Docker だけでなく、さまざまなコンテナランタイムで動作します。この標準化により、イメージの移植性が保証されます。

レジストリとタグの理解

イメージはレジストリに保存されます。最も一般的なパブリックレジストリは Docker Hub です。node:20-alpine のようなイメージを参照する場合、リポジトリ(node)とタグ(20-alpine)を指定しています。

初心者がつまずくポイント:latest タグは魔法ではありません。自動的に最新バージョンを指すわけではありません。これは単なるデフォルトのタグであり、イメージのメンテナーが更新する場合もしない場合もあります。予測可能なビルドのために、常に node:20-alpine のような明示的なタグを使用しましょう。

最初のコンテナを実行する

公式の Node.js イメージを使用してシンプルなコンテナを実行してみましょう:

docker run -it --rm node:20-alpine node -e "console.log('Hello from Docker!')"

-it フラグは、ターミナルを使用したインタラクティブモードを有効にします。--rm フラグは、コンテナが終了したときに自動的に削除します。

より実用的な例として、開発サーバーを実行できます。まず、フロントエンドコードを含むプロジェクトディレクトリを作成し、次に:

docker run -d -p 3000:3000 -v $(pwd):/app -w /app node:20-alpine sh -c "npm install && npm run dev"

-d フラグはコンテナをバックグラウンドで実行します。-p 3000:3000 はコンテナ内のポート 3000 をマシンのポート 3000 にマッピングします。-v フラグは現在のディレクトリをコンテナにマウントし、-w は作業ディレクトリを設定します。

Dockerfile でカスタムイメージをビルドする

実際のプロジェクトでは、カスタムイメージを作成します。React アプリケーション用の Dockerfile は次のようになります:

FROM node:20-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
EXPOSE 80

これはマルチステージビルドを示しています。これは Docker のベストプラクティスの重要な要素です。最初のステージでアプリをビルドし、2番目のステージで本番ファイルのみを最小限の nginx イメージにコピーします。最終的なイメージは小さく安全に保たれます。

ビルドして実行します:

docker build -t my-frontend-app .
docker run -d -p 8080:80 my-frontend-app

Docker ボリュームと永続化

コンテナは一時的なものです。停止すると、内部に書き込まれたデータは消えます。ローカル開発では、バインドマウントを使用してソースコードを同期します:

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

永続化が必要なデータ(データベースファイルなど)には、名前付きボリュームを使用します:

docker volume create app-data
docker run -v app-data:/data my-app

Docker ボリュームと永続化の理解は不可欠です:重要なデータをコンテナのファイルシステム内だけに保存しないでください。

Docker セキュリティの基本

いくつかのプラクティスでコンテナをより安全に保ちます:

非 root として実行する。 Dockerfile にユーザーを追加します:

RUN adduser -D appuser
USER appuser

最小限のベースイメージを使用する。 Alpine ベースのイメージは、完全なディストリビューションよりも脆弱性が少なくなります。

定期的にイメージをスキャンする。 Docker ScoutTrivy などのツールは、既知の脆弱性を特定します。

シークレットをイメージに組み込まない。 環境変数やシークレット管理ツールで認証情報を処理します。ハードコーディングすると、イメージレイヤーに残るセキュリティリスクが生じます。

Compose でマルチコンテナセットアップを簡素化する

フロントエンドがローカルでバックエンド API とデータベースを必要とする場合、Docker Compose がすべてをオーケストレーションします:

services:
  frontend:
    build: ./frontend
    ports:
      - "3000:3000"
  api:
    build: ./api
    ports:
      - "4000:4000"

docker compose up を実行すると、両方のサービスが一緒に起動します。docker compose down を使用してすべてのコンテナを停止して削除します。

まとめ

Docker イメージは設計図であり、コンテナは実行中のインスタンスです。マルチステージビルドでイメージを小さく保ち、latest の代わりに明示的なタグを使用し、ボリュームを使用してコンテナから状態を分離し、セキュリティ更新をキャッチするために定期的にイメージを再ビルドしましょう。これらの基本は、開発環境を実行する場合でも、シンプルなフロントエンドアプリケーションをデプロイする場合でも役立ちます。

よくある質問

Docker イメージは、アプリケーションコード、依存関係、設定を含む読み取り専用のテンプレートです。コンテナは、そのイメージの実行中のインスタンスです。同じイメージから複数のコンテナを作成でき、それぞれが独自の分離されたファイルシステムとネットワークで独立して実行されます。

latest タグは自動的に最新バージョンに更新されるわけではありません。これは単なるデフォルトのタグであり、メンテナーが最新の状態に保つ場合もしない場合もあります。node:20-alpine のような明示的なバージョンタグを使用することで、再現性のあるビルドが保証され、イメージが更新されたときの予期しない破壊的変更を防ぐことができます。

Docker ボリュームを使用して、コンテナのファイルシステムの外部にデータを永続化します。名前付きボリュームは Docker が管理する場所にデータを保存し、バインドマウントはホストマシン上の特定のディレクトリにリンクします。重要なデータをコンテナの内部ファイルシステムに依存しないでください。

マルチステージビルドでは、アプリケーションのビルドに1つのイメージを使用し、実行には別の小さなイメージを使用できます。これにより、ビルドツールや依存関係を除外することで本番イメージを軽量に保ち、イメージサイズと潜在的なセキュリティ脆弱性の両方を削減します。

Gain control over your UX

See how users are using your site as if you were sitting next to them, learn and iterate faster with OpenReplay. — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay