初心者のためのDocker:コンテナの実践ガイド

私がDockerを使い始めたとき、その強力さにすぐ気づきました。数時間かかる代わりに数分で開発環境をセットアップしたり、異なるマシン間でアプリケーションを実行したりする「自分のマシンでは動作する」問題を解決できると考えてみてください。

Dockerは、軽量でポータブルなコンテナにアプリケーションをパッケージ化することで、アプリケーションのビルド、配布、実行を簡素化します。開発者、データサイエンティスト、システム管理者であっても、Dockerをマスターすることで手間を省き、ワークフローを効率化することができます。

このチュートリアルでは、Dockerの基本事項、インストール、主要な概念の理解、最初のコンテナ化されたアプリケーションの実行について説明します。最後まで進むと、Dockerの動作原理だけでなく、実際に使用して経験を積むことができ、より高度なトピックに強力な基盤を築くことができます。

Dockerとは何ですか?

Dockerは、ソフトウェアとその依存関係をコンテナと呼ばれる標準化された単位にパッケージ化することで、アプリケーションの展開を簡素化するオープンソースのコンテナ化プラットフォームです。従来の仮想マシンとは異なり、DockerコンテナはホストOSカーネルを共有しており、より効率的で軽量です。

コンテナは、アプリケーションが開発、テスト、そして本番環境で同じように動作することを保証します。これにより、互換性の問題が減少し、さまざまなプラットフォーム間でのポータビリティが向上します。その柔軟性とスケーラビリティのために、Dockerは現代のDevOpsおよびクラウドネイティブ開発ワークフローにおいて重要なツールとなっています。

Docker公式ロゴ。

Dockerのインストール

Dockerは、Windows、macOS、Linuxなどのさまざまなオペレーティングシステムにインストールできます。コア機能はすべてのプラットフォームで同じですが、インストールプロセスはシステムによって若干異なります。以下に、お好みのオペレーティングシステムにDockerをインストールするための手順を示します。

WindowsにDockerをインストールする

  1. Windows用の Docker Desktop をダウンロードしてください。

Windows用のDocker Desktopインストーラーをダウンロードしてください。

  1. インストーラーを実行し、セットアップ手順に従ってください。

Windows用Docker Desktopのインストール

  1. 求められた場合はWSL 2の統合を有効にします。
  2. PowerShellでdocker –versionを実行してインストールを確認します。

インストール後のDockerバージョンをPowerShellで確認

5. ランメニューからDocker Desktopアプリを起動します。

WindowsでDocker Desktopアプリケーションを起動する

macOSへのDockerのインストール

  1. Docker Desktop for Macをダウンロードします。

Mac用Docker Desktopインストーラーをダウンロード

  1. ダウンロードした.dmgファイルを開き、DockerをApplicationsフォルダにドラッグします。
  2. Dockerを起動し、セットアップを完了します。
  3. ターミナルで docker –version を使用してインストールを確認します。

Linux(Ubuntu)にDockerをインストールする

  1. パッケージリストを更新します: sudo apt update 
  2. 依存関係をインストールします: sudo apt install apt-transport-https ca-certificates curl software-properties-common 
  3. Dockerの公式GPGキーを追加します: curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - 
  4. Dockerのリポジトリを追加します: sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" 
  5. Dockerをインストールします: sudo apt install docker-ce  
  6. インストールを確認します: docker –version

基本的なDockerの概念

Dockerがインストールされたので、すぐにコンテナを実行し始めたいかもしれません。しかし、その前に、Dockerの動作の基礎を形成するいくつかの重要な概念を理解することが重要です。これらの概念は、Dockerをより効果的にナビゲートし、初心者の一般的な落とし穴を避けるのに役立ちます。

Dockerの中心にはイメージがあり、これはコンテナの設計図となります;コンテナはこれらのイメージの実行インスタンスです;そしてDocker Hubは、イメージを共有し管理するための集中リポジトリです。

これらの概念をさらに詳しく探ってみましょう。

Dockerイメージ

