はじめに — なぜ今ふたたび話題なのか
macOSでコンテナを動かすことは、長らく「Linux VMを1台立ち上げて、その中でDockerを動かすこと」と同義でした。Docker Desktop、Lima、Colima、OrbStackは実装の詳細こそ異なりますが、大きな構図は同じでした。ところがAppleがWWDC25でオープンソースとして公開したapple/containerは、この前提を覆しました。コンテナ1つにつき軽量VMを1つ、1対1で割り当てるモデルを打ち出したのです。
そして2026年6月、WWDC26で発表されたContainer Machine機能がGeekNewsとHacker Newsを再び沸かせました。ホームディレクトリとストレージを自動マウントする汎用Linuxマシンモードが追加され、「LimaやWSLのような開発用Linux環境までApple純正ツールで解決できるのではないか」という反応が殺到しました。GeekNewsのコメント欄では、Docker Desktopのライセンス費用に疲れた企業ユーザーの歓迎と、「composeエコシステムなしでは乗り換えられない」という現実論がぶつかり合いました。
折しもAIコーディングエージェントの普及により、隔離された実行環境への需要も爆発しています。Claude Codeのようなエージェントが数時間にわたり自律的にコードをビルド・テストする時代において、エージェントごとに強く隔離されたサンドボックスを素早く作って壊せる能力は、単なる利便性ではなくセキュリティ要件になりました。2026年6月のnpmサプライチェーン攻撃がRed Hat Cloud Servicesにまで侵入した事件以降は、なおさらです。
本記事では、Docker DesktopのmacOS構造が抱える根本的な限界から、apple/containerのアーキテクチャ、Container Machine、実践的な使い方、そして乗り換え時に確認すべきチェックリストまで、順に見ていきます。
背景 — macOSでコンテナが難しい理由
まず前提を明確にしておきましょう。私たちが普段コンテナ(OCIコンテナ)と呼ぶものは、Linuxカーネル機能の組み合わせです。namespaceでプロセス・ネットワーク・ファイルシステムのビューを隔離し、cgroupでリソースを制限し、OverlayFSでイメージレイヤーを合成します。すべてLinuxカーネルにしかない機能です。
macOSのXNUカーネルにはこれらの機能がありません。したがってmacOSでLinuxコンテナを動かすには、必ずどこかにLinuxカーネルが必要であり、それはつまり仮想マシンが必要だということです。すべてのmacOSコンテナツールの違いは、結局のところ「VMをどのように、何台、どれだけ軽く立ち上げるか」の違いなのです。
Docker Desktopの構造 — 単一巨大VMの光と影
Docker DesktopはmacOS上にLinux VMを1台立ち上げ、その中でdockerd(Dockerデーモン)を実行します。すべてのコンテナは、この単一VMの中で兄弟プロセスとして動作します。
+---------------------------------------------------------------+
| macOS Host |
| |
| docker CLI ----(API)----> +--------------------------------+ |
| | Linux VM (single, shared) | |
| Docker Desktop GUI | | |
| | dockerd + containerd | |
| | +-----------+ +-----------+ | |
| | | container | | container | | |
| | | A | | B | | |
| | +-----------+ +-----------+ | |
| | +-----------+ +-----------+ | |
| | | container | | container | | |
| | | C | | D | | |
| | +-----------+ +-----------+ | |
| +--------------------------------+ |
+---------------------------------------------------------------+
この構造の利点は明確です。LinuxサーバーでDockerを使っていた経験がほぼそのまま移植でき、VMが1台なのでイメージキャッシュとネットワークをすべてのコンテナが共有します。composeで複数コンテナをまとめても同じVM内なので通信が高速です。
しかし、限界も構造から生じます。
第一に、リソースの先取り問題です。VM 1台にCPUコアとメモリをあらかじめ大きく割り当てる必要があり、コンテナを1つも動かしていなくてもそのリソースは確保されたままです。8GBを割り当てたVMは、アイドル状態でもmacOSのメモリ圧迫に寄与します。
第二に、隔離の弱さです。すべてのコンテナが同じカーネルを共有するため、コンテナエスケープの脆弱性が1つ発生すると、同じVM内の他のすべてのコンテナが影響圏に入ります。信頼できないコード(例:AIエージェントが生成したコード、外部PRのCIビルド)を動かすには不安な構造です。
第三に、ファイル共有のパフォーマンスです。macOSのディレクトリをVM内にバインドマウントするには、VirtioFSやgRPC FUSEのようなファイルシステムブリッジを経由する必要があり、これは長年Docker Desktopの性能不満の定番ネタでした。
第四に、ライセンス費用です。Docker Desktopは一定規模以上の企業では有料サブスクリプションが必要です。これがColimaとOrbStackが成長した直接的な背景でもあります。
apple/containerのアプローチ — コンテナ = 軽量VM
apple/containerは発想を変えました。コンテナを共有VM内のプロセスにする代わりに、コンテナ1つごとに専用の軽量VMを立ち上げます。
+---------------------------------------------------------------+
| macOS Host |
| |
| container CLI (Swift) |
| | |
| | Virtualization.framework / Containerization package |
| v |
| +-------------+ +-------------+ +-------------+ |
| | micro VM 1 | | micro VM 2 | | micro VM 3 | |
| | | | | | | |
| | linux kernel| | linux kernel| | linux kernel| |
| | vminitd | | vminitd | | vminitd | |
| | container A | | container B | | container C | |
| +-------------+ +-------------+ +-------------+ |
| |
| VMの数 = 実行中のコンテナの数 (1対1) |
+---------------------------------------------------------------+
主要な構成要素を1つずつ見ていきましょう。
Virtualization.framework
AppleがmacOS Big Surから提供している高水準の仮想化フレームワークです。Hypervisor.frameworkの上に構築され、virtioベースのディスク・ネットワーク・メモリバルーンデバイスを提供します。Apple Siliconに最適化されており、VMの作成と起動が非常に高速です。LimaやUTMのような既存ツールもすでにこのフレームワークをバックエンドとして使ってきましたが、apple/containerはこれをコンテナ単位の隔離に直接使う点が異なります。
Containerization Swiftパッケージ
apple/containerの基盤となるライブラリで、こちらもオープンソースです。OCIイメージのプルと展開、軽量Linuxルートファイルシステムの構成、VMの起動、コンテナプロセスの実行までをSwift APIとして提供します。起動時間を短縮するために最小化されたLinuxカーネル構成を使い、initシステムにはSwiftで書かれたvminitdを使用します。vminitdはsystemdのような汎用initではなく、コンテナプロセス1つを起動するために必要な最小機能だけを持つ専用initです。その結果、コンテナ(つまりVM)の起動は1秒未満のレベルまで短縮されます。
デーモンレス設計
Dockerのdockerdのような常駐rootデーモンがありません。container CLIが必要なときにヘルパープロセスを起動する構造のため、攻撃対象領域が減り、アイドル時にリソースを消費しません。VM自体もコンテナの終了とともに消えるため、「使っていないのに8GBを占有するVM」という問題が構造的に存在しません。
WWDC26 — Container Machine機能
WWDC25のapple/containerが「コンテナの実行」に集中していたとすれば、WWDC26で追加されたContainer Machineは汎用Linux開発環境へと領域を広げました。GeekNewsで話題になった核心ポイントは次のとおりです。
第一に、ホームディレクトリの自動マウントです。マシンを作成すると、macOSのホームディレクトリがLinuxマシン内に自動でマウントされ、特別な設定なしにホストのファイルをそのまま扱えます。LimaでマウントをYAMLで手作業設定していた経験と比べると、参入障壁が大幅に下がりました。
第二に、ストレージの自動構成です。マシン専用のディスクイメージが自動的に作成・管理されるため、ユーザーがディスクサイズやフォーマットを事前に悩む必要がありません。
第三に、WSLに似た使い勝手です。コマンド1行でLinuxシェルに入り、ホストとファイルを自然に共有する流れは、WindowsのWSL体験に似ています。「macOSのWSLの瞬間が来た」というコメントが多かった理由です。
これによりapple/containerは2つのモードを持つことになりました。短命で強く隔離されるコンテナモードと、長く生きてホストと密に統合されるマシンモードです。AIコーディングエージェントのサンドボックスには前者を、日常の開発環境には後者を使うという絵が自然でしょう。
アーキテクチャ比較 — 4つのツール
macOSコンテナツール4種の構造を1枚で比較すると次のようになります。
[Docker Desktop] [Lima / Colima]
macOS macOS
| |
+-- 単一共有VM +-- 単一共有VM (QEMU または VZ)
| |
+-- dockerd +-- containerd / dockerd
+-- コンテナN個 +-- コンテナN個
[OrbStack] [apple/container]
macOS macOS
| |
+-- 単一共有VM (独自最適化) +-- micro VM 1 -- コンテナ1
| +-- micro VM 2 -- コンテナ2
+-- コンテナN個 +-- micro VM N -- コンテナN
(カーネル共有なし、VM対コンテナ = 1対1)
主な特性を表に整理します。執筆ルール上、表内に特殊文字を使えないため数値は言葉で表しています。
| 項目 | Docker Desktop | LimaとColima | OrbStack | apple container |
| --- | --- | --- | --- | --- |
| VMモデル | 単一共有VM | 単一共有VM | 単一共有VM | コンテナごとにVM |
| カーネル共有 | 全コンテナで共有 | 全コンテナで共有 | 全コンテナで共有 | 共有なし |
| デーモン | dockerd常駐 | containerd常駐 | 独自デーモン常駐 | デーモンレス |
| 隔離レベル | プロセス隔離 | プロセス隔離 | プロセス隔離 | ハードウェア仮想化隔離 |
| ライセンス | 企業は有料 | オープンソース | 個人無料・企業有料 | オープンソース Apache 2 |
| compose対応 | 公式対応 | docker互換で対応 | 公式対応 | 未対応 |
| 実装言語 | Go中心 | Go中心 | 非公開 | Swift |
| アイドル時のリソース | VM割当分を常時占有 | VM割当分を常時占有 | 動的に調整 | コンテナなしならほぼゼロ |
実践的な使い方
インストール
Apple Silicon MacとmacOS 15以降が必要で、ネットワーキング機能をフルに使うにはmacOS 26以降が推奨されます。GitHubリリースから署名済みインストーラーパッケージを取得するか、Homebrewでインストールします。
Homebrewでインストール
brew install --cask container
APIサービス(ヘルパー)の起動 — 初回のみ
container system start
状態確認
container system status
イメージのプルとコンテナの実行
Dockerユーザーならコマンド体系に馴染みがあるはずです。
イメージのプル (Docker HubのOCIイメージをそのまま使用)
container image pull alpine:latest
対話型コンテナの実行 — この1行が専用VMをブートする
container run -it alpine:latest sh
バックグラウンド実行とポート公開
container run -d --name web -p 8080:80 nginx:latest
実行中のコンテナの確認
container list
ログと終了
container logs web
container stop web
container delete web
体感的に最も印象的なのは起動速度です。container runコマンドがカーネルブートを含むにもかかわらず、1秒未満でシェルが返ってきます。「VMだから遅いはず」という直感が崩れる瞬間です。
イメージのビルド
Dockerfileをそのまま使えます。ビルドはBuildKitを実行する専用ビルダーVMで行われます。
ビルダーの起動 (初回のみ、リソース指定可能)
container builder start --cpus 4 --memory 8g
Dockerfileベースのビルド
container build --tag myapp:dev --file Dockerfile .
マルチアーキテクチャビルド (arm64 + amd64)
container build --arch arm64 --arch amd64 --tag myapp:multi .
レジストリへのプッシュ
container registry login ghcr.io
container image push ghcr.io/myorg/myapp:dev
ごく普通のDockerfileがそのまま動く
FROM golang:1.24-alpine AS build
WORKDIR /src
COPY . .
RUN go build -o /out/server ./cmd/server
FROM alpine:3.21
COPY --from=build /out/server /usr/local/bin/server
EXPOSE 8080
ENTRYPOINT ["server"]
ボリュームとファイル共有
ホストディレクトリはvirtioベースの共有でVM内にマウントされます。
カレントディレクトリをコンテナの /work にマウント
container run -it --volume "$PWD:/work" --workdir /work alpine:latest sh
名前付きボリュームの作成と使用
container volume create pgdata
container run -d --name db --volume pgdata:/var/lib/postgresql/data postgres:17
ネットワーキング
macOS 26以降では、コンテナごとに専用のIPアドレスが付与されます。同じVM内でポートを分け合うDocker Desktopモデルとは異なり、コンテナ間通信が実際のネットワークトポロジーに近い形で動作します。
コンテナのIP確認
container list --format json
ユーザー定義ネットワークの作成 (macOS 26以降)
container network create devnet
container run -d --network devnet --name api myapp:dev
container run -d --network devnet --name cache redis:7
devnet内では名前で互いに到達できる
Rosettaでamd64イメージを実行する
Apple Siliconでamd64(x86_64)専用イメージを動かす必要があるときは、Rosetta 2のバイナリ変換を使います。Virtualization.frameworkはLinux VM内のx86_64バイナリをRosettaで実行する機能を提供しており、apple/containerはこれをそのまま活用します。QEMUエミュレーションと比べて体感速度が大幅に速くなります。
amd64イメージを明示的に指定して実行
container run --arch amd64 -it amazonlinux:2023 bash
マルチアーチのマニフェストがある場合、デフォルトはarm64が選ばれる
container image pull --arch amd64 mysql:8.4
ただしRosetta変換にも限界はあります。AVX512のような一部の命令セット拡張はサポートされず、JITを多用するワークロードではネイティブarm64との性能差が広がることがあります。可能であればマルチアーチイメージをビルドするのが正攻法です。
OCI互換性 — エコシステムはそのまま
apple/containerがDockerを置き換えられる決定的な理由は、OCI標準への準拠です。イメージフォーマットはOCI Image Spec、レジストリ通信はOCI Distribution Specに従うため、Docker Hub、GitHub Container Registry、Amazon ECRなどの既存レジストリをそのまま使えます。Dockerfileでビルドしたイメージは、LinuxサーバーのDockerでも、Kubernetesでも、クラウドランタイムでも同一に動作します。
つまり「ローカル開発はapple/container、デプロイは既存パイプラインのまま」という漸進的な導入が可能です。イメージに互換性があるため、チーム全体が一斉に乗り換える必要もありません。
パフォーマンスとセキュリティのトレードオフ
コンテナごとVMモデルの損益計算書を整理してみましょう。
| 観点 | 単一共有VM方式 | コンテナごとVM方式 |
| --- | --- | --- |
| 隔離の強さ | カーネル共有で弱い | ハードウェア仮想化で強い |
| カーネル脆弱性の影響 | 全コンテナに波及 | 該当VM 1つに限定 |
| メモリオーバーヘッド | VM 1台分を固定先取り | コンテナごとにカーネルとinitのコスト |
| 起動速度 | VMはすでに起動済み | カーネルブート込みで1秒未満 |
| アイドルコスト | 常にVM割当分を占有 | コンテナなしならほぼゼロ |
| コンテナ間通信 | 同一カーネル内で高速 | 仮想ネットワーク経由 |
| 多数コンテナの実行 | リソース共有で有利 | VMの数だけオーバーヘッド累積 |
隔離の強化は明確な利得です。カーネルを共有しないため、コンテナエスケープ脆弱性の爆発半径がVM 1つに限定されます。AWSがLambdaをFirecracker microVMの上に載せたのと同じ論理であり、信頼境界が不明瞭なコード(外部コントリビューションのCI、AIエージェントの成果物)を扱う環境では特に重要です。
一方、メモリオーバーヘッドは実在します。VMごとにゲストカーネル、ページテーブル、vminitdが載るため、コンテナあたり数十MBレベルの固定コストが追加されます。コンテナを2〜3個立ち上げる一般的な開発シナリオでは、むしろ単一巨大VMより総占有量が小さくなりますが、マイクロサービスを20個同時に立ち上げるシナリオでは累積オーバーヘッドを計算する必要があります。メモリバルーニングがアイドルVMのメモリを回収してくれますが、万能ではありません。
実践シナリオ — AIコーディングエージェントのサンドボックス構築
隔離強化が最も輝く実践事例を1つ作ってみましょう。AIコーディングエージェントに外部リポジトリのコードをビルド・テストさせる作業です。エージェントが何を実行するか事前にわからないため、タスク単位で使い捨てVMを作り、終わったら痕跡なく破棄するパターンが適しています。
#!/bin/bash
agent-sandbox.sh — エージェントのタスクごとに使い捨ての隔離コンテナを作る
set -euo pipefail
TASK_ID="$1"
REPO_URL="$2"
SANDBOX_NAME="agent-${TASK_ID}"
1. タスク専用ボリュームの作成 (成果物の回収用)
container volume create "${SANDBOX_NAME}-out"
2. リソース制限付きの使い捨てコンテナを実行
- ホストディレクトリはマウントしない (ホームディレクトリへのアクセスを遮断)
- 成果物ボリュームだけを書き込み可能で接続
container run --rm \
--name "${SANDBOX_NAME}" \
--cpus 2 --memory 4g \
--volume "${SANDBOX_NAME}-out:/out" \
ubuntu:24.04 \
bash -c "git clone ${REPO_URL} /src && cd /src && make test 2>&1 | tee /out/test.log"
3. 結果だけを回収してボリュームを整理
container run --rm --volume "${SANDBOX_NAME}-out:/out" alpine:latest cat /out/test.log
container volume delete "${SANDBOX_NAME}-out"
このパターンの核心は3つです。第一に、エージェントのコードがコンテナをエスケープしても、到達するのは最小構成の使い捨てゲストカーネルだけであり、他のタスクやホストではありません。第二に、ホストのファイルシステムを一切マウントしないことで、機密情報の流出経路を遮断します。第三に、runコマンドのrmオプションにより、タスク終了と同時にVMとコンテナが一緒に消滅するため、残留状態が蓄積しません。単一共有VMモデルでは第一の保証を作れないという点が決定的な違いです。
運用のヒントとトラブルシューティング
数ヶ月使っていると出会う運用上の問題と対処法を整理します。
ディスク使用量の管理
イメージとビルダーキャッシュは溜まります。定期的に整理するのが良いでしょう。
未使用イメージの整理
container image prune
ビルダーVMの停止と再起動 (キャッシュ初期化の効果)
container builder stop
container builder delete
container builder start --cpus 4 --memory 8g
プライベートレジストリの認証問題
企業環境のプライベートレジストリは認証トークンの期限切れが頻発します。まずログイン状態を疑いましょう。
認証情報の更新
container registry login registry.internal.example.com
プルに失敗したら詳細ログで原因を確認
container --debug image pull registry.internal.example.com/team/app:latest
システムサービスが応答しないとき
ヘルパープロセスがおかしくなったら、システムサービスを再起動します。実行中のコンテナは終了するため注意が必要です。
container system stop
container system start
container system logs # 問題が繰り返される場合はログを確認
メモリ使用量の点検
コンテナごとVMモデルでは、総メモリ占有量をときどき確認する習慣が良いでしょう。コンテナごとの割当量を明示すると予測可能性が上がります。
コンテナごとのリソースを明示する習慣
container run -d --name api --cpus 2 --memory 1g myapp:dev
実行中のコンテナと状態の確認
container list --all
既存ツールから乗り換える際のチェックリスト
Docker DesktopやColimaからapple/containerに移行する前に、次の点を確認してください。
1. composeへの依存度の確認。docker-compose.ymlでマルチコンテナスタックを管理している場合、現時点では直接の対応物がありません。コンテナを個別に実行するスクリプトに展開するか、composeが必須のプロジェクトでは既存ツールを併用する必要があります。
2. TestcontainersなどDocker API依存ツールの確認。DockerソケットAPIを直接呼ぶテストライブラリは動作しない可能性があります。チームの統合テスト構成を先に点検しましょう。
3. macOSバージョンの確認。macOS 15では一部のネットワーキング機能(コンテナごとのIP、ユーザー定義ネットワーク)に制約があります。チーム全員がmacOS 26以降かどうか確認するのが良いでしょう。
4. amd64依存イメージの棚卸し。Rosettaでほとんど解決できますが、カーネルモジュールや特殊命令に依存するイメージは事前にテストすべきです。
5. CIとの整合性。ローカルがapple/container、CIがLinux Dockerの場合、イメージ互換性は問題ありませんが、ネットワーキングとボリューム動作の違いがテスト結果に影響することがあります。
6. ローカルKubernetesクラスタの必要性。kindやminikubeのようにDockerの上にクラスタを構築するツールを使っているなら、当面は既存環境の維持が現実的です。
7. 漸進的な導入戦略の策定。イメージがOCI互換なので、ビルドと単一コンテナの実行から移行し、マルチコンテナ開発環境はゆっくり移す2段階戦略が安全です。
限界と批判的視点
バランスのために批判的な観点も整理します。
Linux専用機能の不在。単一VMツールはVMの中が丸ごとLinuxなので、特権コンテナ、カーネルモジュールのロード、eBPFデバッグといった作業が可能です。コンテナごとmicroVMモデルではゲストカーネルが最小構成のため、こうした高度なシナリオに制約があります。Container Machineモードが一部を埋めてくれますが、コンテナモードとは別の流れです。
composeエコシステムの空白。現代の開発ワークフローにおいてcomposeは事実上の標準です。「dbが1つ、キャッシュが1つ、アプリが1つ」を宣言的に立ち上げる体験なしにCLIコマンドを並べるのは、明らかな後退に感じられるでしょう。コミュニティで互換レイヤーの試みが進行中ですが、公式サポートはまだありません。
Appleエコシステムへの従属。このツールはApple Silicon専用で、macOSのバージョンに依存します。チームにLinuxデスクトップユーザーが混ざっている場合、共通ツールにはなれません。また、Appleのオープンソースプロジェクトが長期的にどれだけ活発に維持されるかへの懐疑論も、Hacker Newsで繰り返し提起されています。
成熟度。Docker Desktopには10年分のエッジケース対応が蓄積されています。新興ツールは、レジストリ認証方式、プロキシ環境、企業VPNといった現実世界の泥臭い条件で磨かれる時間がもっと必要です。
展望
それでも方向性は明確に見えます。第一に、隔離の強化は時代の要求です。サプライチェーン攻撃とAIエージェントのサンドボックス需要が拡大するほど、ハードウェア仮想化による隔離の価値は上がります。第二に、OSベンダー自身がコンテナランタイムを提供するという事実そのものがゲームチェンジャーです。WindowsにWSLが入って生じた変化を思い起こせば、Container MachineはmacOS開発環境のデフォルトを変える潜在力を持っています。第三に、Containerizationがライブラリとして公開されているため、サードパーティツールがこれをバックエンドとして採用するエコシステム再編も可能です。実際、既存ツールがバックエンドオプションとして検討中だという議論がコミュニティで交わされています。
当面は「ビルドと隔離実行はapple/container、composeスタックは既存ツール」というハイブリッドが現実的な最適解でしょう。しかしcomposeの空白が埋まった瞬間、重心は急速に移動する可能性があります。
おわりに
apple/containerは「macOSにおけるコンテナは結局VMである」という古くからの事実を隠すのではなく、VMをコンテナ並みに軽くすることで正面突破したプロジェクトです。コンテナごとの軽量VMという設計は、隔離とアイドルコストにおいて単一VMモデルを上回り、RosettaとOCI互換性によって実用性も確保しました。WWDC26のContainer Machineは、そこに日常の開発環境という領域まで加えました。
もちろん、composeエコシステムとLinuxの高度な機能という宿題は残っています。今すぐ全面移行を勧めるのは難しいですが、単一コンテナのワークフローと信頼できないコードのサンドボックス化からなら、十分に実戦投入が可能です。Docker Desktopの更新シーズンが来る前に、一度インストールしてcontainer runを実行してみてください。カーネルがブートする1秒間の体験が、思った以上に多くのことを物語ってくれます。
参考資料
- apple/container GitHubリポジトリ: https://github.com/apple/container
- apple/containerization GitHubリポジトリ: https://github.com/apple/containerization
- GeekNews関連トピック: https://news.hada.io/topic?id=30346
- Apple Virtualization.framework公式ドキュメント: https://developer.apple.com/documentation/virtualization
- apple/container公式チュートリアル: https://github.com/apple/container/blob/main/docs/tutorial.md
- OCI Image Format Specification: https://github.com/opencontainers/image-spec
- OCI Distribution Specification: https://github.com/opencontainers/distribution-spec
- Hacker Newsでのapple/container公開議論: https://news.ycombinator.com/item?id=44229348
- Limaプロジェクト: https://github.com/lima-vm/lima
- Colimaプロジェクト: https://github.com/abiosoft/colima
- Firecracker microVM (隔離モデルの比較参考): https://firecracker-microvm.github.io/
현재 단락 (1/196)
macOSでコンテナを動かすことは、長らく「Linux VMを1台立ち上げて、その中でDockerを動かすこと」と同義でした。Docker Desktop、Lima、Colima、OrbStackは実...