🤖 Running Codex CLI on FreeBSD 15

How to run OpenAI's coding agent on FreeBSD via Linux compatibility • 06.03.2026

The Problem: Codex CLI only ships Linux/macOS/Windows binaries. FreeBSD is not supported natively.
The Solution: Use FreeBSD's Linux compatibility layer (Linuxulator) with Rocky Linux 9 base.

1. Why Doesn't It Work Natively?

Codex CLI is distributed as a Node.js wrapper that spawns a native binary (compiled from Rust). When you try to install it:

$ npm i -g @openai/codex
$ codex
Error: Unsupported platform: freebsd (x64)

The npm package explicitly blocks FreeBSD in codex.js:

const PLATFORM_PACKAGE_BY_TARGET = {
  "x86_64-unknown-linux-musl": "@openai/codex-linux-x64",
  "aarch64-unknown-linux-musl": "@openai/codex-linux-arm64",
  "x86_64-apple-darwin": "@openai/codex-darwin-x64",
  "aarch64-apple-darwin": "@openai/codex-darwin-arm64",
  "x86_64-pc-windows-msvc": "@openai/codex-win32-x64",
  "aarch64-pc-windows-msvc": "@openai/codex-win32-arm64",
};
// FreeBSD not listed → throws error

2. Available Options

Tool FreeBSD Native Linuxulator Linux Jail
Codex CLI ❌ No Maybe ✅ Yes
OpenCode ❌ No Maybe ✅ Yes
Claude Code ❌ No Maybe ✅ Yes

We'll try Linuxulator first (simpler), then fall back to a Linux jail if needed.

3. Linux Base Options

FreeBSD provides several Linux compatibility bases:

$ pkg search linux_base
linux_base-c7-7.9.2009_5    CentOS 7.9 (glibc 2.17)
linux_base-rl9-9.7          Rocky Linux 9.7 (glibc 2.34)
Recommendation: Use linux_base-rl9 (Rocky Linux 9).
It's modern, actively maintained, and compatible with current software.

4. Installation Steps

Step 1: Enable Linux Compatibility

# Enable Linuxulator at boot
sysrc linux_enable="YES"
# Output: linux_enable: NO -> YES

# Start Linux compatibility now (loads kernel module)
service linux start
Important: You must start the Linux service before installing linux_base packages, otherwise you'll get:
Cannot install package: kernel missing 64-bit Linux support

Step 2: Install Rocky Linux 9 Base

pkg install linux_base-rl9

# Expected output:
Updating FreeBSD-ports repository catalogue...
Fetching data: 100% 10 MiB 2.1 M/s 00:05
...
The following 1 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:
    linux_base-rl9: 9.7

Number of packages to be installed: 1
The process will require 361 MiB more space.
58 MiB to be downloaded.

Proceed with this action? [y/N]: y
[1/1] Fetching linux_base-rl9-9.7: 100% 58 MiB 8.8 M/s 00:07
[1/1] Extracting linux_base-rl9-9.7: 100%

This installs the Rocky Linux userspace in /compat/linux/ (~361 MB).

Step 3: Mount Linux Filesystems

Linux binaries need these special filesystems mounted:

FilesystemPurpose
linprocfsExposes /proc as Linux expects it (process info, /proc/cpuinfo, etc.)
linsysfsExposes /sys (device/kernel info that many Linux binaries read)
devfsShares the host devfs into the Linux compat tree
fdescfsMakes /dev/fd/0,1,2 work (stdin/stdout/stderr by fd number)
tmpfs/dev/shm for POSIX shared memory (required by many apps, browsers, etc.)
# Mount immediately
mount -t linprocfs linprocfs /compat/linux/proc
mount -t linsysfs linsysfs /compat/linux/sys
mount -t devfs devfs /compat/linux/dev
mount -t fdescfs -o linrdlnk fdescfs /compat/linux/dev/fd
mount -t tmpfs tmpfs /compat/linux/dev/shm
Important: The linrdlnk option on fdescfs is required! Without it, readlink() on /proc/self/fd/N returns FreeBSD-style paths instead of Linux-style paths, causing some Linux binaries to crash when introspecting their own fd paths.

Add to /etc/fstab for boot persistence:

# Add these lines to /etc/fstab
linprocfs   /compat/linux/proc   linprocfs  rw          0  0
linsysfs    /compat/linux/sys    linsysfs   rw          0  0
devfs       /compat/linux/dev    devfs      rw          0  0
fdescfs     /compat/linux/dev/fd fdescfs    rw,linrdlnk 0  0
tmpfs       /compat/linux/dev/shm tmpfs     rw,mode=1777 0  0

Verify after reboot:

$ mount | grep compat
linprocfs on /compat/linux/proc (linprocfs, local)
linsysfs on /compat/linux/sys (linsysfs, local)
devfs on /compat/linux/dev (devfs)
fdescfs on /compat/linux/dev/fd (fdescfs)
tmpfs on /compat/linux/dev/shm (tmpfs, local)

Step 4: Download Codex Linux Binary

# Create directory
mkdir -p /home/clawdie/codex
cd /home/clawdie/codex

# Download musl build (statically linked, better compatibility)
fetch https://github.com/openai/codex/releases/latest/download/codex-x86_64-unknown-linux-musl.tar.gz

# Extract
tar -xzf codex-x86_64-unknown-linux-musl.tar.gz

# Make executable
chmod +x codex-x86_64-unknown-linux-musl

# Optional: rename for convenience
ln -s codex-x86_64-unknown-linux-musl codex
Why musl? The musl build is statically linked and doesn't depend on a specific glibc version, making it more portable across Linux compatibility layers.

Step 5: Run Codex

cd /home/clawdie/codex
./codex

Or add to your PATH:

# Add to ~/.shrc or ~/.bashrc
export PATH="/home/clawdie/codex:$PATH"

# Then run from anywhere
codex

5. Troubleshooting

If the musl binary fails: Try the glibc build instead:
cd /home/clawdie/codex
fetch https://github.com/openai/codex/releases/latest/download/codex-x86_64-unknown-linux-gnu.tar.gz
tar -xzf codex-x86_64-unknown-linux-gnu.tar.gz
./codex-x86_64-unknown-linux-gnu
Common errors and fixes:

6. Alternative: Ubuntu Linux Jail

If Linuxulator doesn't work, use a full Linux jail via Bastille:

# Install Bastille
pkg install bastille

# Bootstrap Ubuntu template
bastille bootstrap ubuntu-22.04

# Create jail (NAT mode for single-IP servers)
bastille create -L codex-jail 10.0.0.2 vtnet0

# Enter jail
bastille console codex-jail

# Inside jail - install Codex natively
apt update && apt install -y curl nodejs npm
npm install -g @openai/codex
codex

7. Summary

✅ Quick Start Commands
# 1. Enable Linux compat (must be done BEFORE installing linux_base!)
sysrc linux_enable="YES"
service linux start

# 2. Install Rocky Linux base
pkg install linux_base-rl9

# 3. Mount filesystems (note: linrdlnk is required for fdescfs!)
mount -t linprocfs linprocfs /compat/linux/proc
mount -t linsysfs linsysfs /compat/linux/sys
mount -t devfs devfs /compat/linux/dev
mount -t fdescfs -o linrdlnk fdescfs /compat/linux/dev/fd
mount -t tmpfs tmpfs /compat/linux/dev/shm

# 4. Add to /etc/fstab for persistence
cat >> /etc/fstab << 'EOF'
linprocfs   /compat/linux/proc   linprocfs  rw          0  0
linsysfs    /compat/linux/sys    linsysfs   rw          0  0
devfs       /compat/linux/dev    devfs      rw          0  0
fdescfs     /compat/linux/dev/fd fdescfs    rw,linrdlnk 0  0
tmpfs       /compat/linux/dev/shm tmpfs     rw,mode=1777 0  0
EOF

# 5. Verify mounts (after reboot)
mount | grep compat

# 6. Download and run Codex
mkdir -p /home/clawdie/codex && cd /home/clawdie/codex
fetch https://github.com/openai/codex/releases/latest/download/codex-x86_64-unknown-linux-musl.tar.gz
tar -xzf codex-x86_64-unknown-linux-musl.tar.gz
./codex-x86_64-unknown-linux-musl

Resources