Dockerイメージはコンテナの基本的な構成要素です。これらは不変で、読み取り専用のテンプレートであり、アプリケーションを実行するために必要なすべてが含まれています。オペレーティングシステム、アプリケーションコード、ランタイム、および依存関係が含まれます。

イメージは、Dockerfileを使用してビルドされ、これはイメージをレイヤーごとに作成するための指示を定義します。

イメージは、Docker Hubなどのコンテナレジストリに保存され、そこから取得できます。

イメージを操作するためのいくつかのコマンドの例を示します:

  • docker pull nginx: Docker Hubから最新のNginxイメージを取得します。
  • docker images: ローカルマシン上のすべての利用可能なイメージを一覧表示します。
  • docker rmi nginx: ローカルマシンからイメージを削除します。

Dockerコンテナ

Dockerコンテナは、Dockerイメージの実行中のインスタンスです。コンテナは、アプリケーションが相互に干渉することなく、またホストシステムに干渉することなく実行できる分離されたランタイム環境を提供します。各コンテナは独自のファイルシステム、ネットワーク、およびプロセス空間を持ちますが、ホストのカーネルを共有します。

コンテナは、作成、起動、停止、削除のシンプルなライフサイクルに従います。以下は一般的なコンテナ管理コマンドの内訳です:

  1. コンテナの作成: docker create または docker run
  2. コンテナの起動: docker start
  3. コンテナの停止: docker stop
  4. コンテナの再起動: docker restart
  5. コンテナの削除: docker rm

実践的な例を見てみましょう。以下のコマンドは、Nginxコンテナをデタッチモード(バックグラウンドで実行)で起動し、コンテナ内のポート80をホストマシンのポート8080にマッピングします:

docker run -d -p 8080:80 nginx

このコマンドを実行すると、DockerはNginxイメージをプルし(すでに存在しない場合)、コンテナを作成して起動します。

すべての実行中および停止したコンテナを確認するには:

docker ps -a

すべてのコンテナのリストと、それらのステータスや割り当てられたポートの詳細が表示されます。

Docker Hub

Docker Hubは、コンテナイメージを見つけ、保存し、配布するためのクラウドベースのレジストリサービスです。ユーザーはカスタムイメージをDocker Hubにプッシュし、公開またはプライベートで共有できます。

以下は、Docker Hubとやり取りするためのいくつかのコマンドです:

  • docker login:Docker Hubに認証します。
  • docker push my-image:カスタムビルドしたイメージをDocker Hubにアップロードします。
  • docker search ubuntu:公式およびコミュニティイメージを検索します。
  • docker pull ubuntu:Docker HubからUbuntuイメージをダウンロードします。

コンテナ化に不慣れですか?コンテナ化と仮想化の概念コースでしっかりとした基礎を築きましょう。

初めてのDockerコンテナを実行する

Dockerの基本概念を学んだので、実際に行動に移す時が来ました!まず、Dockerが正しくインストールされ、期待通りに動作していることを確認するために、最初のコンテナを実行してみましょう。

Dockerインストールをテストするには、PowerShell(Windows)またはターミナル(MacおよびLinux)を開き、次のコマンドを実行します:

docker run hello-world

これにより、DockerHubからhello-worldイメージがプルされ、コンテナ内で実行されます。

Docker hello-worldイメージの例

さあ、次のステップに進んで、実際のアプリケーション—Nginxウェブサーバーを実行しましょう。以下のコマンドを実行してください:

docker run -d -p 8080:80 nginx

上記のコマンドは以下のことを行います:

  • -dフラグはコンテナをデタッチモードで実行し、バックグラウンドで動作することを意味します。
  • -p 8080:80フラグはコンテナ内のポート80をローカルマシンのポート8080にマッピングし、ウェブサーバーにアクセスできるようにします。

コマンドが正常に実行されると、ブラウザを開いて次のURLにアクセスしてください:http://localhost:8080

localhost:8080でウェブサーバーにアクセスしています

デフォルトのNginxウェルカムページが表示され、ウェブサーバーがコンテナ内で実行されていることが確認できるはずです!

また、Docker Desktopで実行中のコンテナが表示されます:

ポート8080で実行中のNginxコンテナ

最初のDockerイメージの構築

これまで、私たちはDocker Hubから事前構築されたイメージを使用してきました。しかし、アプリケーションに合わせたカスタム環境が必要な場合はどうでしょうか?そこで、自分自身のDockerイメージを構築することが重要になります。

Dockerイメージの作成には、イメージビルディングを自動化するスクリプトであるDockerfileを書くことが含まれます。これにより、異なる環境間での一貫性と移植性が確保されます。イメージが構築されると、それはコンテナとして実行され、隔離された環境でアプリケーションを実行できます。

このセクションでは、Dockerfileの基本、カスタムイメージの構築、そしてそれをコンテナとして実行する方法を学びます。

Dockerfileの基本

Dockerfileは、Dockerイメージの構築方法を定義する一連の命令を含むスクリプトです。イメージ作成プロセスを自動化し、環境間の一貫性を確保します。Dockerfile内の各命令は、イメージ内に新しいレイヤーを作成します。以下は、シンプルなPython FlaskアプリのためのDockerfileの例の内訳です:

# Pythonランタイムを含むベースイメージ FROM python:3.9 # コンテナ内の作業ディレクトリを設定 WORKDIR /app # ホストからコンテナにアプリケーションファイルをコピー COPY . /app # requirements.txtにリストされた依存関係をインストール RUN pip install -r requirements.txt # コンテナ起動時にFlaskアプリを実行するコマンドを定義 CMD ["python", "app.py"]

上記のコマンドでは:

  • -v my-volume:/app/dataは、my-volumeストレージをコンテナ内の/app/dataディレクトリにマウントします。
  • コンテナが停止したり削除されたりしても、/app/dataに保存されたデータは保持されます。

上記のDockerfileの内訳:

  • FROM python:3.9: Python 3.9が事前にインストールされたベースイメージを指定します。
  • WORKDIR /app: コンテナ内の作業ディレクトリを/appに設定します。
  • COPY . /app: ホストの現在のディレクトリからすべてのファイルをコンテナ内の/appにコピーします。
  • RUN pip install -r requirements.txt: コンテナ内にすべての必要な依存関係をインストールします。
  • CMD ["python", "app.py"]: コンテナが起動するときに実行するコマンドを定義します。

イメージのビルドと実行

Dockerfileが定義されたら、次のコマンドを使用してイメージをビルドして実行できます:

ステップ1:イメージをビルドする

docker build -t my-flask-app .

上記のコマンド:

  • 現在のディレクトリ(.)をビルドコンテキストとして使用します。
  • Dockerfileを読み取り、その指示を実行します。
  • 結果のイメージに-tを付けてmy-flask-appとしてタグ付けします。

ステップ2:イメージをコンテナとして実行する

docker run -d -p 5000:5000 my-flask-app

上記のコマンド:

  • コンテナをデタッチモードで実行します(-d)。
  • コンテナ内のポート5000をホストのポート5000にマッピングします(-p 5000:5000)。

実行中は、ブラウザでhttp://localhost:5000に移動することでFlaskアプリケーションにアクセスできます。

Dockerボリュームと永続性

デフォルトでは、Dockerコンテナ内のデータは一時的です。コンテナが停止したり削除されたりすると、データは消えてしまいます。コンテナの再起動をまたいでデータを永続化し、複数のコンテナ間で共有するために、Dockerはボリュームを提供しており、これは永続ストレージを効率的に管理するための組み込みメカニズムです。

コンテナのファイルシステム内にデータを保存するのとは異なり、ボリュームはDockerによって別々に管理されるため、より効率的で柔軟性があり、バックアップが容易です。

次のセクションでは、コンテナ内のデータの永続性を確保するために、Dockerボリュームを作成して使用する方法を探ります。

Dockerボリュームの作成と使用

ステップ1: ボリュームを作成する

ボリュームを使用する前に、作成する必要があります。次のコマンドを実行してください:

docker volume create my-volume

