FreeBSD
ZeroClaw se ejecuta de forma nativa en FreeBSD (probado en FreeBSD 15.0-RELEASE, amd64). Hay dos diferencias con respecto a las rutas de Linux/macOS/Windows:
- Sin binario precompilado y sin compatibilidad con
install.sh. FreeBSD no es un objetivo del instalador de arranque, por lo que debes compilar desde el código fuente con la cadena de herramientas Rust del sistema. - Sin backend
zeroclaw service. El comandozeroclaw service installreconoce systemd, OpenRC, launchd y el Programador de tareas de Windows, pero norc.dde FreeBSD. Debe instalar usted mismo un pequeño script derc.d. Esta página le proporciona uno completo y probado.
Todo lo demás, la configuración, los proveedores, los canales, el daemon, el gateway, es idéntico a cualquier otra plataforma.
Cuándo usar FreeBSD. Las implementaciones de FreeBSD son comunes en alojamiento de dispositivos de red, sistemas embebidos y basado en jails, donde los operadores buscan la estabilidad del sistema base, las primitivas de ZFS + jails, o necesitan FreeBSD por razones de políticas o licencias. Dado que no existe un binario precompilado y la configuración de
rc.des manual, esta vía es adecuada para operadores familiarizados con las convenciones de FreeBSD. Si solo está evaluando plataformas sin un requisito específico de FreeBSD, Linux (systemd) o macOS (launchd) ofrecen una incorporación más rápida medianteinstall.shyzeroclaw service install.Obtén los archivos en lugar de copiar y pegar. Cada script de shell y configuración de ejemplo que se muestra a continuación se incluye en
dist/freebsd/: cópialos directamente a tu host. El tutorial explica qué hace cada pieza y por qué.
Dependencias del sistema
Instala la cadena de herramientas y el runtime desde pkg:
sh
doas pkg install -y rust git
| Paquete | Por qué |
|---|---|
rust | Proporciona cargo y rustc para compilar el binario. El MSRV del espacio de trabajo de ZeroClaw es Rust 1.96.0; el port rust de FreeBSD sigue una versión estable más reciente, por lo que pkg install rust cumple ese requisito. |
git | Clonar el repositorio, y requerido en tiempo de ejecución si usas herramientas basadas en git. |
doas, nosudo. FreeBSD incluyedoascomo herramienta base de escalada de privilegios;sudoes un port opcional. Los ejemplos aquí usandoas. Un/usr/local/etc/doas.confmínimo que otorga al grupowheelescalada sin contraseña es:permit nopass keepenv :wheel
Compilar desde el código fuente
sh
git clone https://github.com/zeroclaw-labs/zeroclaw.git
cd zeroclaw
cargo build --release
El binario de release se genera en target/release/zeroclaw. Una compilación limpia del conjunto de características predeterminado tarda un tiempo en hardware modesto; esto es lo esperado, ya que ZeroClaw es un espacio de trabajo de Rust de gran tamaño.
Para reducir el tamaño de la compilación, deshabilita las características que no necesites (consulta ./install.sh --list-features en una máquina Linux, o Cargo.toml):
sh
cargo build --release --no-default-features --features agent-runtime
Instalar el binario
Colócalo en algún lugar de PATH. /usr/local/bin es la ubicación convencional para los binarios instalados mediante ports en FreeBSD:
sh
doas install -m 755 target/release/zeroclaw /usr/local/bin/zeroclaw
zeroclaw --version
(~/.cargo/bin/zeroclaw funciona igual de bien si prefieres mantenerlo por usuario.)
Configuración de primera ejecución
sh
zeroclaw quickstart
Esto crea ~/.zeroclaw/ con una configuración inicial y te guía a través de la configuración del proveedor. La estructura de configuración y la precedencia son idénticas a las de cualquier otra plataforma: consulta Referencia → Configuración.
Autenticación del proveedor
La autenticación de proveedores no es específica de FreeBSD. Los proveedores con clave de API solo necesitan que la clave se configure a través del gateway, zerocode, zeroclaw config set o el entorno. Los proveedores con OAuth y suscripción (p. ej., una suscripción de OpenAI/Codex ChatGPT, Anthropic Claude Pro/Team) obtienen su token desde el panel de control o el flujo de inicio de sesión del propio proveedor, que luego configuras de la misma manera que lo harías con una clave de API.
Para el modelo completo de credenciales (claves API, tokens de OAuth/suscripción, anulaciones de variables de entorno y el almacén de secretos), consulte Configuración de proveedores → Credenciales y OAuth y autenticación por suscripción. Esa página es la fuente de verdad para todas las plataformas.
Ejecución como servicio (rc.d)
Debido a que zeroclaw service install no tiene un backend para FreeBSD, supervise el daemon con el daemon(8) nativo de FreeBSD mediante un script de rc.d. Esto le proporciona service zeroclaw start|stop|restart|status, reinicio en caso de fallo, un pidfile y arranque al iniciar el sistema.
Copias listas para instalar de cada script a continuación se encuentran en
dist/freebsd/(zeroclaw-run.sh, elzeroclaw.rcbásico y elzeroclaw-hardened.rcreforzado). Los dos scriptsrc.dincluyen un marcador de posición@@ZEROCLAW_USER@@que debe sustituir conseddurante la instalación, de modo que puede descargar los archivos en lugar de copiarlos y pegarlos: consultedist/freebsd/README.md. La guía paso a paso a continuación explica qué hace cada componente.
1. Script de lanzamiento
daemon(8) inicia el proceso hijo con un entorno mínimo, así que exporte un PATH completo (FreeBSD coloca git, python3, etc. bajo /usr/local/bin, que no está en el PATH predeterminado del servicio). El script rc.d lo ejecuta a través de daemon -u <user>, que según daemon(8) establece HOME, USER y SHELL a partir de la entrada passwd de esa cuenta antes de exec, por lo que ${HOME} ya es el directorio home de la cuenta de servicio (las cuentas cuyo home está en otra ubicación, y las anulaciones de usuario de ejecución en rc.conf, simplemente funcionan). Guárdelo como /usr/local/libexec/zeroclaw-run.sh:
sh
#!/bin/sh
# daemon -u <user> has already set HOME from the accountentrada passwd del usuario.
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. Script rc.d
Guardar como /usr/local/etc/rc.d/zeroclaw:
sh
#!/bin/sh
#
# PROVIDE: zeroclaw
# REQUIRE: NETWORKING DAEMON
# PALABRA CLAVE: shutdown
. /etc/rc.subr
name=zeroclaw
rcvar="zeroclaw_enable"
load_rc_config $name
: ${zeroclaw_enable:=NO}
# NO nombrar esto ${name}_user — rc.subr ejecutaría entonces su propio cambio de usuario con su
# and collide with daemon -u ("no se pudo establecer el entorno del usuario").
: ${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 permanecen con propietario root: rc.d (root) escribe el daemon -P pidfile
# aquí y confía en él después, por lo que el usuario sin privilegios del servicio no debe poder
# falsificarlo. daemon -o abre el logfile antes de cambiar al usuario ${zeroclaw_runas}.
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
Qué hacen los flags:
-r: supervisar y reiniciar el proceso hijo si finaliza (recuperación ante fallos).-P ${pidfile}: escribe el pid del supervisor para queservice zeroclaw stoppueda enviarle una señal.-o ${logfile}: redirige stdout/stderr del proceso hijo a un archivo de registro.-u ${zeroclaw_runas}: ejecuta zeroclaw como un usuario sin privilegios, no como root.
Por qué
daemon -uy nosu -m. Un patrón común esdaemon ... su -m user -c launcher. Evítelo:su(1)no reenvíaSIGTERMa su proceso hijo, por lo queservice zeroclaw stopmata al supervisordaemonpero deja atrás un procesozeroclawhuérfano, y el siguientestartacumula una segunda copia.daemon -u userhace quedaemon(8)sea el padre directo dezeroclaw, de modo que reenvía la señal de detención y se cierra limpiamente. (Si está obligado a usar un script basado ensupor otras razones, añada un barridopkill -f "zeroclaw daemon"a su ruta de detención.)
3. Habilitar e iniciar
sh
doas sysrc zeroclaw_enable=YES
doas sysrc zeroclaw_runas=youruser # la cuenta propietaria de ~/.zeroclaw
doas service zeroclaw start
doas service zeroclaw status
service zeroclaw stop / restart funcionan como se espera. Como zeroclaw_enable=YES está en /etc/rc.conf (escrito por sysrc), el daemon también se inicia durante el arranque.
4. Refuerzo de seguridad para operación desatendida y remota
El script anterior es correcto para una instalación interactiva de una sola instancia. Tres comportamientos de daemon(8) le sorprenderán en el momento en que maneje el servicio de forma remota (a través de ssh) o ejecute más de una copia. Los tres afectaron un despliegue en producción; las correcciones son pequeñas. Un script completo que incorpora todas las correcciones a continuación se distribuye como dist/freebsd/zeroclaw-hardened.rc: instálelo en lugar del script básico de zeroclaw.
El comando remoto service ... start se queda colgado. daemon -r hereda y mantiene abiertos los stdin/stdout/stderr con los que fue lanzado. Si ejecuta ssh host 'service zeroclaw start', el supervisor mantiene abierto el fd de stdout de su sesión ssh indefinidamente, por lo que ssh nunca recibe EOF y el comando se queda colgado aunque el daemon haya arrancado correctamente. Desacople los descriptores propios del supervisor: -o ${logfile} ya redirige la salida del proceso hijo, así que no se pierde nada:
sh
command_args="-r -P ${pidfile} -o ${logfile} -u ${zeroclaw_runas} ${launcher}"
# ...invocar el daemon con sus propios std{in,out,err} enviados a /dev/null:
/usr/sbin/daemon ${command_args} </dev/null >/dev/null 2>&1
Si usas la forma estándar command/command_args, envuelve el inicio en un start_cmd personalizado para que tú controles la redirección. Este único cambio es lo que hace que service zeroclaw start sea seguro de invocar desde ssh, CI o un push de gestión de configuración.
Ejecutar start repetidamente acumula supervisores huérfanos. Un start simple no comprueba si ya hay un supervisor en ejecución, por lo que un segundo start (o un start después de un fallo que dejó un pidfile obsoleto) lanza otro daemon que compite con el primero por el puerto del gateway. Haga que start sea idempotente rechazando la ejecución cuando ya existe un supervisor activo. Identifique el supervisor por la ruta del lanzador, no solo por el pidfile (el pidfile puede estar obsoleto). Dos trampas específicas de FreeBSD al hacer esto:
daemon(8)renombra su supervisor adaemon: /usr/local/libexec/zeroclaw-run.sh[<childpid>] (daemon). Por lo tanto,pgrep -f zeroclaw-run.shcoincide con el supervisor, pero unpgrep -fcon el nombre del binario no. Ancle en el prefijo literaldaemon:: esto coincide con el supervisor y nunca con el hijo, una ejecución manual del lanzador o el propio shell rc. Ancle también el[final que abre el[<childpid>]de daemon, de modo que un lanzador hermano cuyo nombre simplemente comience conzeroclaw-run.shno pueda coincidir (esto importa cuando se ejecuta un pool, consulte Ejecución de un pool de instancias más adelante).- FreeBSD
pgrep -fno respeta un ancla^inicial frente a esa cadena de retitulación:pgrep -f '^daemon: ...'no encuentra coincidencias. Elimine el^; confíe en el prefijodaemon:para la especificidad y escape el punto en.shcomo[.](y el corchete como[[]) para que sean literales.
sh
launcher_pat="daemon: /usr/local/libexec/zeroclaw-run[.]sh[[]"
zeroclaw_running()
{
pgrep -f "${launcher_pat}" >/dev/null 2>&1
}
read desde un pidfile de daemon -P reporta un falso negativo. daemon -P escribe el pid sin salto de línea final, por lo que IFS= read -r pid < "${pidfile}" devuelve un estado distinto de cero (EOF antes del salto de línea) aunque haya asignado pid correctamente. Si lo proteges con read -r pid < "$pf" || return 1, cada instancia en ejecución parecerá detenida y tu start idempotente lanzará alegremente un duplicado. No bases la ruta de éxito en el estado de salida de read: valida el valor en su lugar:
sh
pid=""
IFS= read -r pid < "${pidfile}" # NO usar `|| return 1` aquí
case "${pid}" in
''|*[!0-9]*) return 1 ;; # vacío o no numérico → tratar como no en ejecución
esac
Ejecución de un pool de instancias. Para ejecutar N daemons (p. ej., un pool de workers), asigne a cada uno su propio pidfile y logfile (worker.$i.pid, worker.$i.log) y ejecute el inicio/parada en un bucle sobre $i. Dado que el retitulado del supervisor es idéntico para cada instancia y no incluye argumentos por instancia, el pidfile es el único identificador por instancia: gestione la parada/estado a partir del pidfile y, en una parada completa, elimine cualquier supervisor sobrante al que no apunte ningún pidfile activo (iniciado manualmente, o cuyo pidfile haya quedado obsoleto).
Ejecución en un jail
Las jails le proporcionan a ZeroClaw una raíz aislada con sus propios paquetes, usuario de servicio y, opcionalmente, su propia IP, lo cual es útil si el host ejecuta otros servicios o si desea restringir el agente. La configuración del servicio es idéntica a la del caso del host; simplemente se ejecuta dentro de la jail. Esta guía describe paso a paso una thick jail clásica con las herramientas del sistema base (no se requiere un gestor de jails).
Opción de un solo paso.
dist/freebsd/zeroclaw-jail-setup.shautomatiza los pasos 1–3 a continuación: crea el jail, extrae una base compatible, añade la entrada en/etc/jail.conf, inicia el jail e instala el lanzador + el scriptrc.dreforzado dentro de él (doas sh zeroclaw-jail-setup.sh, conJAIL_NAME/JAIL_PATH/ZPOOL/ZEROCLAW_USERsobrescribibles mediante variables de entorno). El recorrido manual a continuación explica lo que hace.
1. Crea la jail
sh
# Dataset de ZFS para el jail (use un directorio normal si está en UFS).
doas zfs create -o mountpoint=/jails/zeroclaw zroot/jails/zeroclaw # ajustar el pool
# Extraer en él una base que coincida con la versión del HOST.
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. Configura e inicia
Añade una entrada de jail a /etc/jail.conf (en el lado del host). Este ejemplo comparte la red del host; configura ip4.addr en su lugar si le asignas al jail una dirección dedicada.
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+=zeroclaw
doas service jail start zeroclaw
3. Instalar ZeroClaw dentro del jail
Todo lo de las secciones anteriores se ejecuta dentro del jail: anteponga doas jexec zeroclaw … a los comandos, o abra un shell con doas jexec zeroclaw /bin/sh:
sh
doas jexec zeroclaw pkg install -y rust git # o copiar un binario compilado en el host
# build + install zeroclaw to /usr/local/bin/zeroclaw exactly as above, then:
doas jexec zeroclaw pw useradd zeroclaw -m -s /usr/sbin/nologin
Instala el launcher y el script rc.d en el sistema de archivos de la jail (desde el host, la raíz de la jail tiene el prefijo: /jails/zeroclaw/usr/local/libexec/… y /jails/zeroclaw/usr/local/etc/rc.d/…). Luego habilita e inicia el servicio dentro de la jail:
sh
doas jexec zeroclaw sysrc zeroclaw_enable=YES
doas jexec zeroclaw service zeroclaw start
doas jexec zeroclaw service zeroclaw status
Notas específicas de jail
- Edite los archivos del jail desde el host con
tee, no concp /dev/stdin. Canalice mediante… | doas tee /jails/zeroclaw/usr/local/etc/rc.d/zeroclaw >/dev/null;doas cp /dev/stdin …puede fallar a mitad de la copia concp: /dev/stdin: File changed. - El gateway se enlaza dentro del jail. El daemon escucha en loopback de forma predeterminada: para acceder a él desde el host o la LAN, inicia zeroclaw con
--host 0.0.0.0(editazeroclaw-run.sh) y asigna al jail una dirección accesible, o usa un proxy desde el host. - Prefiere el script
rc.dreforzado en un jail. Normalmente ejecutarásservicede forma no interactiva mediantejexec/ssh, que es exactamente donde el bloqueo destarty la acumulación de procesos huérfanos del script básico causan problemas: consulta Hardening. También mantiene/var/run/zeroclawcon propiedad de root dentro del jail para que el usuario de servicio sin privilegios no pueda falsificar el pidfile del supervisor. - Ejecutar varios demonios en un mismo jail (p. ej., un pool de workers) sigue la nota sobre pools de la sección de hardening: un pidfile/logfile por instancia y un
pgrepvinculado al retitulado del lanzador, dado que el jail comparte una única tabla de procesos.
Ejecución de la imagen de Linux bajo Podman + Linuxulator
La compilación nativa anterior es el camino correcto para ZeroClaw en sí. Pero algunas herramientas y skills respaldadas por Python dependen de wheels exclusivos de manylinux: polars, pyarrow y oracledb, por ejemplo, no publican wheels para FreeBSD, por lo que una herramienta que los importe no puede ejecutarse bajo el python3 nativo de FreeBSD. El Linuxulator de FreeBSD (capa de compatibilidad binaria con Linux) junto con Podman le permite ejecutar la imagen de contenedor oficial de Linux en un host FreeBSD, brindando a esas herramientas la ABI de Linux que esperan. Esto complementa el daemon nativo de rc.d: puede ejecutar cualquiera de los dos, o ambos en paralelo.
1. Requisitos previos
Habilite la ABI de Linux y confirme que reporta una versión de Linux:
sh
doas sysrc linux_enable="SÍ"
doas service linux start # carga los módulos y monta /compat/linux
sysctl compat.linux.osrelease # p. ej. compat.linux.osrelease: 5.15.0
linux_enable="YES" en /etc/rc.conf también carga la ABI al arrancar. Luego instala Podman:
sh
doas pkg install -y podman
2. Descargar la imagen: forzar la plataforma Linux
FreeBSD Podman usa por defecto os=freebsd al resolver una lista de manifiestos. Las imágenes de ZeroClaw se publican solo para linux/amd64 y linux/arm64, por lo que un podman pull simple falla con no image found in manifest list for architecture ..., OS freebsd. Fuerza la plataforma Linux explícitamente:
sh
doas podman pull --os linux --arch amd64 ghcr.io/zeroclaw-labs/zeroclaw:debian
Use la etiqueta
debianen lugar delatest: la imagen distrolesslatestno tiene shell, lo que dificulta la depuración bajo emulación. Consulte Docker & Containers para ver la lista completa de imágenes.
3. Ejecuta el contenedor
La imagen de Linux se comporta exactamente como se documenta en Docker & Containers, espera el estado persistente en /zeroclaw-data y genera automáticamente una configuración en la primera ejecución:
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
Mantén las banderas --os linux --arch amd64 en cada run (no solo en pull) para que Podman no vuelva a resolver al valor predeterminado de FreeBSD.
Notas sobre Linuxulator
- Persistencia tras el arranque. El
--restart=alwayspropio de Podman solo reinicia el contenedor dentro de un Podman en ejecución; no sobrevivirá por sí solo a un reinicio del host. Supervise elpodman startdesde un scriptrc.d(el mismo patrón que el servicio nativo) o una entrada cron@rebootpara que el contenedor vuelva a iniciarse después de que el host se reinicie. - Redes.
-p 42617:42617publica la puerta de enlace a través del bridge de Podman. Si la configuración de bridge/CNI no está configurada en tu host,--network hostes la alternativa más sencilla: el contenedor comparte entonces directamente la pila de red del host. - No todo se emula sin problemas. Linuxulator cubre la superficie de syscalls comunes, pero los binarios exóticos pueden encontrarse con llamadas no implementadas. Si una herramienta se comporta mal, revisa
dmesgen busca de advertenciaslinux:antes de asumir que es un error de ZeroClaw.
Registros
sh
tail -f /var/log/zeroclaw.log
Configure el nivel de registro mediante las opciones estándar de configuración / variables de entorno: consulte Operations → Logs & observability.
Verificar
sh
zeroclaw --version
service zeroclaw status
# si el daemon expone el gateway local (predeterminado 127.0.0.1:42617):
fetch -qo - http://127.0.0.1:42617/health
Una carga útil de estado "status":"ok" significa que el gateway está activo; el campo runtime de la respuesta contiene el estado de salud por componente (canales, proveedores, etc.).
Desinstalar
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 # opcional — elimina la configuración + el historial
Siguiente
- Gestión de servicios: cómo funcionan los backends propios en otras plataformas
- Referencia → Config: estructura del archivo de configuración
- Quickstart: primera conversación
- Operaciones → Visión general: ejecución en producción