Mac で Docker コマンドが見つからない:トラブルシューティングと環境設定

DockerBeginner
オンラインで実践に進む

はじめに

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+OEnter の順に押してファイルを保存し、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 の主要なコンポーネントを確認しましょう。

  1. FROM node:14-alpine: 使用するベースイメージを指定します
  2. WORKDIR /usr/src/app: コンテナ内の作業ディレクトリを設定します
  3. COPY package.json ./: ホストからコンテナにファイルをコピーします
  4. RUN npm install: ビルドプロセス中にコンテナ内でコマンドを実行します
  5. EXPOSE 3000: コンテナがポート 3000 でリッスンすることをドキュメント化します
  6. 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-networkanother-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 ネットワーキングがどのようにして以下を可能にするかを示しました。

  1. カスタムネットワークを使用したコンテナ間の通信
  2. コンテナ名を使用した DNS 解決
  3. 複数のネットワークへのコンテナの接続
  4. ポート公開を使用したコンテナサービスの外部への公開

これらのネットワーキング機能は、コンポーネントが互いに、そして外部サービスと通信する必要がある、複雑なマルチコンテナアプリケーションを構築するために不可欠です。

まとめ

この Docker 実験を完了したことをおめでとうございます!コンテナベースの開発とデプロイメントの基盤となる、Docker の重要な概念とスキルを習得しました。

この実験では、以下のことを行いました。

  • Docker のインストールを確認し、最初のコンテナを実行しました
  • Docker Hub からイメージをプルし、コンテナのライフサイクルを管理するなど、Docker イメージとコンテナを操作しました
  • Dockerfile を使用して、独自のカスタム Docker イメージを作成しました
  • Docker ボリュームを使用して、コンテナのライフサイクル間でデータを永続化しました
  • Docker ネットワーキングを探索し、コンテナ間の通信を可能にしました

これらのスキルにより、次のことが可能になります。

  • アプリケーションとその依存関係をポータブルなコンテナにパッケージ化する
  • 開発、テスト、本番環境の標準化された環境を作成する
  • 各コンポーネントが独自のコンテナで実行されるマイクロサービスアーキテクチャを実装する
  • ステートフルアプリケーションのデータ永続性を確保する
  • 適切な分離と通信を備えた複雑なマルチコンテナアプリケーションを構築する

Docker は、最新のソフトウェア開発において不可欠なツールとなっており、習得した知識は、幅広い開発および運用シナリオで役立ちます。