Docker と Docker Compose 完全ガイド:コマンドとベストプラクティス
Docker と Docker Compose 完全ガイド:コマンドとベストプラクティス
Docker の基本概念
Dockerは、アプリとその依存関係をコンテナにパッケージ化するツールです。「私の環境では動くけど」という問題を、丸ごと1つの移植可能なユニットに押し込むことで解決します。
3つの概念を押さえれば、あとのコマンドは全部その周辺の話です。イメージはコンテナのテンプレートで、コード、ランタイム、ライブラリ、設定が全部入っています。コンテナはイメージを実際に動かしたインスタンスです。Docker Hubは、イメージを検索・共有するための公式サービスです。
Docker CLI コマンド(基本)
よく使うコマンドをまとめました。docker stopがSIGTERMを送って安全にシャットダウンしてくれる、という点だけ覚えておけば十分です。
| タスク | CLI コマンド | 説明 |
|---|---|---|
| イメージ | ||
| イメージ構築 | docker build -t <image_name> . | 現在ディレクトリの Dockerfile からイメージを構築。 |
| キャッシュ無し構築 | docker build -t <image_name> . --no-cache | キャッシュを使用せず強制的に再構築。 |
| イメージ一覧 | docker images | すべてのローカルイメージを表示。 |
| イメージ削除 | docker rmi <image_name> | ローカルイメージを削除。 |
| 未使用イメージ削除 | docker image prune | 未使用のすべてのイメージを削除。 |
| Docker Hub へ公開 | docker push <user>/<image_name> | イメージを Docker Hub へアップロード。 |
| コンテナ | ||
| コンテナ実行(名前付き) | docker run --name <container_name> <image_name> | イメージからコンテナを作成・実行。 |
| バックグラウンド実行 | docker run -d <image_name> | 分離モード(バックグラウンド)でコンテナ実行。 |
| ポート公開付き実行 | docker run -p <host_port>:<container_port> <image_name> | コンテナポートをホストへマッピング。 |
| コンテナ一覧(実行中) | docker ps | 現在実行中のコンテナを表示。 |
| すべてのコンテナ一覧 | docker ps --all | 状態に関わらずすべてのコンテナを表示。 |
| 開始/停止/再起動 | docker start|stop|restart <container_name> | 既存コンテナの開始または停止。docker stop は SIGTERM シグナルを送り優雅にシャットダウン。 |
| コンテナ削除 | docker rm <container_name> | 停止したコンテナを削除。 |
| コンテナ内に入る | docker exec -it <container_name> sh | 実行中のコンテナ内にインタラクティブシェルを開く。 |
| ログ表示 | docker logs -f <container_name> | コンテナログを表示・追跡。 |
| コンテナ検査 | docker inspect <container_name> | コンテナ詳細を表示(通常 JSON 形式)。 |
| リソース監視 | docker stats | ランタイムリソース使用統計を表示。 |
高度な Docker:イメージとセキュリティのベストプラクティス
マルチステージビルド
マルチステージビルドを使うと、開発に必要なツールを本番イメージに含めずに済みます。出来上がるイメージが小さく、攻撃面も減る。実務では必須のテクニックだと思います。
やり方は複数のFROM命令を使うだけです。各FROMが新しいステージを開始します。COPY --from=<stage>で前のステージから成果物だけをコピーして、FROM <image> AS <NAME>でステージに名前を付けておくと参照しやすいです。たとえばCOPY --from=build /bin/hello /bin/hello。
デバッグが必要なときはdocker build --target <stage> -t hello .で特定ステージまでのビルドに留められます。BuildKitが有効なら、ターゲットに必要なステージだけ処理されるので速いです。
イメージとコンテナのセキュリティ
セキュリティは「攻撃面を減らす」積み重ねです。ここに挙げる項目は、どれか一つが銀弾というわけではありませんが、全部やればかなり堅くなります。
まずベースイメージ。公式の検証済みイメージを使い、最小ベースから始めて必要な依存だけ追加する。脆弱性はTrivyやDocker Scoutで定期的にスキャンします。
実行ユーザーはroot以外で。コンテナは可能な限り読み取り専用ファイルシステムで動かす。イメージの改ざん防止にはDocker Content Trust (DCT)を有効にして、署名済みイメージだけを使うようにします。
Docker Compose(マルチコンテナアプリケーション管理)
Docker Composeは、docker-compose.yml1つで複数コンテナを定義・起動できるツールです。Webアプリ、データベース、キャッシュなど、協調動作するサービス群を一元管理できます。
Docker単体だとコンテナごとにコマンドを打つ必要がありますが、Composeなら定義ファイル1つで全体を上げ下げできます。開発・テスト環境で特に重宝します。
バージョンについて。V1(docker-compose、ハイフン付き)は更新が止まっています。V2はdocker compose(ハイフンなし)を使います。今から始めるならV2一択です。
Compose 構造と基本コマンド
docker-compose.ymlの基本構造はこうなります:
# 注:最新 Docker Compose バージョンではバージョン指定は不要
# version: '3.8' # 現代バージョンではオプション
services:
service1: # コンテナ/サービス定義
# サービス設定
networks:
network1: # カスタムネットワーク設定
# ネットワーク設定
volumes:
volume1: # 名前付きボリューム定義
# ボリューム設定| タスク | CLI コマンド(V2) | 説明 |
|---|---|---|
| 構築と展開 | docker compose up | yml で定義されたコンテナを構築・実行。 |
| バックグラウンド展開 | docker compose up -d | 展開しアプリをバックグラウンドで実行。 |
| アプリ停止 | docker compose stop | コンテナを停止。 |
| 停止と削除 | docker compose down | サービスとネットワークを停止・削除。デフォルトで名前付きボリュームは削除しない。 |
| ボリューム付き削除 | docker compose down --volumes または -v | サービス、ネットワーク、名前付きボリュームを強制削除。 |
| サービススケール | docker compose up --scale service=n | 特定サービスのコンテナ数(n)を増加。 |
| サービスステータス | docker compose ps | コンテナの現在ステータスを表示。 |
| ログ | docker compose logs | 定義コンテナのログを表示。 |
永続データ管理(ボリューム)
コンテナは停止すると中身が消えます。データベースのデータやユーザーアップロードファイルを残すには、ボリュームが不可欠です。
名前付きボリュームは、ymlのvolumesセクションで定義してサービスにマウントします。管理しやすくて、明示的に消さない限り残ります。ホストマウント(バインドマウント)は、ホストのディレクトリを直接コンテナに共有する方式で、/path/on/host:/path/in/containerという構文です。開発中にソースコードの変更を即座にコンテナに反映したいときに便利です。
| タスク | CLI コマンド(Docker、Compose ボリュームに適用) |
|---|---|
| ボリューム一覧 | docker volume ls |
| ボリューム検査 | docker volume inspect <volume_name> |
| ボリューム削除 | docker volume rm <volume_name> |
| 未使用ボリュームクリーン | docker volume prune |
Compose の高度な本番ベストプラクティス
シークレットと環境変数管理
データベースのパスワードやAPIキーをコードに直書きしてはいけません。これは本当にやらかしやすいポイントです。イメージレイヤーに残って、後からdocker historyで丸見えになります。
.envファイルに環境変数を保存し、docker-compose.ymlでenv_file: .envとして参照するのが基本パターンです。ただし、この.envファイルは必ず.gitignoreに入れてください。Gitに突っ込んだ瞬間に意味がなくなります。
ネットワークとアクセスセキュリティ
Composeで定義したコンテナは、デフォルトで内部ネットワーク上で相互に通信できます。これを利用して、データベースのポートをホストに公開しない、という設定をするとよいです。ymlからポート公開を削除するだけで、データベースには同じComposeネットワーク内からしかアクセスできなくなり、外部から隠せます。ホストからアクセスしたい場合はSSHトンネルを使います。
リソース制限と再起動
共有サーバでコンテナを動かすなら、リソース制限は必須です。一つのサービスがCPUやメモリを食いつぶして、他のサービスに影響が出るのを防げます。
deploy: resourcesでメモリ、CPU、GPUの制限を指定します。limitsはそのコンテナが使える上限、reservationsは予約量です。restart: alwaysを付けておけば、サーバ再起動時にも自動でコンテナが立ち上がります。on-failure、遅延(delay)、最大試行回数(max_attempts)などで細かく条件を絞ることもできます。
ヘルスチェック
コンテナが「実際に動いているか」を定期的に確認する仕組みです。単にプロセスが生きているだけでなく、HTTPリクエストに応答するかとか、DB接続できるかをテストして、失敗したら再起動します。
設定項目はinterval(テストの頻度)、retries(ダウンとみなす失敗回数)、timeout(タイムアウト時間)、start_period(起動時の猶予)です。
ホストセキュリティと一般的ベストプラクティス
Docker Engineが動くLinuxサーバ自体のセキュリティも大事です。コンテナがどれだけ堅くても、ホストが落ちたら終わりです。
Rootでのログインは無効にする(Ubuntu Serverならデフォルトで無効)。SSHログインはパスワードではなくRSAキーを使う。ssh-keygenで鍵を作って、ssh-copy-id <user>@<server>で公開鍵をサーバに登録します。
ブルートフォース対策にFail2Banを入れます(apt install fail2ban)。SSHへの失敗が多いIPを自動でブロックしてくれます。あとはDocker Engineと依存関係のこまめな更新、docker statsでのリソース監視、ログの記録と監視システムの導入。地味ですが、これらが効いてきます。
このガイドのコマンドとプラクティスを一通り試せば、開発から本番までDockerで困ることはほぼなくなります。次に掘るとしたら、Kubernetesでのオーケストレーションか、イメージサイズと起動時間をさらに削る最適化手法あたりでしょうか。