Keyboard shortcuts

Press or to navigate between chapters

Press ? to show this help

Press Esc to hide this help

FreeBSD

ZeroClaw は FreeBSD 上でネイティブに動作します(FreeBSD 15.0-RELEASE、amd64 でテスト済み)。Linux/macOS/Windows のパスと異なる点が 2 つあります。

  1. ビルド済みバイナリと install.sh のサポートはありません。 FreeBSD はブートストラップインストーラーの対象外であるため、システムの Rust ツールチェーンを使ってソースからビルドします。
  2. zeroclaw service バックエンドはありません。 zeroclaw service install コマンドは systemd、OpenRC、launchd、Windows タスクスケジューラには対応していますが、FreeBSD の rc.d には対応していません。小さな rc.d スクリプトはご自身でインストールします。このページでは、完全でテスト済みのスクリプトを提供します。

設定、プロバイダー、チャネル、デーモン、ゲートウェイなど、それ以外はすべて他のプラットフォームと同じです。

FreeBSD を使用する場合。 FreeBSD のデプロイは、ネットワークアプライアンス、組み込み、jail ベースのホスティングで一般的であり、運用者がベースシステムの安定性、ZFS + jail プリミティブを求める場合や、ポリシー/ライセンス上の理由で FreeBSD が必要な場合に利用されます。ビルド済みバイナリが存在せず、rc.d のセットアップが手動であるため、このパスは FreeBSD の慣習に慣れた運用者に適しています。特定の FreeBSD 要件がなく、単にプラットフォームを評価しているだけであれば、Linux (systemd) や macOS (launchd) のほうが install.shzeroclaw service install を通じてより迅速に導入できます。

コピー&ペーストする代わりにファイルを取得してください。 以下に示すシェルスクリプトとサンプル設定はすべて dist/freebsd/ に同梱されています。それらをホストに直接コピーしてください。このチュートリアルでは、各部分が何をするのか、そしてなぜそうするのかを説明します。

システム依存関係

pkg からツールチェインとランタイムをインストールします:

sh

doas pkg install -y rust git
パッケージなぜ
rustバイナリをビルドするための cargorustc を提供します。ZeroClaw のワークスペースの MSRV は Rust 1.96.0 です。FreeBSD の rust ポートはより新しい安定版を追跡しているため、pkg install rust で要件を満たせます。
gitリポジトリのクローン作成時、およびgitベースのツールを使用する場合に実行時に必要です。

sudo ではなく doas FreeBSD は基本の権限昇格ツールとして doas を同梱しています。sudo はオプションの port です。ここでの例では doas を使用します。wheel グループにパスワードなしの昇格を許可する最小限の /usr/local/etc/doas.conf は次のとおりです:

permit nopass keepenv :wheel

ソースからビルドする

sh

git clone https://github.com/zeroclaw-labs/zeroclaw.git
cd zeroclaw
cargo build --release

リリースバイナリは target/release/zeroclaw に生成されます。デフォルトの機能セットをクリーンビルドする場合、ハードウェアの性能が控えめだと時間がかかりますが、これは想定どおりです。ZeroClaw は大規模な Rust ワークスペースです。

ビルドを削減するには、不要な機能を無効化してください(Linux マシンで ./install.sh --list-features を実行するか、Cargo.toml を参照):

sh

cargo build --release --no-default-features --features agent-runtime

バイナリをインストールする

PATH の通った場所に配置してください。FreeBSD では /usr/local/bin が ports でインストールされたバイナリの慣例的な配置場所です:

sh

doas install -m 755 target/release/zeroclaw /usr/local/bin/zeroclaw
zeroclaw --version

ユーザーごとに管理したい場合は、~/.cargo/bin/zeroclaw でも同様に動作します。

初回起動時の設定

sh

zeroclaw quickstart

これにより ~/.zeroclaw/ がスターター設定とともに作成され、プロバイダーのセットアップが順を追って案内されます。設定のレイアウトと優先順位は他のすべてのプラットフォームと同一です。詳しくは Reference → Config を参照してください。

プロバイダー認証

