Claude Media
Claude CodeをFreeBSDで動かす方法 — Linuxulatorの手順と制約

Claude CodeをFreeBSDで動かす方法 — Linuxulatorの手順と制約

FreeBSDはClaude Codeの公式対応外で、インストーラーもnpmも使えません。LinuxulatorでLinux版バイナリを動かす手順と、自動更新・jailまわりの制約をまとめます。

FreeBSDで最新リリースに追従できる経路は、Linux互換レイヤー(Linuxulator)の上でLinux版のバイナリを動かす方法だけです。標準のインストーラーもnpm経由の導入も、FreeBSDでは成立しません。コミュニティ製のportはバージョンが固定されがちな代替で、リモート環境を使う手もあります。

この記事では、ドキュメントが何を対応外としているかを確認したうえで、GitHubのissueで共有されているLinuxulator運用の手順と、自動更新やjailで踏みやすい制約を説明します。issueの手順は公式の保証ではなく、利用者の報告に基づく運用例です。

FreeBSDは対応環境に入っていない

システム要件に載っているOSは、macOS 13.0以上、Windows 10 1809以上またはWindows Server 2019以上、Ubuntu 20.04以上、Debian 10以上、Alpine Linux 3.19以上です。FreeBSDはありません。

導入経路ごとの状況は次のとおりです。

導入経路FreeBSDでの状況根拠
ネイティブインストーラー(install.sh)FreeBSDでの状況プラットフォーム非対応と報告される根拠トラブルシューティング
npm install -gFreeBSDでの状況対応するプラットフォームパッケージが無く、動かない根拠セットアップ / トラブルシューティング
Linux版バイナリをLinuxulatorで実行FreeBSDでの状況利用者の報告では動作根拠GitHub issue
FreeBSD ports(misc/claude-code)FreeBSDでの状況コミュニティ製。更新との競合報告あり根拠GitHub issue

なぜnpmでも入らないのか

以前はnpmパッケージにNode.jsのフォールバックがあり、FreeBSDでも動きました。issueの記述では、v2.1.113でそのフォールバックが外れたとされています。

現在のnpmパッケージは、プラットフォームごとのオプション依存としてネイティブバイナリを取得し、postinstallでclaudeコマンドの位置に置く作りです。対応プラットフォームは次の8つです。

  • darwin-arm64 / darwin-x64
  • linux-x64 / linux-arm64
  • linux-x64-musl / linux-arm64-musl
  • win32-x64 / win32-arm64

FreeBSD向けのパッケージは含まれません。トラブルシューティングには、FreeBSDではインストーラーがプラットフォーム非対応と報告し、v2.1.205より前はFreeBSDをLinuxと見なして動かないバイナリを取得していた、という記載があります。

issueのコメントによれば、npmのラッパー側にはfreebsd向けのエントリが以前から入っています。ただしその先の@anthropic-ai/claude-code-freebsd-x64が未公開のため、npm i -gは「native binary not installed」で止まる、ようです。

Linuxulatorで動かす手順

issue #81704のコメントには、FreeBSD 15.0-RELEASEでLinuxulatorを使い、最新リリースに追従している利用者の手順が載っています。TUIの対話、-pによるヘッドレス実行、多段のサブエージェントまで動いたという報告です。以下はその手順の要約です。

Linux互換レイヤーを有効にする

最初に一度だけ実行します。

sysrc linux_enable=YES
service linux start
pkg install linux_base-rl9

service linux startでlinux64.koなどのカーネルモジュールが読み込まれ、linux_base-rl9がglibcと/lib64/ld-linux-x86-64.so.2を提供します。

linux-x64のバイナリを取得して検証する

npmのラッパーを経由せず、linux-x64のプラットフォームパッケージだけを直接取り出します。取り出したバイナリは、置き場所へ入れる前にその場で動作確認します。

VER=$(npm view @anthropic-ai/claude-code version)
npm pack @anthropic-ai/claude-code-linux-x64@$VER
tar xf anthropic-ai-claude-code-linux-x64-$VER.tgz
./package/claude --version

--versionがバージョン番号を返せば、Linuxulator上での起動は成立しています。ここで失敗するなら、linux_baseの導入かカーネルモジュールの読み込みを疑います。

バージョン付きパスに置いてシムで呼ぶ

バイナリはlibexec配下にバージョン名付きで置き、/usr/local/bin/claudeには自分で管理する1行のシェルスクリプトを置きます。

sudo install -m 755 package/claude \
  /usr/local/libexec/claude-code/claude-$VER
#!/bin/sh
exec /usr/local/libexec/claude-code/claude-2.1.219 "$@"

シェルスクリプトの2.1.219は、置いたバージョンに合わせて書き換えます。この構成なら、古いバージョンのバイナリがディスクに残ります。戻したいときはシムの向き先を古いパスに書き換えるだけです。

更新用の手順をスクリプトにまとめる

リリースごとに繰り返す部分は、次のようなシェルスクリプトにまとめられます。上の手順を並べただけの例で、issueに載っているものではありません。

#!/bin/sh
set -e
VER=$(npm view @anthropic-ai/claude-code version)
npm pack @anthropic-ai/claude-code-linux-x64@$VER
tar xf anthropic-ai-claude-code-linux-x64-$VER.tgz
./package/claude --version
sudo install -m 755 package/claude \
  /usr/local/libexec/claude-code/claude-$VER

set -eを付けておくと、--versionの確認で失敗した時点で止まり、動かないバイナリを置き場所へ入れずに済みます。シムの書き換えは最後に手で行う形にすると、確認前に向き先が変わることもありません。

ここで躓く原因は、linux_base-rl9が未導入でld-linux-x86-64.so.2が見つからない場合と、service linux startでlinux64.koが読み込まれていない場合が中心です。どちらも--versionの段階で表に出るので、置き場所へ入れる前に切り分けられます。

