はじめに
Docker は、開発者がコンテナと呼ばれる分離された環境でアプリケーションを作成、デプロイ、実行できるようにすることで、アプリケーション開発に革命をもたらしました。Mac ユーザーは、コンテナ化を始めたばかりのときに、"docker command not found" エラーに遭遇することがあり、これは苛立たしいものです。この実験(Lab)では、Docker の概念を理解し、Docker のインストールを確認し、一般的な問題をトラブルシューティングし、開発作業に適した Docker 環境をセットアップする方法を説明します。
Docker の基本を理解し、インストールを確認する
Docker は、アプリケーションとその依存関係をコンテナにパッケージ化するための標準化された方法を提供し、さまざまな環境で移植可能にします。Docker の問題をトラブルシューティングする前に、基本を理解し、インストールを確認しましょう。
Docker とは?
Docker は、コンテナ化技術を使用して、アプリケーションの作成、デプロイ、実行を容易にするプラットフォームです。仮想マシンとは異なり、Docker コンテナはホストシステムのカーネルを共有しますが、分離された環境で実行されるため、軽量で効率的です。
Docker の主要なコンポーネントには以下が含まれます。
- Docker Engine: コンテナを構築し実行するランタイム
- Docker Images: コンテナを作成するために使用される読み取り専用テンプレート
- Docker Containers: Docker イメージの実行インスタンス
- Docker Registry: Docker イメージを保存および共有するためのリポジトリ
- Dockerfile: Docker イメージを構築するための命令を含むテキストファイル
Docker のインストール確認
この実験(Lab)環境には、すでに Docker がインストールされています。Docker のバージョンを確認して、これを確認しましょう。
docker --version
次のような出力が表示されるはずです。
Docker version 20.10.21, build 20.10.21-0ubuntu1~22.04.3
次に、Docker デーモンが実行されているかどうかを確認しましょう。
sudo systemctl status docker
Docker がアクティブ(実行中)であることを示す出力が表示されるはずです。出力は次のようになります。
● docker.service - Docker Application Container Engine
Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
Active: active (running) since ...
ステータスビューを終了するには q を押します。
何らかの理由で Docker が実行されていない場合は、次のようにして起動できます。
sudo systemctl start docker
最初のコンテナを実行する
シンプルな "hello-world" コンテナを実行して、Docker が正しく動作していることを確認しましょう。
docker run hello-world
このコマンドは、hello-world イメージがローカルにまだ存在しない場合はダウンロードし、コンテナ内で実行します。次のような出力が表示されるはずです。
Hello from Docker!
This message shows that your installation appears to be working correctly.
...
この出力は、Docker がこのコンテナを実行するために何を行ったかを説明しており、Docker の仕組みを理解するのに役立ちます。
実行中のコンテナの確認
現在実行中のすべてのコンテナを表示するには、次を使用します。
docker ps
hello-world コンテナはメッセージを表示した直後に終了するため、このリストには表示されない可能性があります。停止したコンテナを含むすべてのコンテナを表示するには、次を使用します。
docker ps -a
これにより、すべてのコンテナ、その ID、作成元のイメージ、作成日時、および現在のステータスが表示されます。
これで、Docker が環境にインストールされ、正しく動作していることを確認し、最初のコンテナを実行しました!
Docker イメージとコンテナの操作
Docker が正しく動作することを確認したので、Docker イメージとコンテナをより詳細に操作する方法を学びましょう。
Docker イメージの理解
Docker イメージは、コンテナのブループリントです。これらには、アプリケーションコード、ライブラリ、依存関係、ツール、およびアプリケーションの実行に必要なその他のファイルが含まれています。
いくつかの基本的なコマンドを使用して、Docker イメージを調べてみましょう。
利用可能なイメージのリスト表示
システムで利用可能なすべての Docker イメージを表示するには、次のようにします。
docker images
次のような出力が表示されるはずです。
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest feb5d9fea6a5 X months ago 13.3kB
Docker Hub からのイメージのプル
Docker Hub は、Docker イメージを見つけて共有できるクラウドベースのレジストリサービスです。一般的なイメージをプルしてみましょう。
docker pull nginx
このコマンドは、最新の nginx Web サーバーイメージをダウンロードします。イメージのさまざまなレイヤーがダウンロードされるにつれて、進捗状況が出力されます。
Using default tag: latest
latest: Pulling from library/nginx
...
Digest: sha256:...
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
新しくダウンロードした nginx イメージをリストに表示するには、もう一度 docker images を実行します。
コンテナの操作
いくつかのイメージがあるので、コンテナを作成して管理する方法を学びましょう。
コンテナの実行
Web ページを提供する nginx コンテナを実行してみましょう。
docker run --name my-nginx -p 8080:80 -d nginx
このコマンドは、いくつかのことを行います。
--name my-nginx: コンテナに "my-nginx" という名前を付けます-p 8080:80: ホストのポート 8080 をコンテナのポート 80 にマッピングします-d: コンテナをデタッチモード(バックグラウンド)で実行しますnginx: 使用するイメージを指定します
コンテナが実行されていることの確認
コンテナが実行されていることを確認します。
docker ps
実行中のコンテナのリストに、nginx コンテナが表示されるはずです。
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a1b2c3d4e5f6 nginx "/docker-entrypoint.…" X seconds ago Up X seconds 0.0.0.0:8080->80/tcp my-nginx
Web サーバーへのアクセス
LabEx VM 環境で Web ブラウザを開き、以下に移動することで、nginx Web サーバーにアクセスできます。
http://localhost:8080
または、ターミナルから curl を使用することもできます。
curl http://localhost:8080
デフォルトの nginx ウェルカムページ HTML が表示されるはずです。
コンテナログの表示
コンテナのログを表示するには、次のようにします。
docker logs my-nginx
これにより、nginx サーバーのアクセスログが表示されます。
コンテナの停止と削除
実行中のコンテナを停止するには、次のようにします。
docker stop my-nginx
コンテナを削除するには(最初に停止する必要があります)、次のようにします。
docker rm my-nginx
コンテナが削除されたことを確認します。
docker ps -a
"my-nginx" という名前のコンテナがリストに表示されなくなるはずです。
これで、Docker イメージとコンテナの操作の基本を理解できました。Docker Hub からイメージをプルし、コンテナを実行し、ポートをマッピングし、ログを表示し、コンテナのライフサイクルを管理しました。
Dockerfile を使用して独自の Docker イメージを作成する
これまでは、Docker Hub からの既製の Docker イメージを使用してきました。次に、Dockerfile を使用して独自のカスタム Docker イメージを作成する方法を学びましょう。
Dockerfile とは?
Dockerfile は、Docker イメージを構築するための命令を含むテキストファイルです。ベースイメージを指定し、ファイルを追加し、ソフトウェアをインストールし、環境変数を設定し、イメージから作成されるコンテナを構成します。
最初の Dockerfile の作成
Node.js を使用してシンプルな Web アプリケーションを作成し、Docker イメージとしてパッケージ化してみましょう。
まず、プロジェクト用の新しいディレクトリを作成します。
mkdir -p ~/project/node-app
cd ~/project/node-app
次に、シンプルな Node.js アプリケーションを作成します。まず、app.js という名前のファイルを作成します。
nano app.js
ファイルに次のコードを追加します。
const http = require("http");
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader("Content-Type", "text/plain");
res.end("Hello World from Docker!\n");
});
const port = 3000;
server.listen(port, () => {
console.log(`Server running at http://localhost:${port}/`);
});
Ctrl+O、Enter の順に押してファイルを保存し、Ctrl+X で nano を終了します。
次に、Node.js アプリケーションを定義する package.json ファイルを作成します。
nano package.json
次の内容を追加します。
{
"name": "docker-node-app",
"version": "1.0.0",
"description": "A simple Node.js app for Docker",
"main": "app.js",
"scripts": {
"start": "node app.js"
},
"author": "",
"license": "ISC"
}
保存して nano を終了します。
次に、Dockerfile を作成します。
nano Dockerfile
次の内容を追加します。
## Use an official Node.js runtime as the base image
FROM node:14-alpine
## Set the working directory in the container
WORKDIR /usr/src/app
## Copy package.json and package-lock.json
COPY package.json ./
## Install dependencies
RUN npm install
## Copy the application code
COPY app.js ./
## Expose the port the app runs on
EXPOSE 3000
## Command to run the application
CMD ["npm", "start"]
保存して nano を終了します。
Docker イメージの構築
Dockerfile があるので、Docker イメージを構築できます。
docker build -t my-node-app .
このコマンドは、Dockerfile からイメージを構築します。
-t my-node-app: イメージに "my-node-app" という名前のタグを付けます.: Dockerfile が現在のディレクトリにあることを指定します
ビルドの進行状況を示す出力が表示されます。
Sending build context to Docker daemon X.XXkB
Step 1/7 : FROM node:14-alpine
---> XXXXXXXXXX
Step 2/7 : WORKDIR /usr/src/app
---> XXXXXXXXXX
...
Successfully built XXXXXXXXXX
Successfully tagged my-node-app:latest
カスタム Docker イメージの実行
次に、新しく構築したイメージを使用してコンテナを実行します。
docker run --name node-app-container -p 3000:3000 -d my-node-app
コンテナが実行されていることを確認します。
docker ps
リストにコンテナが表示されるはずです。
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
XXXXXXXXXX my-node-app "npm start" X seconds ago Up X seconds 0.0.0.0:3000->3000/tcp node-app-container
アプリケーションのテスト
アプリケーションに HTTP リクエストを送信して、アプリケーションをテストします。
curl http://localhost:3000
次のように表示されるはずです。
Hello World from Docker!
Dockerfile の理解
Dockerfile の主要なコンポーネントを確認しましょう。
FROM node:14-alpine: 使用するベースイメージを指定しますWORKDIR /usr/src/app: コンテナ内の作業ディレクトリを設定しますCOPY package.json ./: ホストからコンテナにファイルをコピーしますRUN npm install: ビルドプロセス中にコンテナ内でコマンドを実行しますEXPOSE 3000: コンテナがポート 3000 でリッスンすることをドキュメント化しますCMD ["npm", "start"]: コンテナの起動時に実行するコマンドを指定します
クリーンアップ
コンテナを停止して削除して、クリーンアップしましょう。
docker stop node-app-container
docker rm node-app-container
これで、Dockerfile を使用して独自の Docker イメージを作成し、それらのイメージを構築し、それらに基づいてコンテナを実行する方法を学びました。これは、Docker 開発の基本的なスキルです。
Docker ボリュームを使用したデータの管理
Docker コンテナを操作する際の課題の 1 つは、データの永続性です。コンテナは一時的なものであり、コンテナ内で作成されたデータは、コンテナが削除されると失われます。Docker ボリュームは、コンテナの外部にデータを永続化する方法を提供することにより、この問題を解決します。
Docker ボリュームの理解
Docker ボリュームは、Docker コンテナによって生成および使用されるデータを永続化するための推奨されるメカニズムです。これらは Docker によって完全に管理され、ホストファイルシステムのディレクトリ構造から分離されています。
ボリュームを使用する利点には、以下が含まれます。
- ボリュームは、バインドマウントよりもバックアップまたは移行が容易です
- Docker CLI コマンドを使用してボリュームを管理できます
- ボリュームは、Linux および Windows コンテナの両方で動作します
- ボリュームは、複数のコンテナ間でより安全に共有できます
- ボリュームドライバを使用すると、リモートホスト、クラウドプロバイダにボリュームを保存したり、ボリュームの内容を暗号化したりできます
Docker ボリュームの作成と使用
ボリュームを使用してデータを永続化するシンプルな MySQL データベースコンテナを作成してみましょう。
ボリュームの作成
まず、Docker ボリュームを作成します。
docker volume create mysql-data
すべてのボリュームを一覧表示するには、次のようにします。
docker volume ls
新しいボリュームがリストに表示されるはずです。
DRIVER VOLUME NAME
local mysql-data
ボリュームを使用したコンテナの実行
次に、このボリュームを使用する MySQL コンテナを実行してみましょう。
docker run --name mysql-db -e MYSQL_ROOT_PASSWORD=mysecretpassword -v mysql-data:/var/lib/mysql -p 3306:3306 -d mysql:5.7
このコマンドは、次のことを行います。
--name mysql-db: コンテナに "mysql-db" という名前を付けます-e MYSQL_ROOT_PASSWORD=mysecretpassword: MySQL を構成するための環境変数を設定します-v mysql-data:/var/lib/mysql: "mysql-data" ボリュームを、MySQL がデータを保存するディレクトリにマウントします-p 3306:3306: ホストのポート 3306 をコンテナのポート 3306 にマッピングします-d: コンテナをデタッチモードで実行しますmysql:5.7: 使用するイメージを指定します
コンテナが起動するまでしばらく待ち、実行されていることを確認します。
docker ps
データベースとの対話
データの永続性を示すために、データベースとテーブルを作成しましょう。まず、MySQL コンテナに接続します。
docker exec -it mysql-db bash
コンテナ内で、MySQL サーバーに接続します。
mysql -u root -pmysecretpassword
新しいデータベースとテーブルを作成します。
CREATE DATABASE testdb;
USE testdb;
CREATE TABLE users (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255));
INSERT INTO users (name) VALUES ('John'), ('Jane'), ('Bob');
SELECT * FROM users;
挿入されたデータが表示されるはずです。
+----+------+
| id | name |
+----+------+
| 1 | John |
| 2 | Jane |
| 3 | Bob |
+----+------+
MySQL プロンプトとコンテナを終了します。
exit
exit
ボリュームの永続性のテスト
次に、コンテナを停止して削除し、同じボリュームを使用して新しいコンテナを作成します。
docker stop mysql-db
docker rm mysql-db
同じボリュームを使用して新しいコンテナを作成します。
docker run --name mysql-db-new -e MYSQL_ROOT_PASSWORD=mysecretpassword -v mysql-data:/var/lib/mysql -p 3306:3306 -d mysql:5.7
次に、新しいコンテナに接続し、データが永続化されているかどうかを確認します。
docker exec -it mysql-db-new bash
mysql -u root -pmysecretpassword
USE testdb
SELECT * FROM users
先ほど挿入したのと同じデータが表示されるはずです。
+----+------+
| id | name |
+----+------+
| 1 | John |
| 2 | Jane |
| 3 | Bob |
+----+------+
MySQL プロンプトとコンテナを終了します。
exit
exit
これは、元のコンテナが削除された後でもデータが永続化されたことを示しています。これは、データが Docker ボリュームに保存されていたためです。
ボリュームの検査と管理
ボリュームを検査して、詳細情報を取得できます。
docker volume inspect mysql-data
これにより、マウントポイントや使用されているドライバなどの詳細が表示されます。
[
{
"CreatedAt": "YYYY-MM-DDTHH:MM:SS+00:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/mysql-data/_data",
"Name": "mysql-data",
"Options": {},
"Scope": "local"
}
]
クリーンアップするには、コンテナを停止して削除します。
docker stop mysql-db-new
docker rm mysql-db-new
ボリュームも削除する場合は、次のようにします。
docker volume rm mysql-data
これで、Docker ボリュームを使用して、コンテナのライフサイクル間でデータを永続化する方法を学びました。これは、データベースなどのステートフルアプリケーションに不可欠です。
Docker ネットワーキングの探求
Docker ネットワーキングにより、コンテナは互いに、そして外部の世界と通信できます。Docker のネットワーキング機能を理解することは、マルチコンテナアプリケーションを構築する上で不可欠です。
Docker ネットワークの種類
Docker は、すぐに使用できるいくつかのネットワークドライバを提供しています。
- bridge: デフォルトのネットワークドライバです。同じブリッジネットワーク上のコンテナは通信できます。
- host: コンテナとホスト間のネットワーク分離を削除します。
- none: コンテナのすべてのネットワーキングを無効にします。
- overlay: 複数の Docker デーモンを接続し、Swarm サービスが通信できるようにします。
- macvlan: コンテナに MAC アドレスを割り当て、ネットワーク上の物理デバイスのように表示させます。
デフォルトのブリッジネットワークの探求
Docker をインストールすると、デフォルトのブリッジネットワークが自動的に作成されます。それを調べてみましょう。
docker network ls
次のような出力が表示されるはずです。
NETWORK ID NAME DRIVER SCOPE
XXXXXXXXXXXX bridge bridge local
XXXXXXXXXXXX host host local
XXXXXXXXXXXX none null local
デフォルトのブリッジネットワークを検査できます。
docker network inspect bridge
このコマンドは、ネットワークに関する詳細情報(接続されているコンテナ、IP アドレス範囲、ゲートウェイなど)を提供します。
カスタムブリッジネットワークの作成と使用
コンテナの分離を向上させるために、カスタムブリッジネットワークを作成しましょう。
docker network create my-network
ネットワークが作成されたことを確認します。
docker network ls
新しいネットワークがリストに表示されるはずです。
NETWORK ID NAME DRIVER SCOPE
XXXXXXXXXXXX bridge bridge local
XXXXXXXXXXXX host host local
XXXXXXXXXXXX my-network bridge local
XXXXXXXXXXXX none null local
次に、このネットワーク上で 2 つのコンテナを実行し、それらの間の通信を実演してみましょう。
まず、カスタムネットワーク上で NGINX コンテナを起動します。
docker run --name web-server --network my-network -d nginx
次に、Alpine Linux コンテナを実行し、それを使用して NGINX コンテナへの接続をテストしてみましょう。
docker run --name alpine --network my-network -it alpine sh
Alpine コンテナ内で、curl をインストールし、NGINX コンテナへの接続をテストします。
apk add --update curl
curl web-server
出力は、NGINX ウェルカムページの HTML になるはずです。これは、Docker がカスタムネットワーク内のコンテナに組み込み DNS を提供し、コンテナ名から IP アドレスへの解決を可能にしているためです。
exit と入力して、Alpine コンテナを終了します。
exit
複数のネットワークへのコンテナの接続
コンテナは、複数のネットワークに接続できます。別のネットワークを作成しましょう。
docker network create another-network
既存の web-server コンテナをこの新しいネットワークに接続します。
docker network connect another-network web-server
コンテナが両方のネットワークに接続されていることを確認します。
docker inspect web-server -f '{{json .NetworkSettings.Networks}}' | json_pp
コンテナが my-network と another-network の両方に接続されていることがわかるはずです。
ポート公開を使用したコンテナの実行
コンテナのサービスを Docker ホストの外部からアクセスできるようにするには、そのポートを公開する必要があります。
docker run --name public-web -p 8080:80 -d nginx
このコマンドは、ホストのポート 8080 をコンテナのポート 80 にマッピングします。NGINX Web サーバーには、次を使用してアクセスできます。
curl http://localhost:8080
NGINX ウェルカムページが表示されるはずです。
クリーンアップ
作成したコンテナとネットワークをクリーンアップしましょう。
docker stop web-server alpine public-web
docker rm web-server alpine public-web
docker network rm my-network another-network
コンテナとネットワークが削除されたことを確認します。
docker ps -a
docker network ls
コンテナ通信の理解
このステップでは、Docker ネットワーキングがどのようにして以下を可能にするかを示しました。
- カスタムネットワークを使用したコンテナ間の通信
- コンテナ名を使用した DNS 解決
- 複数のネットワークへのコンテナの接続
- ポート公開を使用したコンテナサービスの外部への公開
これらのネットワーキング機能は、コンポーネントが互いに、そして外部サービスと通信する必要がある、複雑なマルチコンテナアプリケーションを構築するために不可欠です。
まとめ
この Docker 実験を完了したことをおめでとうございます!コンテナベースの開発とデプロイメントの基盤となる、Docker の重要な概念とスキルを習得しました。
この実験では、以下のことを行いました。
- Docker のインストールを確認し、最初のコンテナを実行しました
- Docker Hub からイメージをプルし、コンテナのライフサイクルを管理するなど、Docker イメージとコンテナを操作しました
- Dockerfile を使用して、独自のカスタム Docker イメージを作成しました
- Docker ボリュームを使用して、コンテナのライフサイクル間でデータを永続化しました
- Docker ネットワーキングを探索し、コンテナ間の通信を可能にしました
これらのスキルにより、次のことが可能になります。
- アプリケーションとその依存関係をポータブルなコンテナにパッケージ化する
- 開発、テスト、本番環境の標準化された環境を作成する
- 各コンポーネントが独自のコンテナで実行されるマイクロサービスアーキテクチャを実装する
- ステートフルアプリケーションのデータ永続性を確保する
- 適切な分離と通信を備えた複雑なマルチコンテナアプリケーションを構築する
Docker は、最新のソフトウェア開発において不可欠なツールとなっており、習得した知識は、幅広い開発および運用シナリオで役立ちます。