プロバイダー認証はFreeBSD固有のものではありません。APIキーを使用するプロバイダーでは、ゲートウェイ、zerocode、zeroclaw config set、または環境変数を通じてキーを設定するだけで済みます。OAuthおよびサブスクリプション型のプロバイダー(例: OpenAI/Codex ChatGPTサブスクリプション、Anthropic Claude Pro/Team)は、ベンダー独自のダッシュボードまたはログインフローからトークンを取得し、APIキーと同じ方法で設定します。

認証情報モデルの全体像(API キー、OAuth/サブスクリプショントークン、環境変数によるオーバーライド、シークレットストア)については、Provider Configuration → Credentials および OAuth and subscription auth を参照してください。このページがすべてのプラットフォームにおける信頼できる情報源です。

サービスとして実行する (rc.d)

zeroclaw service install には FreeBSD バックエンドがないため、FreeBSD ネイティブの daemon(8) を使い、rc.d スクリプトでデーモンを監視します。これにより、service zeroclaw start|stop|restart|status、クラッシュ時の再起動、pidfile、ブート時の起動が利用できます。

以下のすべてのスクリプトについて、インストール可能な状態のコピーが dist/freebsd/ にありますzeroclaw-run.sh、基本的な zeroclaw.rc、強化版の zeroclaw-hardened.rc)。2つの rc.d スクリプトには @@ZEROCLAW_USER@@ プレースホルダーが含まれており、インストール時に sed で置き換えるため、コピー&ペーストする代わりにファイルを取得できます。dist/freebsd/README.md を参照してください。以下の解説では、各部分が何を行うかを説明します。

1. ランチャースクリプト

daemon(8) は最小限の環境で子プロセスを起動するため、完全な PATH をエクスポートしてください(FreeBSD は gitpython3 などを /usr/local/bin 配下に配置しますが、これはデフォルトのサービス PATH には 含まれていません)。rc.d スクリプトはこれを daemon -u <user> 経由で実行し、daemon(8) によれば exec の前にそのアカウントの passwd エントリから HOMEUSERSHELL を設定するため、${HOME} はすでにサービスアカウントのホームになっています(ホームが別の場所にあるアカウントや、rc.conf の実行ユーザーのオーバーライドも問題なく機能します)。/usr/local/libexec/zeroclaw-run.sh として保存してください:

sh

#!/bin/sh
# daemon -u <user> has already set HOME from the accountユーザーの passwd エントリ。
export PATH="/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:${HOME}/bin"
exec /usr/local/bin/zeroclaw daemon --config-dir "${HOME}/.zeroclaw"

sh

doas install -m 755 zeroclaw-run.sh /usr/local/libexec/zeroclaw-run.sh

2. rc.d スクリプト

/usr/local/etc/rc.d/zeroclaw として保存します:

sh

#!/bin/sh
#
# PROVIDE: zeroclaw
# REQUIRE: NETWORKING DAEMON
# キーワード: shutdown

. /etc/rc.subr

name=zeroclaw
rcvar=zeroclaw_enable

load_rc_config $name

: ${zeroclaw_enable:=NO}
# これに ${name}_user という名前を付けないでください — そうすると rc.subr が独自の su によるユーザー切り替えを実行してしまいます
# and collide with daemon -u (ユーザー環境の設定に失敗しました).
: ${zeroclaw_runas:="youruser"}

rundir=/var/run/zeroclaw
pidfile="${rundir}/zeroclaw.pid"
logfile=/var/log/${name}.log
launcher=/usr/local/libexec/zeroclaw-run.sh

command=/usr/sbin/daemon
command_args=-r -P ${pidfile} -o ${logfile} -u ${zeroclaw_runas} ${launcher}

start_precmd=zeroclaw_precmd

zeroclaw_precmd()
{
    # rundir + logfile はroot所有のまま維持: rc.d(root)がここにデーモンの-P pidfileを
    # 書き込み、後でそれを信頼するため、非特権サービスユーザーがそれを
    # 偽装できないようにする必要があります。daemon -oは${zeroclaw_runas}に降格する前にlogfileを開きます。
    install -d -o root -g wheel -m 755 ${rundir}
    install -o root -g wheel -m 640 /dev/null ${logfile}
}

