Install on Linux
Pre-built binaries for x86_64 and ARM64. Published GNU binaries require glibc 2.34+ (for example RHEL/Rocky/AlmaLinux 9, Ubuntu 22.04, or Debian 12), libgcc_s, and possibly libz.
Download, Verify, and Install the Binary
Pick the block that matches your CPU architecture and run it in an empty directory. uname -m prints x86_64 or aarch64. Both are GNU/glibc binaries; use a glibc-based system or the published container image.
ASSET=ferrum-edge-linux-x86_64
BASE=https://github.com/ferrum-edge/ferrum-edge/releases/download/v0.9.10
curl -fsSLO "$BASE/$ASSET" &&
curl -fsSLO "$BASE/$ASSET.sha256" &&
sha256sum -c "$ASSET.sha256" &&
sudo install -m 0755 "$ASSET" /usr/local/bin/ferrum-edge &&
/usr/local/bin/ferrum-edge version
# Expected: ferrum-edge-linux-x86_64: OK
# ferrum-edge 0.9.10 (x86_64-unknown-linux-gnu)
ASSET=ferrum-edge-linux-aarch64
BASE=https://github.com/ferrum-edge/ferrum-edge/releases/download/v0.9.10
curl -fsSLO "$BASE/$ASSET" &&
curl -fsSLO "$BASE/$ASSET.sha256" &&
sha256sum -c "$ASSET.sha256" &&
sudo install -m 0755 "$ASSET" /usr/local/bin/ferrum-edge &&
/usr/local/bin/ferrum-edge version
# Expected: ferrum-edge-linux-aarch64: OK
# ferrum-edge 0.9.10 (aarch64-unknown-linux-gnu)
&&, so a failed download or a checksum mismatch stops the block before anything is installed, and the final version line does not run. If sha256sum 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.
Create a Configuration File
Start with file mode — no database required. This sample proxies /api to a backend on localhost:3000; step 3 starts a throwaway backend there.
sudo mkdir -p /etc/ferrum
sudo tee /etc/ferrum/config.yaml << 'EOF'
version: "1"
proxies:
- id: "my-api"
listen_path: "/api"
backend_scheme: http
backend_host: "localhost"
backend_port: 3000
strip_listen_path: true
plugins:
- plugin_config_id: "rate-limit"
- plugin_config_id: "log-stdout"
plugin_configs:
- id: "rate-limit"
plugin_name: "rate_limiting"
scope: proxy
proxy_id: my-api
enabled: true
config:
limit_by: ip
limits:
- scope: default
requests_per_minute: 1000
- id: "log-stdout"
plugin_name: "stdout_logging"
scope: proxy
proxy_id: my-api
enabled: true
config: {}
EOF
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 it is already present on most systems.
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 ...
ferrum-edge validate --spec /etc/ferrum/config.yaml &&
ferrum-edge run --spec /etc/ferrum/config.yaml -v
# Leave this running. If validate fails, fix the config before continuing.
# 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
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 systemd section until both checks pass. Stop the backend and gateway with Ctrl+C when you are done.
Systemd Service
For production deployments, run Ferrum Edge as a systemd service with automatic restarts.
Create a Dedicated User
sudo useradd --system --no-create-home --shell /bin/false ferrum
sudo install -d -o ferrum -g ferrum /var/log/ferrum /var/lib/ferrum
Create Environment File
sudo tee /etc/ferrum/env << 'EOF'
FERRUM_MODE=database
FERRUM_DB_TYPE=postgres
FERRUM_DB_URL=postgres://ferrum:secret@localhost/ferrum
FERRUM_ADMIN_JWT_SECRET=your-secure-jwt-secret-min-32-characters
FERRUM_ADMIN_BIND_ADDRESS=127.0.0.1
FERRUM_LOG_LEVEL=info
EOF
sudo chmod 600 /etc/ferrum/env
sudo chown ferrum:ferrum /etc/ferrum/env
Create the Systemd Unit File
[Unit]
Description=Ferrum Edge API Gateway
Documentation=https://ferrumedge.com
After=network.target
Wants=network-online.target
[Service]
Type=simple
User=ferrum
Group=ferrum
EnvironmentFile=/etc/ferrum/env
ExecStart=/usr/local/bin/ferrum-edge run
# SIGHUP reload is supported in file mode, not this database-mode service.
Restart=on-failure
RestartSec=5s
TimeoutStopSec=30s
KillMode=mixed
LimitNOFILE=65536
# Security hardening
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/log/ferrum /var/lib/ferrum
[Install]
WantedBy=multi-user.target
Enable and Start the Service
sudo systemctl daemon-reload
sudo systemctl enable ferrum-edge
sudo systemctl start ferrum-edge
sudo systemctl status ferrum-edge
# View logs
sudo journalctl -u ferrum-edge -f
Build from Source
# Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source "$HOME/.cargo/env"
# Install protoc (Protocol Buffers compiler)
# Ubuntu/Debian:
sudo apt-get install -y protobuf-compiler
# Fedora/RHEL:
# sudo dnf install -y protobuf-compiler
# 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
# The binary will be at:
./target/release/ferrum-edge version
# Install
sudo cp target/release/ferrum-edge /usr/local/bin/