インストール手順
一番簡単: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種類のパッケージがあります
- Formula(フォーミュラ): 主にコマンドラインツールやライブラリ。ターミナルで使うCLI系のソフト。
例:brew install wget
- Cask(カスク): GUIアプリケーションやmacOSアプリを対象とした仕組み。
例:brew install --cask google-chrome
- Formula(フォーミュラ): 主にコマンドラインツールやライブラリ。ターミナルで使うCLI系のソフト。
なぜ分かれているのか
- 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 を入れたことがある場合、アンインストールしてもその残骸が残っている場合があり、それがエラーの原因となる。
解決方法
- Finderで「Macintosh HD」を開いて「コマンド+Shift+. (ドット)」のショートカットで隠しファイルを表示
usr/lobal/bin
というフォルダに移動して「docker」という文字があるファイルを全て削除する- あとは再度
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を使ってみる
- 作業用フォルダを作る
mkdir -p ~/pg-play && cd ~/pg-play
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
- データ保存用ディレクトリを用意
mkdir -p pgdata initdb
- 起動
docker compose up -d
- 動作確認
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
を選ぶとよい。