run_rc_command $1

sh

doas install -m 755 zeroclaw /usr/local/etc/rc.d/zeroclaw

フラグの機能:

  • -r: 子プロセスを監視し、終了した場合は再起動します(クラッシュリカバリ)。
  • -P ${pidfile}: service zeroclaw stop がシグナルを送れるように、スーパーバイザーの pid を書き込みます。
  • -o ${logfile}: 子プロセスの stdout/stderr をログファイルにリダイレクトします。
  • -u ${zeroclaw_runas}: zeroclawをrootではなく非特権ユーザーとして実行します。

su -m ではなく daemon -u を使う理由。 よくあるパターンとして daemon ... su -m user -c launcher があります。これは避けてください。su(1)SIGTERM を子プロセスに転送しないため、service zeroclaw stopdaemon スーパーバイザーを終了させますが、孤立した zeroclaw プロセスが残り、次の start で2つ目のコピーが積み重なってしまいます。daemon -u user を使うと daemon(8)zeroclaw の直接の親プロセスになるため、停止シグナルを転送してクリーンにシャットダウンします。(他の理由で su ベースのスクリプトを使わざるを得ない場合は、その停止パスに pkill -f "zeroclaw daemon" によるスイープを追加してください。)

3. 有効化して起動

sh

doas sysrc zeroclaw_enable=YES
doas sysrc zeroclaw_runas=youruser     # ~/.zeroclaw を所有するアカウント

doas service zeroclaw start
doas service zeroclaw status

service zeroclaw stop / restart は期待どおりに動作します。/etc/rc.conf に(sysrc によって書き込まれた)zeroclaw_enable=YES があるため、デーモンは起動時にも開始されます。

4. 無人およびリモート運用のための堅牢化

上記のスクリプトは、対話的な単一インスタンスのインストールには正しく動作します。しかし、サービスをリモート(ssh 経由)で操作したり、複数のコピーを実行したりした瞬間に、3 つの daemon(8) の挙動に驚かされることになります。これら 3 つはすべて本番環境のデプロイで問題を引き起こしましたが、その修正はわずかなものです。以下のすべての修正を取り込んだ完全なスクリプトは dist/freebsd/zeroclaw-hardened.rc として提供されています。基本の zeroclaw スクリプトの代わりにこちらをインストールしてください。

リモートでの service ... start がハングする。 daemon -r は起動時に渡された stdin/stdout/stderr をそのまま継承し、開いたまま保持します。ssh host 'service zeroclaw start' を実行すると、スーパーバイザがあなたの ssh セッションの stdout fd を永久に開いたままにするため、ssh は EOF を検出できず、デーモンは正常に起動しているのにコマンドがハングします。スーパーバイザ自身のディスクリプタをデタッチしましょう。-o ${logfile} はすでに_子プロセスの_出力をルーティングしているため、何も失われません。

sh

command_args=-r -P ${pidfile} -o ${logfile} -u ${zeroclaw_runas} ${launcher}
# ...独自の std{in,out,err} を /dev/null に送信してデーモンを呼び出す:
/usr/sbin/daemon ${command_args} </dev/null >/dev/null 2>&1

定番の command/command_args 形式を使う場合は、リダイレクトを制御できるように、起動処理をカスタムの start_cmd でラップしてください。この変更ひとつで、service zeroclaw startssh、CI、または構成管理のプッシュから安全に呼び出せるようになります。

