homebrew でDockerをインストールする方法

インストール手順

一番簡単:HomebrewでDocker Desktopを入れる

Docker DesktopはDockerエンジン用のLinux VMやComposeなどをまとめて提供します

# 公式のCask(推奨)
brew install --cask docker-desktop

# もしくは一部の環境では下記でも可
# brew install --cask docker

インストール後に「アプリケーション」から Docker を起動し、メニューバーのクジラアイコンが安定したら利用できます。初回は権限確認のダイアログが出ます

動作確認

docker --version
docker run hello-world

商用利用のライセンス条件(従業員251名以上または年商1000万USD超は有償)がある点に注意してください。公式ドキュメントの「Install Docker Desktop on Mac」に記載があります。Docker Documentation
Homebrew側のCask名は「docker-desktop」です。Homebrew Formulae

Homebrewにおける「Cask」とは

--cask「これはGUIアプリなので、Homebrewにアプリケーションとして扱ってほしい」 という指示です。

  • Homebrew には大きく分けて2種類のパッケージがあります
    1. Formula(フォーミュラ): 主にコマンドラインツールやライブラリ。ターミナルで使うCLI系のソフト。
      例: brew install wget
    2. Cask(カスク): GUIアプリケーションやmacOSアプリを対象とした仕組み。
      例: brew install --cask google-chrome

なぜ分かれているのか

  • CLIツールは基本的にソースコードやバイナリを /usr/local/ などに展開すれば動く
  • GUIアプリ(.app)は /Applications に配置し、アイコンや依存サービスも扱う必要がある
  • その違いを吸収するために「cask」という仕組みが用意されています

使用例

# CLIツール
brew install git

# GUIアプリ(caskを明示)
brew install --cask docker-desktop
brew install --cask visual-studio-code

補足

  • 最近のHomebrewでは brew install google-chrome と書いても内部的にcaskを解決してくれる場合が多いですが、明示的に --cask を付けると「GUIアプリをインストールする」と意図を示せるので分かりやすいです。

エラーが出る場合

brew install --cask docker-desktopと打って、パスワードも入力して、順調だと思ってたらエラーになる場合がある。

例:Error: It seems there is already a Binary at '/usr/local/bin/hub-tool'.など

以前に Docker Desktop を入れたことがある場合、アンインストールしてもその残骸が残っている場合があり、それがエラーの原因となる。

解決方法

  1. Finderで「Macintosh HD」を開いて「コマンド+Shift+. (ドット)」のショートカットで隠しファイルを表示
  2. usr/lobal/binというフォルダに移動して「docker」という文字があるファイルを全て削除する
  3. あとは再度brew install --cask docker-desktopを実行する

Dockerの動作確認

まずはhello-world

docker run hello-worldというコマンドでいろいろ文字が出てきたら成功。hello-world は「起動→メッセージを標準出力に表示→正常終了(exit 0)」というだけの、瞬間的に終わるコンテナです。常駐もしません。

補足ポイント

  • docker run hello-world は、イメージがなければ pull してから起動し、メッセージを表示してすぐ終了します。
  • 終了したコンテナはプロンプトが戻った後も履歴として残ります(ステータスは Exited)。
  • もう一度メッセージを見たい場合は、直後ならその場の出力、後からならログや履歴を確認します。

便利コマンド

# 終了したコンテナも含めて一覧
docker ps -a

# 直前(または指定)のコンテナのログを再確認
docker logs <CONTAINER_ID_OR_NAME>

# 実行後に自動でコンテナを消す
docker run --rm hello-world

# たまった停止コンテナを一括掃除
docker container prune

対照例:ずっと動き続けるタイプ(常駐)は nginx などがあります。docker run -d -p 8080:80 nginx は終了せずバックグラウンドで待ち続けます。

PostgreSQLを使ってみる

  1. 作業用フォルダを作る
mkdir -p ~/pg-play && cd ~/pg-play
  1. compose.yml を作る(コピーして貼り付け)
# compose.yml
services:
  db:
    image: postgres:16
    container_name: pg
    environment:
      POSTGRES_PASSWORD: postgres
      POSTGRES_USER: postgres
      POSTGRES_DB: playground
      TZ: Asia/Tokyo
    ports:
      - "5432:5432"
    volumes:
      - ./pgdata:/var/lib/postgresql/data
      - ./initdb:/docker-entrypoint-initdb.d

  adminer:
    image: adminer:latest
    container_name: adminer
    ports:
      - "8080:8080"   # ブラウザは http://localhost:8080
    depends_on:
      - db
  1. データ保存用ディレクトリを用意
mkdir -p pgdata initdb
  1. 起動
docker compose up -d
  1. 動作確認
docker compose ps
docker logs -f pg    # 起動ログを確認、Ctrl+Cで抜ける

ブラウザで http://localhost:8080 を開き、Adminerのログイン画面で次を入力
サーバー: db / ユーザー: postgres / パスワード: postgres / データベース: playground

使い方の基本コマンド

docker compose ps                 # 稼働中の確認
docker compose logs -f            # 全サービスのログ追跡
docker compose exec db psql -U postgres -d playground   # psqlで接続
docker compose restart            # 再起動
docker compose stop               # 停止
docker compose start              # 再開
docker compose down               # 停止してコンテナ削除(データは残る)
docker compose down -v            # ボリュームも削除(データも消えるので注意)

よくあるつまずき

  • ポートが既に使われている:address already in use が出たら、5432や8080が他のプロセスで使用中。ports の番号を変えるか、該当プロセスを止める。
  • YAMLのインデント崩れ:スペース2個を基準にコピペ。タブは使わない。

適当なテーブルを作成