古いバージョンに固定される代償と、JITフラグの扱い

npm経由でFreeBSDに入れた環境は、v2.1.112付近のバージョンで止まります。issueのコメントには、Linuxulatorを使わない場合は新しいモデルや自動モードの機能を使えず、旧世代のモデルに留まるという報告があります。バージョン固定の代償は、新機能に届かないことです。

もう1つ、以前の手順に出てくる環境変数BUN_JSC_useBBQJIT=0は、いまは不要という報告があります。Bunの実行環境でJITを切る設定で、Linuxulatorの初期の運用では必須でした。コメントの利用者は、2.1.154付近から外しても、2.1.204、2.1.219と3回の更新で問題が出なかったと書いています。古いブログやissueの手順をそのまま写す前に、この設定を入れているかを確認する価値があります。

更新はすべて手作業になる

claude updateとインストーラーにFreeBSDの経路が無いため、新しいリリースへの追従は上の取得手順の繰り返しです。バージョン番号を変えてnpm packからinstallまで実行し、シムの向き先を差し替えます。

自動更新との衝突は、次のとおり構成で避けます。

  • ドキュメントによると、ネイティブインストーラーの管理下にあるランチャーは~/.local/bin/claudeです。シムを/usr/local/binに置けば、更新機構と同じファイル名を共有しません
  • 独自のランチャーを~/.local/bin/claudeに置く場合、v2.1.207からは自動更新やclaude updateが上書きしなくなりました。それ以前は毎回シンボリックリンクに置き換えられていました
  • 更新を止めたいときは、settings.jsonのenvにDISABLE_AUTOUPDATERを"1"で設定します。手動のclaude updateは動きます。手動更新も含めて止めるならDISABLE_UPDATESです
claude doctor

claude doctorのAuto-updatesの行にdisabled (set by env: DISABLE_AUTOUPDATER)と出れば、設定は効いています。

FreeBSD portsを使う場合の落とし穴

コミュニティ製のport(misc/claude-code)は、cli.jsとベンダー済みバイナリをまとめて配る形です。issue #81704の記述では、実行中に自動更新がnpmのラッパーでport版を上書きし、そのラッパーがFreeBSDに対応しないため壊れる報告があります。

回避策として挙がっているのはDISABLE_AUTOUPDATER=1です。ただしissue本文はこの回避策を「undocumented」と書いています。現在のドキュメントには設定方法が載っているため、この記述は古い可能性があります。別の回避策として、Node.jsフォールバックが残る最後のバージョン(v2.1.112)に固定する案もありますが、新機能や新モデルは使えません。

jailの中では動かなくなる場合がある

issue #90984では、jailの内側でLinuxulator版を動かしていた利用者が、バージョン2.1.251で動かなくなった様子が報告されています。最後に動いたバージョンは2.1.212です。

報告された原因は、/dev/fdではなく/proc/self/fdを使う処理への切り替えです。jailのlinprocfsではfdのシンボリックリンクが空に解決され、/proc/self/fd/N/childの作成がENOTDIRで失敗します。その結果、BashツールもWriteツールも、スクラッチパッドの作成の段階で失敗する、という説明です。ホスト側では/proc/self/fdが正常に働くため、症状が出ません。

このissueは書かれた時点でopenで、修正版は確認できていません。jailで運用するなら、次の点が実務上の手がかりになります。

  1. Bashツールが急に失敗し始めたら、まずjail内のclaude --versionと、マウントしているホスト側のバージョンを見比べる
  2. 動作が確認できているバージョンのバイナリをバージョン付きパスに残し、シムで固定する
  3. jail内でもDISABLE_AUTOUPDATER=1を設定し、内蔵の更新機構がマウント済みのバイナリを覆い隠さないようにする

選び方の早見表

状況向く経路注意点
ホストのFreeBSDで最新に追従したい向く経路Linuxulator + 自前シム注意点更新は手動。linux_baseが必要
手間を減らしたい・新機能に急ぎではない向く経路FreeBSD ports注意点更新との競合に注意
jailで隔離して使いたい向く経路Linuxulator + バージョン固定注意点/proc/self/fdの問題で新しいバージョンが動かない場合あり
管理の手間を避けたい向く経路Linux・macOSの環境をリモートで使う注意点FreeBSD側はSSHクライアントとして使う

ネイティブ対応の見通し

issue #81704は、FreeBSD向けネイティブバイナリの追加を求める要望です。Bunの側でFreeBSDビルドが提供されたことを根拠に、bun build --compileでFreeBSD向けの単一実行ファイルを作れるはずだ、と主張しています。

要望は書かれた時点でopenで、コメントには追従の声が続いています。システム要件にFreeBSDが入るまでは、ホスト上で最新に追従できる現実的な経路はLinuxulatorだけです。ネイティブ対応が入れば、インストーラーとnpmの両方が使えるようになり、シムや手動更新は不要になります。

隣接する環境との違い

同じLinux系でも、対応OSに入っているAlpineでは事情が違います。musl系ディストリビューションでは、インストール用にbashとcurl、実行時にlibgcc・libstdc++・ripgrepを入れ、USE_BUILTIN_RIPGREP=0を設定すれば、標準のインストーラーが使えます。詳しくはClaude Code Alpine Linuxセットアップにまとめています。

Linux全般のインストール手段はClaude Code install完全ガイド、apt・dnf・apkによる導入はClaude Code apt installでのLinuxパッケージ導入と更新が扱っています。glibcとmuslのバイナリ選択に絡む不具合はClaude Agent SDKのmusl版バイナリ優先バグの記事で確認できます。

この記事を共有:XはてブLinkedIn