これにより、my-volumeという名前のボリュームが作成され、Dockerは特定のコンテナとは別に管理します。ステップ2: コンテナ内でボリュームを使用する

さて、コンテナを開始し、その中にボリュームをマウントしましょう:

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

上記のコマンドについて:

  • -v my-volume:/app/data は、my-volume ストレージをコンテナ内の /app/data ディレクトリにマウントします。
  • /app/data に格納されたデータは、コンテナが停止または削除されても永続化されます。

複数コンテナのアプリケーションのためのDocker Compose

これまでは、単一コンテナのアプリケーションに取り組んできましたが、多くの実世界のアプリケーションでは複数のコンテナが連携して動作する必要があります。たとえば、Webアプリケーションにはバックエンドサーバー、データベース、およびキャッシュレイヤーが必要になる場合があります。それぞれが独自のコンテナで実行されます。個々の docker run コマンドを使用してこれらのコンテナを手動で管理するとすぐに手間がかかります。

そこで、Docker Composeが登場します。

Docker Composeとは何ですか?

Docker Composeは、複数のコンテナを管理するのを簡素化するツールです。複数のdocker runコマンドを実行する代わりに、docker-compose.ymlファイルを使ってアプリケーションスタック全体を定義し、1つのコマンドでデプロイできます。

Docker Composeファイルの作成

それでは、実際の例として、Node.jsアプリケーションを作成し、MongoDBデータベースに接続する簡単なマルチコンテナアプリケーションを作成しましょう。2つのコンテナを別々に管理する代わりに、docker-compose.ymlファイルでそれらを定義します。

以下は、Docker Composeでマルチコンテナセットアップを定義する方法です。

version: '3' services: web: build: . ports: - "3000:3000" depends_on: - database database: image: mongo volumes: - db-data:/data/db volumes: db-data:

上記のファイルを分解すると:

  • version: '3': Docker Composeのバージョンを指定します。
  • services:: 個々のサービス(コンテナ)を定義します。
  • web:: Node.jsウェブアプリケーションを定義します。
  • database:: MongoDBデータベースコンテナを定義します。
  • volumes:: MongoDBデータ永続化のための名前付きボリューム(db-data)を作成します。

マルチコンテナアプリケーションの実行

docker-compose.ymlファイルが準備できたら、1つのコマンドでアプリケーションスタック全体を起動できます:

docker-compose up -d

前述のコマンドは、webおよびデータベースコンテナをデタッチモード(-d)で起動します。

すべてのサービスを停止するには、以下を使用します:

docker-compose down

これはすべてのコンテナを停止し、ボリュームとネットワーク設定を保持しながら削除します。

Dockerネットワーキングの基本

これまで、コンテナの実行とストレージの管理に焦点を当ててきましたが、コンテナ同士が通信する必要がある場合はどうなるのでしょうか?ほとんどの実際のアプリケーションでは、コンテナは孤立して動作することはなく、データを交換する必要があります。ウェブサーバーがデータベースと話す場合や、マイクロサービス同士が相互に作用する場合などです。

Dockerは、孤立した内部ネットワークから外部からアクセス可能な構成まで、さまざまなユースケースに対応するネットワーキングオプションを提供します。

Dockerスキルをレベルアップさせる準備はできていますか?中級Dockerに登録して、マルチステージビルド、先進的なネットワーキングなどを探求しましょう!

Dockerネットワーキングとは何ですか?

Dockerネットワーキングは、同じホスト上または分散環境内の複数のホスト間で、コンテナ同士が通信できるようにする組み込み機能です。ネットワークの分離、セグメンテーション、さまざまなデプロイメントシナリオに適した接続オプションを提供します。

