Install / macOS

Install on macOS

Native binaries for both Intel and Apple Silicon. Ferrum Edge was benchmarked on Apple Silicon — expect excellent performance.

Apple Silicon recommended: The ARM64 binary is compiled natively for M-series chips. The benchmarks showing ~102K RPS HTTP/1.1 were measured on Apple Silicon.
1

Download, Verify, and Install the Binary

Pick the block that matches your Mac and run it in an empty directory. uname -m prints arm64 on Apple Silicon and x86_64 on Intel. Each block also clears the Gatekeeper quarantine flag that macOS adds to files downloaded through a browser.

bash — Apple Silicon (uname -m: arm64)
ASSET=ferrum-edge-macos-aarch64
BASE=https://github.com/ferrum-edge/ferrum-edge/releases/download/v0.9.10
curl -fsSLO "$BASE/$ASSET" &&
curl -fsSLO "$BASE/$ASSET.sha256" &&
shasum -a 256 -c "$ASSET.sha256" &&
(xattr -d com.apple.quarantine "$ASSET" 2>/dev/null || true) &&
sudo install -d -m 0755 /usr/local/bin &&
sudo install -m 0755 "$ASSET" /usr/local/bin/ferrum-edge &&
/usr/local/bin/ferrum-edge version
# Expected: ferrum-edge-macos-aarch64: OK
#           ferrum-edge 0.9.10 (aarch64-apple-darwin)
bash — Intel (uname -m: x86_64)
ASSET=ferrum-edge-macos-x86_64
BASE=https://github.com/ferrum-edge/ferrum-edge/releases/download/v0.9.10
curl -fsSLO "$BASE/$ASSET" &&
curl -fsSLO "$BASE/$ASSET.sha256" &&
shasum -a 256 -c "$ASSET.sha256" &&
(xattr -d com.apple.quarantine "$ASSET" 2>/dev/null || true) &&
sudo install -d -m 0755 /usr/local/bin &&
sudo install -m 0755 "$ASSET" /usr/local/bin/ferrum-edge &&
/usr/local/bin/ferrum-edge version
# Expected: ferrum-edge-macos-x86_64: OK
#           ferrum-edge 0.9.10 (x86_64-apple-darwin)
⚠
Every command is chained with &&, so a failed download or a checksum mismatch stops the block before anything is installed, and the final version line does not run. If shasum prints FAILED, delete both files and download again; do not install that binary. The version check calls /usr/local/bin/ferrum-edge by full path so an older copy elsewhere on your PATH cannot answer for it.
2

Create a Configuration File

This sample proxies /api to a backend on localhost:3000; step 3 starts a throwaway backend there.

bash
mkdir -p ~/.ferrum
cat > ~/.ferrum/config.yaml << 'EOF'
version: "1"
proxies:
  - id: "local-api"
    listen_path: "/api"
    backend_scheme: http
    backend_host: "localhost"
    backend_port: 3000
    strip_listen_path: true
    plugins:
      - plugin_config_id: "cors-dev"
      - plugin_config_id: "log-stdout"

plugin_configs:
  - id: "cors-dev"
    plugin_name: "cors"
    scope: proxy
    proxy_id: local-api
    enabled: true
    config:
      allowed_origins: ["http://localhost:3001", "http://localhost:5173"]
      allowed_methods: [GET, POST, PUT, DELETE, OPTIONS]
      allowed_headers: [Content-Type, Authorization]
  - id: "log-stdout"
    plugin_name: "stdout_logging"
    scope: proxy
    proxy_id: local-api
    enabled: true
    config: {}
EOF
3

Start Ferrum Edge and Send a First Request

ferrum-edge run stays in the foreground, so the walkthrough uses three terminals: one for a test backend, one for the gateway, and one for the checks. Any HTTP server on port 3000 works as the backend; Python's built-in server is used because macOS ships python3 with the Xcode Command Line Tools.

bash — Terminal A: throwaway backend on :3000
mkdir -p /tmp/ferrum-backend && cd /tmp/ferrum-backend &&
echo 'hello from the backend' > index.html &&
python3 -m http.server 3000 --bind 127.0.0.1
# Leave this running. Expected: Serving HTTP on 127.0.0.1 port 3000 ...
bash — Terminal B: validate, then run the gateway
ferrum-edge validate --spec ~/.ferrum/config.yaml &&
ferrum-edge run --spec ~/.ferrum/config.yaml -v
# Leave this running. If validate fails, fix the config before continuing.
bash — Terminal C: checks (run while A and B are still up)
# 1. Gateway liveness on the admin listener (no auth).
curl -fsS http://localhost:9000/live; echo
# Expected: {"status":"ok"}

# 2. A real proxied request: /api is stripped and forwarded to the backend.
curl -sS -i http://localhost:8000/api/
# Expected: HTTP/1.1 200 OK ... followed by: hello from the backend
ℹ️
Read the results before moving on. If check 1 fails, the gateway is not running; look at Terminal B. If check 2 returns 502 with an X-Gateway-Error header, the gateway is alive but cannot reach the backend; look at Terminal A. A passing liveness check alone does not prove that proxying works, so do not continue to the launchd section until both checks pass. Stop the backend and gateway with Ctrl+C when you are done.

Run as a Background Service (launchd)

On macOS, use launchd to run Ferrum Edge as a user-level background service that starts automatically on login.

xml — ~/Library/LaunchAgents/com.ferrumedge.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
  "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key>
  <string>com.ferrumedge</string>
  <key>ProgramArguments</key>
  <array>
    <string>/usr/local/bin/ferrum-edge</string>
    <string>run</string>
    <string>--spec</string>
    <string>/Users/YOUR_USER/.ferrum/config.yaml</string>
  </array>
  <key>RunAtLoad</key>
  <true/>
  <key>KeepAlive</key>
  <true/>
  <key>StandardOutPath</key>
  <string>/tmp/ferrum-edge.log</string>
  <key>StandardErrorPath</key>
  <string>/tmp/ferrum-edge-error.log</string>
</dict>
</plist>
bash
launchctl load ~/Library/LaunchAgents/com.ferrumedge.plist
launchctl start com.ferrumedge

Build from Source

bash
# Install Rust via rustup
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source "$HOME/.cargo/env"

# Install protoc via Homebrew
brew install protobuf

# Clone and build
git clone https://github.com/ferrum-edge/ferrum-edge.git
cd ferrum-edge
git checkout v0.9.10
./scripts/install-build-deps.sh
cargo build --release

# Install
sudo cp target/release/ferrum-edge /usr/local/bin/
Admin API Reference → Docker Install Browse Plugins