start の繰り返しでオーファンとなったスーパーバイザーが積み重なる。 単純な start はスーパーバイザーがすでに実行中かどうかを確認しないため、2回目の start(またはクラッシュ後に古い pidfile が残った状態での start)は別の daemon を起動し、ゲートウェイポートをめぐって最初のものと競合します。すでに稼働中のスーパーバイザーが存在する場合は拒否するようにして、start を冪等にしましょう。スーパーバイザーは pidfile だけではなく、ランチャーのパスで照合してください(pidfile は古くなっている可能性があります)。これを行う際の FreeBSD 特有の落とし穴が2つあります。

  • daemon(8) は_スーパーバイザのタイトルを_ daemon: /usr/local/libexec/zeroclaw-run.sh[<childpid>] (daemon) に_変更します_。そのため pgrep -f zeroclaw-run.sh はスーパーバイザにマッチしますが、バイナリ名に対する pgrep -f はマッチしません。リテラルの daemon: プレフィックスにバインドしてください。これはスーパーバイザにマッチし、子プロセスやランチャーの手動実行、rc シェル自体には決してマッチしません。daemon の [<childpid>] を開く末尾の [ にもバインドしてください。そうすれば、名前が単に zeroclaw-run.sh で_始まる_だけの兄弟ランチャーがマッチすることを防げます(これはプールを実行するようになると重要になります。下記の インスタンスのプールを実行する を参照してください)。
  • FreeBSD の pgrep -f は、そのリタイトル文字列に対して先頭の ^ アンカーを尊重しませんpgrep -f '^daemon: ...' は何もマッチしません。^ を削除し、特定性については daemon: プレフィックスに頼り、.sh のドットを [.] として(角括弧を [[] として)エスケープすることで、それらをリテラルにします。

sh

launcher_pat=daemon: /usr/local/libexec/zeroclaw-run[.]sh[[]

zeroclaw_running()
{
    pgrep -f ${launcher_pat} >/dev/null 2>&1
}

daemon -P の pidfile からの read が誤検知を報告する。 daemon -P は pid を 末尾の改行なし で書き込むため、pid を正しく設定していても IFS= read -r pid < "${pidfile}"非ゼロ ステータス(改行前のEOF)を返す。これを read -r pid < "$pf" || return 1 のようにガードすると、実行中のすべてのインスタンスが停止しているように見え、冪等であるはずの start が嬉々として重複起動してしまう。成功パスを read の終了ステータスに結びつけてはいけない。代わりに値を検証すること:

sh

pid=""
IFS= read -r pid < "${pidfile}"     # ここで `|| return 1` を実行しないこと
case "${pid}" in
    ''|*[!0-9]*) return 1 ;;        # 空または非数値 → 実行中でないものとして扱う
esac

インスタンスのプールを実行する。 N 個のデーモン(例: ワーカープール)を実行するには、それぞれに独自の pidfile と logfile(worker.$i.pidworker.$i.log)を与え、$i にわたって start/stop をループします。スーパーバイザーのリタイトルはすべてのインスタンスで同一であり、インスタンスごとの引数を含まないため、pidfile が唯一のインスタンスごとのハンドルとなります。stop/status は pidfile から駆動し、完全な停止スイープでは、生きている pidfile が指していない残存スーパーバイザー(手動で起動されたもの、または pidfile が古くなったもの)をすべて停止します。

jail内での実行

Jailは、ZeroClawに独自のパッケージ、サービスユーザー、オプションで独自のIPを備えた隔離されたrootを提供します。ホストが他のサービスを実行している場合や、エージェントを制約したい場合に便利です。サービスのセットアップはホストの場合と同一です。jailの_内部_で実行するだけです。 ここでは、ベースシステムのツールを使った従来型のthick jail(jailマネージャー不要)を順を追って説明します。

ワンステップオプション。 dist/freebsd/zeroclaw-jail-setup.sh は以下のステップ1〜3を自動化します。jailを作成し、一致するベースを展開し、/etc/jail.conf エントリを追加し、jailを起動し、その中にランチャーと堅牢化された rc.d スクリプトをインストールします(doas sh zeroclaw-jail-setup.shJAIL_NAME / JAIL_PATH / ZPOOL / ZEROCLAW_USER は環境変数で上書き可能)。以下の手動による手順説明では、その動作を解説します。

1. jailを作成する

sh

# jail用のZFSデータセット(UFSを使用している場合は通常のディレクトリを使用してください)。
doas zfs create -o mountpoint=/jails/zeroclaw zroot/jails/zeroclaw   # プールの調整

# ホストのリリースに一致するベースを抽出します。
doas fetch -o /tmp/base.txz \
    "https://download.freebsd.org/releases/$(uname -m)/$(freebsd-version -u)/base.txz"
doas tar -xpf /tmp/base.txz -C /jails/zeroclaw
doas cp /etc/resolv.conf /jails/zeroclaw/etc/

2. 設定と起動

/etc/jail.conf(ホスト側)に jail エントリを追加します。この例ではホストのネットワークを共有しています。jail に専用のアドレスを割り当てる場合は、代わりに ip4.addr を設定してください。

zeroclaw {
    host.hostname = "zeroclaw";
    path = "/jails/zeroclaw";
    exec.start = "/bin/sh /etc/rc";
    exec.stop  = "/bin/sh /etc/rc.shutdown";
    exec.clean;
    mount.devfs;
    persist;
}

sh

doas sysrc jail_enable=YES
doas sysrc jail_list+=ゼロクロウ
doas service jail start zeroclaw

3. jail内にZeroClawをインストールする

上記セクションのすべては、jail の 内部 で実行されます。コマンドの前に doas jexec zeroclaw … を付けるか、doas jexec zeroclaw /bin/sh でシェルを開いてください:

sh

doas jexec zeroclaw pkg install -y rust git     # または、ホストでビルドされたバイナリをコピーします
# build + install zeroclaw to /usr/local/bin/zeroclaw exactly as above, then:
doas jexec zeroclaw pw useradd zeroclaw -m -s /usr/sbin/nologin

ランチャーと rc.d スクリプトを jail のファイルシステムにインストールします(ホストから見ると、jail のルートには接頭辞が付きます: /jails/zeroclaw/usr/local/libexec/… および /jails/zeroclaw/usr/local/etc/rc.d/…)。その後、jail の_内部で_サービスを有効化して起動します:

sh

doas jexec zeroclaw sysrc zeroclaw_enable=YES
doas jexec zeroclaw service zeroclaw start
doas jexec zeroclaw service zeroclaw status

Jail固有の注意事項

  • ホストからjailのファイルを編集する際は cp /dev/stdin ではなく tee を使用してください。 … | doas tee /jails/zeroclaw/usr/local/etc/rc.d/zeroclaw >/dev/null のようにパイプで渡します。doas cp /dev/stdin … はコピーの途中で cp: /dev/stdin: File changed というエラーで失敗することがあります。
  • ゲートウェイは jail 内部でバインドします。 デーモンはデフォルトでループバックをリッスンします。ホストや LAN から接続するには、--host 0.0.0.0 を指定して zeroclaw を起動し(zeroclaw-run.sh を編集)、jail に到達可能なアドレスを割り当てるか、ホストからプロキシしてください。
  • jail 環境では堅牢化された rc.d スクリプトを推奨します。 通常、servicejexec/ssh を介して非対話的に実行しますが、まさにこの状況で基本スクリプトの start ハングや孤立プロセスの積み重ねが問題になります。堅牢化を参照してください。また、jail 内で /var/run/zeroclaw を root 所有に保つことで、非特権のサービスユーザーがスーパーバイザーの pidfile を偽造できないようにします。
  • 1 つの jail で複数のデーモンを実行する場合(例: ワーカープール)は、ハードニングセクションのプールに関する注記に従ってください。jail は 1 つのプロセステーブルを共有するため、インスタンスごとに 1 つの pidfile/logfile を用意し、pgrep をランチャーの retitle にバインドします。

Podman + Linuxulator での Linux イメージの実行

上記のネイティブビルドは、ZeroClaw 自体にとっては正しい方法です。しかし、一部の Python ベースのツールやスキルは manylinux 専用のホイール に依存しています。たとえば、polarspyarroworacledb は FreeBSD 向けのホイールを公開していないため、それらをインポートするツールはネイティブな FreeBSD の python3 では動作しません。FreeBSD の Linuxulator(Linux バイナリ互換レイヤー)と Podman を組み合わせれば、FreeBSD ホスト上で 公式の Linux コンテナイメージ を実行でき、それらのツールが必要とする Linux ABI を提供できます。これはネイティブな rc.d デーモンを補完するものです。どちらか一方、または両方を並行して実行できます。

1. 前提条件

Linux ABIを有効にして、Linuxリリースが報告されることを確認します:

sh

doas sysrc linux_enable=YES
doas service linux start              # モジュールを読み込み、/compat/linux をマウントします
sysctl compat.linux.osrelease         # 例: compat.linux.osrelease: 5.15.0

/etc/rc.conflinux_enable="YES" を設定すると、起動時に ABI も読み込まれます。次に Podman をインストールします。

sh

doas pkg install -y podman

2. イメージを取得: Linux プラットフォームを強制する

FreeBSD の Podman は、マニフェストリストを解決する際にデフォルトで os=freebsd を使用します。ZeroClaw のイメージは linux/amd64linux/arm64 用にのみ公開されているため、単純な podman pullno image found in manifest list for architecture ..., OS freebsd で失敗します。Linux プラットフォームを明示的に指定してください:

sh

doas podman pull --os linux --arch amd64 ghcr.io/zeroclaw-labs/zeroclaw:debian

latest ではなく debian タグを使用してください。distroless の latest イメージにはシェルが含まれていないため、エミュレーション下でのデバッグが困難になります。イメージの完全な一覧については Docker & Containers を参照してください。

3. コンテナーを実行する

Linux イメージは Docker & Containers に記載されているとおりに動作し、永続状態を /zeroclaw-data に想定しており、初回実行時に設定をブートストラップします:

sh

doas podman run -d --name zeroclaw --restart=always \
    --os linux --arch amd64 \
    -p 42617:42617 \
    -v /var/db/zeroclaw:/zeroclaw-data \
    ghcr.io/zeroclaw-labs/zeroclaw:debian

doas podman exec -it zeroclaw zeroclaw quickstart

Podman が FreeBSD のデフォルトに再解決しないように、(pull だけでなく)すべての run--os linux --arch amd64 フラグを維持してください。

Linuxulatorに関する注記

  • 起動時の永続性。 Podman 自身の --restart=always は、稼働中の Podman 内でコンテナを再起動するだけで、ホストの再起動を単独で乗り越えることはできません。ホスト再起動後にコンテナを復帰させるには、rc.d スクリプト(ネイティブサービスと同じパターン)または @reboot の cron エントリから podman start を管理してください。
  • ネットワーク. -p 42617:42617 は Podman のブリッジを通じてゲートウェイを公開します。ホスト上でブリッジ/CNI のセットアップが構成されていない場合、--network host が最もシンプルな代替手段です。その場合、コンテナはホストのネットワークスタックを直接共有します。
  • すべてがクリーンにエミュレートされるわけではありません。 Linuxulator は一般的なシステムコール領域をカバーしていますが、特殊なバイナリは未実装の呼び出しに遭遇する場合があります。ツールが正しく動作しない場合は、ZeroClaw のバグだと判断する前に dmesglinux: の警告を確認してください。

ログ

sh

tail -f /var/log/zeroclaw.log

ログレベルは標準の設定 / 環境変数で指定できます。詳細は 運用 → ログと可観測性 を参照してください。

確認

sh

zeroclaw --version
service zeroclaw status
# デーモンがローカルゲートウェイを公開している場合(デフォルト 127.0.0.1:42617):
fetch -qo - http://127.0.0.1:42617/health

"status":"ok" のヘルスペイロードはゲートウェイが稼働中であることを示します。レスポンスの runtime フィールドには、コンポーネントごとのヘルス情報(チャネルやプロバイダーなど)が含まれます。

アンインストール

sh

doas service zeroclaw stop
doas sysrc -x zeroclaw_enable
doas rm /usr/local/etc/rc.d/zeroclaw /usr/local/libexec/zeroclaw-run.sh
doas rm /usr/local/bin/zeroclaw
rm -rf ~/.zeroclaw        # オプション — 設定と履歴を削除します

次へ