Dockerは、異なるユースケースに応じた複数のネットワークタイプをサポートしています:

  • ブリッジ(デフォルト):同じホスト上のコンテナは、内部仮想ネットワークを介して通信します。各コンテナはブリッジネットワーク内でプライベートIPアドレスを取得し、コンテナ名を介して互いにアクセスできます。
    • 例: docker network create my-bridge-network
    • 外部にサービスを公開せずに安全に通信する必要がある複数のコンテナを単一のホスト上で実行するのに理想的です。
  • ホスト: コンテナはホストのネットワークスタックを共有し、ホストのIPアドレスとポートを直接使用します。
    • 例: docker run --network host nginx
    • 高パフォーマンスが必要で、ネットワークの隔離が不要な場合に便利です。たとえば、監視エージェントや低遅延アプリケーションを実行する際などです。
  • オーバーレイ:分散ネットワークを作成して異なるホスト間でコンテナ間通信を可能にします。
    • 例:docker network create --driver overlay my-overlay-network
    • Docker Swarmなどのオーケストレーションデプロイメント向けに設計されており、サービスが複数のノードにまたがる場合に使用されます。
  • Macvlan:各コンテナに固有のMACアドレスを割り当て、ネットワーク上で物理デバイスとして表示されるようにします。
    • 例: docker network create -d macvlan --subnet=192.168.1.0/24 my-macvlan
    • コンテナが直接ネットワークアクセスが必要な場合に使用され、レガシーシステムを統合したり物理ネットワークとやり取りする場合に適しています。

カスタムネットワークでコンテナを実行する

カスタムブリッジネットワークを設定して使用する方法を見ていきましょう。カスタムブリッジネットワークを作成してコンテナ間の通信に使用します。

ステップ1: カスタムネットワークを作成する

コンテナを実行する前に、専用のネットワークを作成する必要があります。

docker network create my-custom-network

このコマンドは、コンテナが相互コンテナ通信のために参加できる分離されたネットワークを作成します。

ステップ2: ネットワーク上でコンテナを実行する

さて、2つのコンテナを起動して、新しく作成したネットワークに接続しましょう:

docker run -d --network my-custom-network --name app1 my-app docker run -d --network my-custom-network --name app2 my-app
  • --network my-custom-network フラグはコンテナを指定されたネットワークにアタッチします。
  • --name フラグはユニークなコンテナ名を割り当て、参照しやすくします。

app11app2 は今やコンテナ名を使用して通信できます。コンテナの内部で ping コマンドを使用して接続性をテストできます:

docker exec -it app1 ping app2

すべてが正しく設定されていれば、コンテナが通信できることを確認する応答が表示されます。

Dockerネットワークの検査

ネットワーク設定と接続されたコンテナを確認するには、次のコマンドを使用します:

docker network inspect my-custom-network

このコマンドは、IPレンジ、接続されたコンテナ、設定など、ネットワークに関する詳細を提供します。

ポートの公開と公開

外部からアクセス可能でなければならないコンテナを実行する場合、特定のポートを公開できます。

たとえば、Nginxウェブサーバーを実行し、ローカルマシンのポート8080で公開するには、次のようにします:

docker run -d -p 8080:80 nginx

これにより、コンテナ内のポート80がホストのポート8080にマッピングされ、サービスがhttp://localhost:8080を介してアクセス可能になります。

Dockerネットワーキングのベストプラクティス

  • カスタムネットワークを使用する: 意図しないコンテナ間のアクセスを減らすために、本番環境ではデフォルトのブリッジネットワークを使用しないでください。
  • DNSベースの発見を活用する: IPアドレスをハードコードするのではなく、コンテナ名を使用して動的サービス発見を可能にします。
  • 外部露出を制限する: ファイアウォールやネットワークポリシーを使用してサービスアクセスを制御します。
  • トラフィックを監視する: docker network inspect、Wireshark、またはPrometheusなどのツールを使用してネットワークトラフィックを分析し、異常を検出します。
  • オーバーレイネットワークの最適化:分散セットアップで展開する場合は、ホストローカルルーティングオプションを活用して遅延を軽減するためにオーバーレイネットワークを調整します。

Dockerのベストプラクティスと次のステップ

Dockerの基本を学んだら、安全で効率的でメンテナンスしやすいコンテナ化されたアプリケーションを構築するのに役立つベストプラクティスを取り入れ、スキルを向上させる時です。

