2026 Mac クラウドでの OpenClaw Docker:終了コード137/OOM、uid 1000 のボリューム権限、DNS、そして最短の openclaw doctor 手順
Mac クラウド上で OpenClaw を Docker で動かす運用者は、終了コード137、マウントした設定への Permission denied、ホストでは成功するのにコンテナ内では失敗する HTTPS などにぶつかり、イメージの再インストールに日数を溶かしがちです。本稿では読者像(レンタル Mac 上の SRE と個人開発者)、得られるもの(2026年の公式 Compose 運用に沿った順序付きチェックリストと症状マトリクス)、構成(まずメモリと cgroup、次に uid 1000 のボリューム、続いて Docker DNS、openclaw doctor、ポート18789、コンテナを捨ててネイティブ macOS に移る判断)を明示します。
目次
1. レディネスの三要素:プロセス稼働、ポート公開、ボリューム書き込み可能
公式の Docker および Docker Compose の流れは、OpenClaw ゲートウェイをコンテナに包みます。Mac クラウドのホストは依然として RAM と CPU クォータの所有者であり、~/.openclaw(またはカスタム設定ディレクトリ)をバインドマウントし、ループバック検査や SSH トンネル用に 18789 などの公開ポートを束ねます。手元のノート PC とは異なり、クラウド Mac はメモリ上限がきつめ、GUI セッションが無いことも多く、イメージ内ではしばしば root ではない node ユーザー(uid/gid 1000)で動くのが普通です。これらを腹落ちさせるまで、設定変更はいつもレイヤーを取り違えます。
レディネスを、チケットに貼れる三つの観測可能な事実として定義します。コンテナが実行中または healthyであること、docker compose ps で期待どおりの ports マッピングが見えること、openclaw status やヘルスプローブがコンテナ内部で権限エラーなく成功することです。モデル経路、Slack の Webhook、Cron は、この三つが緑になってからが本番です。典型的な Compose の誤りには、存在しないホストパス(Docker が root 所有のディレクトリを作ってしまう)、ゲートウェイが状態を永続化しなければならないのに読み取り専用マウントにしている、イメージレイヤーやビルドキャッシュで小さなルートボリュームを食いつぶす、などがあります。ランダムクラッシュに見えますが、df -h が真実を突きつけます。
Compose プロジェクト名、サービス名、公開ポート、設定とワークスペースの絶対パスを記録してください。アップグレード手順、Webhook の投稿、無言の Cron 切り分けと突き合わせるとき、その一行が何時間も節約します。誰もが同じトポロジーを見られ、どのマシンを指しているか推測する必要がなくなります。
2. つまずきの分解(番号付き)
- 終了コード137と OOM:Docker は Linux の cgroup メモリ上限をワークロードに投影します。カーネルの OOM キラーが動くと、Docker はしばしば終了コード137(128 + SIGKILL の9)として表に出します。イメージの pull や build は、ゲートウェイの定常トラフィックより遥かに RAM を食います。数時間「問題なく」動いていたノードが、
docker compose buildの数分で死ぬことは珍しくありません。137 がビルド段階か実行段階かを必ずメモしてください。処置が変わります。 - ボリュームの所有者対 uid 1000:ホスト上で
~/.openclawを root や個人ユーザーで作ると、コンテナ内のnodeプロセスはopenclaw.json、ログ、ワークスペースに書けません。失敗は明瞭なスタックトレースではなく、静かな起動ループとして現れることも多く、「リリースノートが悪い」と誤認されがちです。 - Docker DNS と企業のエグレス:ホストで
curl https://api.anthropic.comが成功し、docker exec … curlが失敗する場合、ほぼ確実にコンテナ側の DNS サーバ、HTTP(S)_PROXY 環境変数、TLS インターセプトプロキシ経由のトラストストアの見え方が原因です。ネットワーク経路を直す前に API キーを回すのは時間とクォータの浪費です。 - ヘルスチェックと依存関係のレース:寛い
start_periodなしに攻めたdepends_onは、接続拒否のログを溢れさせ、アプリケーションのバグに見えます。下流が叩く前にゲートウェイが listen していることを証明してください。
この四つの型が、Mac クラウドテナントで見る本番寄りインシデントの大半を説明します。下のマトリクスは、それらを最初の一手に圧縮したものです。
3. 症状から根本原因へのマトリクス
インシデント中の意思決定シートとして表を使います。最も近い症状を選び、二次仮説に進む前に「最初の対応」列を順に実行してください。
| 観測シグナル | 考えられる根本原因 | 最初の対応(優先順) |
|---|---|---|
再起動ループ、OOMKilled、終了137 | cgroup またはホストのメモリ逼迫 | Docker Desktop/Engine のメモリ割当や compose の mem_limit を増やす。競合する RAM 重いジョブを止める。並列レイヤーを減らしてビルドを再試行 |
設定やワークスペースで Permission denied | バインドマウントの uid が合っていない | ホストで sudo chown -R 1000:1000 /path/to/mount。compose で RW を確認。docker exec -u node … touch でテストファイルを検証 |
| HTTPS や DNS の失敗がコンテナ内だけ | コンテナのリゾルバまたはプロキシ環境の欠落 | docker exec で cat /etc/resolv.conf、curl -v。compose に dns: を足すか daemon.json を調整。企業プロキシは --env-file で渡す |
| プロセスは上がっているがリモートからポートに届かない | ポートマッピング、バインドアドレス、クラウドのセキュリティグループ | ports: を意図した 0.0.0.0 と 127.0.0.1 と比較。SG ルールを開く。ハードニング記事どおり SSH トンネルを優先 |
openclaw doctor が資格情報欠如と言うが compose は「設定した」 | 環境変数がコンテナプロセスに注入されていない | docker exec … env | grep OPENCLAW と compose の environment を突き合わせ。クォートと継承を修正 |
4. 順序付きの是正6ステップ(安易に並べ替えない)
順序は重要です。後のステップは、前で失敗のクラスを潰した前提を置きます。いきなりイメージのタグを変えると証拠が消えます。
- 状態の取得:
docker compose ps -aを実行し、続けてdocker logs <service> --tail 200。終了137がイメージ pull、ビルド、定常実行のどれで出たかを保存します。 - メモリ余裕の検証:ビルド用に一時的に Docker におおむね4〜8GB 以上を割り当て(プロバイダの文書に合わせて調整)。ホストでは
memory_pressureや Activity Monitor 相当を確認。激しいスワップとゲートウェイ負荷の組み合わせは、不安定な SIGKILL のレシピです。 - ボリューム所有者の正規化:コンテナが書き込むすべてのバインドパスに
chownを適用。OpenClaw に触る前に、コンテナ内 uid 1000 でささやかな書き込みテストを再実行します。 - コンテナネットワークの証明:コンテナ内から LLM プロバイダへ
curl -sIを当て、TLS が怪しければopenssl s_client。企業 MITM があるなら、ホストと同じトラスト素材やプロキシ変数をミラーします。 - 診断 CLI の実行:
openclaw doctor、openclaw status、openclaw models status(名称は現行 CLI に従う)を実行。上記の後も doctor がインストール系エラーで赤のままなら、初めて再インストールやイメージタグ変更を検討します。 - ポート18789での受け入れ:ホストから
curl -sI http://127.0.0.1:18789(またはマップしたポート)。リモート管理者は SSH トンネルやリバースプロキシを、セキュリティ記事のとおり検証します。
docker system prune -a は避けてください。レイヤーキャッシュとログ文脈を消し、平均修復時間を伸ばします。5. 引用可能な技術的事実(最低3つ、ここでは7つ)
- 終了137の意味:Docker ではまず OOM として扱う。
docker inspect … OOMKilledが取れるときは確認する。 - uid 1000 の契約:公式の Node 系イメージは uid 1000 で書き込み可能なマウントを前提にする。不一致は製品欠陥ではない。
- RAM の下限の経験則:コミュニティや文書ではイメージ作業に約2GB は危うい最小値とされ、ビルドはそれの数倍の余裕を要することが多い。
- ポート18789:多くのサンプルでデフォルトのゲートウェイ/UI マッピング。トークン強化なしで公開するのは VPSMAC のハードニング記事が推奨する本番運用に反する。
- 環境変数の可視性:Compose の変数は魔法ではない。doctor に効くのはコンテナ PID が継承したものだけ。
- 重複スタック:同じホストポートを束ねる二つの compose プロジェクトや、一つの設定ディレクトリを共有すると、「一度だけ動く」挙動が出る。
docker psとマウントの inspect で監査する。 - ベースライン成果物:アップグレード前に、最後に安定していた
docker inspectの JSON 断片と緑の doctor 出力を残し、回帰とドリフトを diff する。
6. まとめ:Docker の便利さと VPSMAC 上のネイティブ macOS
Docker は再現可能なデモとマルチテナント分離には優れますが、名前空間と cgroup はすべて真夜中のページに届くまでのホップを増やします。DNS 設定の二重化、ボリュームの uid 体操、ホストのスワップ逼迫とコンテナの死亡スパイラルの相関の難しさという代償を払います。マウントを直さずイメージを回し続けるチームは、誰も触りたがらない「スノーフレーク」な compose ファイルを積み上げます。7×24 のエージェントゲートウェイに望ましい帰結ではありません。
ベアメタルの Mac クラウドノードへのネイティブ導入(SSH で入り、公式の非コンテナ手順を走らせ、launchd で監視)は、失敗の領域をいくつか折りたたみます。ssh で見える uid が設定を書く uid と一致し、リゾルバはシェルと揃い、openclaw doctor はすでに信頼しているファイルシステムを読みます。使い捨てラボではなく本番サービスに近い OpenClaw 負荷では、動く部品の削減が、カスタムイメージをねじ伏せるより勝ることが多いです。Docker 専用スタックは継続的な切り分けコストと、持続負荷下の性能ばらつきも足します。専用物理 Mac ホストはその両方を和らげます。
したがって、レディネスの三要素がどうしても安定しないときの現実的な次の一手は、VPSMAC の Mac ノードを借りることです。Apple シリコン互換と 24 時間電源を保ちつつ、クラウドのクォータの上にコンテナの人間工学とも戦わなくて済みます。5分デプロイの記事でブートストラップし、公開面は本番ハードニングのチェックリストで揃える。ツールチェーンは同じで、抽象化税だけが減ります。本稿が勧めるのはスローガンではなく、上のマトリクスを正直に尽くしたあとで、繰り返す137と権限ループの証拠がレイヤー数を指しており、モデル品質ではないからです。