Adminerの「SQL」タブに貼り付けて実行してください。PostgreSQL向けに、よくある顧客・注文テーブルとサンプルデータを用意しました。

-- 顧客テーブル
CREATE TABLE IF NOT EXISTS customers (
  id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  name        TEXT        NOT NULL,
  email       TEXT        UNIQUE,
  created_at  TIMESTAMPTZ NOT NULL DEFAULT now()
);

-- 注文テーブル
CREATE TABLE IF NOT EXISTS orders (
  id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  customer_id BIGINT      NOT NULL REFERENCES customers(id) ON DELETE CASCADE,
  amount      NUMERIC(10,2) NOT NULL CHECK (amount >= 0),
  status      TEXT        NOT NULL DEFAULT 'pending' CHECK (status IN ('pending','paid','canceled')),
  ordered_at  TIMESTAMPTZ NOT NULL DEFAULT now()
);

-- よく使う検索に効くインデックス
CREATE INDEX IF NOT EXISTS idx_orders_customer_id ON orders(customer_id);
CREATE INDEX IF NOT EXISTS idx_orders_ordered_at  ON orders(ordered_at);

-- サンプルデータ投入
INSERT INTO customers (name, email) VALUES
  ('Alice', 'alice@example.com'),
  ('Bob',   'bob@example.com'),
  ('Carol', 'carol@example.com');

INSERT INTO orders (customer_id, amount, status) VALUES
  (1, 1200.50, 'paid'),
  (1,  300.00, 'pending'),
  (2,  999.99, 'canceled'),
  (3,   50.00, 'paid');

-- 動作確認のクエリ例(JOIN・集計)
-- 顧客ごとの注文合計金額
SELECT c.id, c.name, SUM(o.amount) AS total_amount
FROM customers c
JOIN orders o ON o.customer_id = c.id
GROUP BY c.id, c.name
ORDER BY total_amount DESC;

-- 直近の注文一覧
SELECT o.id, c.name, o.amount, o.status, o.ordered_at
FROM orders o
JOIN customers c ON c.id = o.customer_id
ORDER BY o.ordered_at DESC;

さらにここからmetabaseを始める

既存の「db + adminer」の compose に Metabase を1サービス足して、初期セットアップを行います。最小構成と実務的に安全なDB権限の付け方を示します。

1) Metabase用のアプリDBとユーザーを作る

PostgreSQLコンテナに入り、Metabaseの設定保存用DBを作成します。

docker compose exec db psql -U postgres -d postgres -c "CREATE USER metabase WITH PASSWORD 'metabase';"
docker compose exec db psql -U postgres -d postgres -c "CREATE DATABASE metabase OWNER metabase ENCODING 'UTF8';"

練習用途なので単純なパスワードで示しています。実運用では強固なものに変更してください。

2) compose.yml に Metabase を追加

既存の compose.yml に下記サービスを追記します。

  metabase:
    image: metabase/metabase:latest
    container_name: metabase
    ports:
      - "3000:3000"          # ブラウザ http://localhost:3000
    environment:
      MB_DB_TYPE: postgres
      MB_DB_DBNAME: metabase
      MB_DB_PORT: 5432
      MB_DB_USER: metabase
      MB_DB_PASS: metabase
      MB_DB_HOST: db        # 同じcompose内のPostgresサービス名
      MB_SITE_URL: "http://localhost:3000"
    depends_on:
      - db

起動

docker compose up -d metabase
docker compose logs -f metabase   # 起動完了まで確認、Ctrl+Cで抜ける

3) 初期セットアップ

ブラウザで http://localhost:3000 を開き、ウィザードに従って管理ユーザーを作成します。
次に「データベースを追加」で、分析対象DBを登録します。いまの構成では playground データベースが対象です。


サーバー名 db
ポート 5432
データベース名 playground
ユーザー postgres
パスワード postgres

すぐにダッシュボードやクエリの作成ができます。

ただしサンプルのデータベースもあるので、そちらの方がデータがたくさんあって練習に使いやすい。

一旦終了する場合のコマンド

使っているのが docker compose 構成なので、以下が基本です。

停止(コンテナは残す)

# すべてのサービスを停止
docker compose stop

# 特定サービスだけ停止(例: Metabase)
docker compose stop metabase

削除して片付け(ネットワーク等も整理)

# 停止+コンテナ削除(ボリュームは残るのでデータは維持)
docker compose down

# さらにボリュームも削除(データが消えるので注意)
docker compose down -v

# 使わないイメージも消す場合
docker compose down --rmi all

再開

# 停止していたコンテナを再起動
docker compose start

# コンテナがない場合や構成を変更した後は再作成して起動
docker compose up -d

補足
今回の例では ./pgdata をボリュームマウントしているため、docker compose down までならデータは残ります。down -v を実行すると pgdata の中身も消えるため注意してください。

明日もすぐ再開したいなら docker compose stop を推奨。down でも問題はありませんが、再起動時の手順と挙動が少し変わります。

推奨(明日すぐ再開したい)

# 今日の作業終了
docker compose stop

# 明日再開
docker compose start

メリット: コンテナが残るため再作成が不要で起動が速い。データはこれまで通り保持。

down を使う場合

# 今日の作業終了(コンテナを削除)
docker compose down

# 明日再開(コンテナを再作成して起動)
docker compose up -d

今回の構成は Postgres のデータを ./pgdata にバインドマウントしているので、down でもデータは残る。adminer は状態を持たない。metabase は設定DBを Postgres に置いているため、こちらも設定は保持される。ただし docker compose down -v はボリューム削除なので実データが消える。

メモリやプロセッサの使用を抑えたい(コンテナは残して止めたい)なら stop、ディスク上のコンテナを一度片付けたいなら down を選ぶとよい。

-Docker, 環境構築
-