以下のベストプラクティスを使用すると、Dockerのワークフローを効率化し、一般的な落とし穴を回避できます。

  • 公式のベースイメージを使用する: セキュリティと安定性を確保するために、公式でよくメンテナンスされたベースイメージを常に優先してください。公式イメージは最適化されており、定期的に更新され、脆弱性を含む可能性が低くなっています。
  • イメージを小さく保つ: 最小限のベースイメージ(例:python:3.9-slim)を選択してイメージサイズを削減します。不要な依存関係やファイルを削除して、ストレージとプル時間を最適化します。
  • マルチステージビルドを使用する: ビルド依存関係とランタイム依存関係を分離することで、Dockerfileを最適化します。マルチステージビルドにより、最終イメージには必要なアーティファクトのみが含まれ、サイズと攻撃面が削減されます。
  • 画像に適切なタグを付ける:イメージを取得する際に予期せぬアップデートを避けるために、バージョン管理されたタグ(例:my-app:v1.0.0)を使用して、latestの代わりに常に使用してください。
  • 脆弱性をスキャンする:デプロイメント前に、docker scanTrivy、またはClairなどのセキュリティスキャンツールを使用して、イメージ内のセキュリティの脆弱性を特定して修正してください。
  • 環境変数を安全に管理する: 画像内に機密情報を保存するのを避けてください。Dockerシークレット、環境変数、またはAWS Secrets ManagerやHashiCorp Vaultなどの外部シークレット管理ツールを使用してください。
  • .dockerignoreファイルを使う: 不要なファイル(例:.git, node_modules, venv)を除外して、ビルドコンテキストのサイズを減少させ、イメージに機密ファイルが誤って含まれるのを防ぎます。
  • ログと監視を有効にする: コンテナのログと監視のためにPrometheus、Grafana、Fluentdなどのツールを利用します。docker logsを使用してログを確認し、より良い可観測性のために構造化ログを有効にします。

Dockerの基本をマスターしたら、探求すべき高度なトピックがたくさんあります。次に探る価値のあるいくつかの分野を以下に示します:

  • Docker Swarm & Kubernetes: Docker Swarm(組み込みのクラスター機能)およびKubernetes(エンタープライズグレードのオーケストレーション、自動スケーリング、サービスディスカバリー)を探求し、プロダクショングレードのオーケストレーションを実現します。
  • コンテナセキュリティのベストプラクティス: コンテナ化されたアプリケーションを保護するために、CIS Dockerベンチマークガイドラインに従い、ロールベースのアクセス制御(RBAC)を実装します。
  • Dockerを使用したCI/CDパイプライン: GitHub Actions、GitLab CI、またはJenkinsを使用して、イメージのビルド、セキュリティスキャン、展開を自動化します。
  • クラウドネイティブ開発: AWS ECS、Azure Container Instances、Google Cloud Runなどのクラウドプラットフォームと組み合わせて、スケーラブルで管理された展開を実現します。
  • データ永続化戦略: Dockerボリューム、バインドマウント、tmpfsの違いを理解して、最適なストレージ管理を実現します。

Conclusion

Dockerは、開発者がアプリケーションを構築、配布、実行する方法に革命をもたらし、現代のソフトウェア開発に欠かせないツールとなっています。

このチュートリアルでは、以下の内容を扱いました:

  • Dockerとは何か、なぜ重要なのか
  • 最初のコンテナをインストールして実行する方法
  • イメージ、コンテナ、ネットワーキングといった重要な概念
  • Dockerボリュームを使った永続ストレージ
  • Docker Composeを使用したマルチコンテナアプリケーション
  • セキュリティ、パフォーマンス、スケーラビリティのベストプラクティス

しかし、これは始まりに過ぎません!Dockerの専門知識を深めたい場合は、初心者向けのDocker入門コースを受講できます。さらに深い知識を得たい方は、マルチステージビルド、Dockerネットワーキングツール、Docker Composeを網羅した中級Dockerコースを受講できます。最後に、Docker認定を取得することもできますので、興味があれば2025年版完全Docker認定(DCA)ガイドをチェックしてください!

Source:
https://www.datacamp.com/tutorial/docker-tutorial