開発者のためのDocker:イメージ、コンテナ、Compose
Dockerについて聞いたことがあり、開発ワークフローを簡素化できることはご存知かもしれません。しかし、コンテナが初めての場合、用語やコマンドが多くて戸惑うこともあるでしょう。このガイドでは、雑音を取り除き、Dockerイメージ、コンテナ、Composeを実践的に理解できるようにします。今日から効果的に使い始められるようになります。
Dockerとは何か、なぜ気にするべきか?
Dockerは、アプリケーションとその依存関係をコンテナと呼ばれる標準化された単位にパッケージ化するプラットフォームです。コンテナは軽量でポータブル、そして互いに隔離されているため、ノートパソコン、同僚のマシン、本番サーバーで一貫してアプリを実行できます。
主な利点は? 「私のマシンでは動く」 という問題が過去のものになります。Dockerは、コードが実行される環境がどこでも同一であることを保証します。
イメージとコンテナ:構成要素
始める前に、イメージとコンテナの違いを理解する必要があります。
- イメージ:アプリケーションコード、ランタイム、ライブラリ、依存関係を含む読み取り専用のテンプレート。スナップショットや設計図のようなものだと考えてください。
- コンテナ:イメージの実行可能なインスタンス。コンテナを起動、停止、移動、削除できます。同じイメージから複数のコンテナを実行できます。
要するに、イメージはレシピであり、コンテナはそれから調理する料理です。
開発者向け必須Dockerコマンド
最もよく使用するコマンドは次のとおりです。
docker pull <image>– Docker Hubなどのレジストリからイメージをダウンロードします。docker images– ローカルのすべてのイメージを一覧表示します。docker run <image>– イメージからコンテナを作成して起動します。docker ps– 実行中のコンテナを一覧表示します。停止したコンテナを含むすべてのコンテナを表示するには-aを追加します。docker stop <container>– 実行中のコンテナを正常に停止します。docker rm <container>– 停止したコンテナを削除します。docker rmi <image>– イメージを削除します。docker exec -it <container> bash– 実行中のコンテナ内で対話型シェルを開きます。
たとえば、シンプルなNginx Webサーバーを実行するには:
docker run -d -p 8080:80 nginx
これはnginxイメージを(まだ存在しない場合は)取得し、デタッチモード(-d)でコンテナを起動し、ホストのポート8080をコンテナのポート80にマップします(-p 8080:80)。
Dockerfileで独自のイメージをビルドする
アプリケーションをパッケージ化するには、指示を含むテキストファイルDockerfileを作成します。以下はNode.jsアプリの簡単な例です:
# 公式のNode.jsランタイムを親イメージとして使用
FROM node:18-alpine
# 作業ディレクトリを設定
WORKDIR /usr/src/app
# package.jsonをコピーして依存関係をインストール
COPY package*.json ./
RUN npm install
# 残りのアプリケーションコードをコピー
COPY . .
# アプリが実行されるポートを公開
EXPOSE 3000
# アプリを実行するコマンドを定義
CMD ["node", "app.js"]
次のコマンドでイメージをビルドします:
docker build -t my-node-app .
そして実行します:
docker run -p 3000:3000 my-node-app
Docker Composeでマルチコンテナアプリを簡素化する
実際のアプリケーションでは、Webサーバー、データベース、キャッシュなど、複数のサービスが必要になることがよくあります。それらをdocker runで個別に管理するのは面倒になります。Docker Composeを使用すると、YAMLファイルでマルチコンテナアプリケーションを定義して実行できます。
docker-compose.ymlファイルを作成します:
version: '3.8'
services:
web:
build: .
ports:
- "3000:3000"
depends_on:
- db
db:
image: postgres:15
environment:
POSTGRES_PASSWORD: example
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:
そしてすべてを起動します:
docker compose up -d
Composeはネットワーキング、ボリューム、依存関係を処理します。コンテナ、ネットワーク、ボリュームを停止して削除するには、docker compose downを実行します。
開発におけるDockerのベストプラクティス
- .dockerignoreを使用する:不要なファイル(
node_modulesなど)をビルドコンテキストから除外してビルドを高速化します。 - マルチステージビルドを活用する:ビルド時の依存関係とランタイムを分離して、最終イメージを小さく保ちます。
- バージョンを固定する:再現性のために正確なイメージタグ(例:
node:18.16.0-alpine)を指定します。 - 非rootで実行する:Dockerfileでユーザーを作成し、
USERで切り替えてセキュリティを向上させます。 - 永続データにはボリュームを使用する:データベースやその他のステートフルサービスは、コンテナ内ではなくボリュームにデータを保存する必要があります。
よくある落とし穴と回避方法
- 肥大化したイメージ:最小限のベースイメージ(Alpineなど)から始め、パッケージキャッシュをクリーンアップします。
- ポートの競合:ホストポートがすでに使用されていないことを確認します。
docker psで確認します。 - ログを無視する:問題をデバッグするには
docker logs <container>を使用します。 - ローカル開発でComposeを使用しない:シンプルなアプリでもComposeの宣言的なセットアップの恩恵を受けます。
FAQ
Dockerイメージとコンテナの違いは何ですか?
イメージはアプリケーションとその環境を定義する読み取り専用のテンプレートです。コンテナはそのイメージの実行インスタンスです。1つのイメージから多数のコンテナを作成できます。
単一コンテナアプリにDocker Composeは必要ですか?
必ずしも必要ではありません。シンプルなアプリではdocker runで十分です。ただし、Composeを使用すると、1つのサービスでも環境変数、ボリューム、ネットワーキングを簡単に管理でき、後でのスケーリングも簡素化されます。
Dockerでデータを永続化するにはどうすればよいですか?
ボリュームを使用します。ボリュームはコンテナのファイルシステムの外部に保存され、コンテナが削除されても持続します。Composeでは、ボリュームを定義し、コンテナ内のパスにマウントします(例:volumes: - mydata:/var/lib/data)。
Dockerワークフローを最適化する準備はできましたか?コンテナログを分析する必要がある場合は、Nginx Log Analyzerを試して、ログデータを迅速に解析および視覚化してください。コンテナ化されたWebサーバーのデバッグに最適です。