Installation

Zentinel can be installed via the install script, from pre-built binaries, built from source, or run as an OCI container.

The easiest way to install Zentinel is using the install script, which automatically detects your OS and architecture:

curl -fsSL https://get.zentinelproxy.io | sh

The script downloads the appropriate binary and installs it to ~/.local/bin. You may need to add this to your PATH:

export PATH="$HOME/.local/bin:$PATH"

Add this line to your shell profile (~/.bashrc, ~/.zshrc, etc.) to make it permanent.

Verify Installation

zentinel --version

Pre-built Binaries

Alternatively, download binaries manually from GitHub Releases.

Linux (amd64)

curl -LO https://github.com/zentinelproxy/zentinel/releases/latest/download/zentinel-linux-amd64.tar.gz
tar xzf zentinel-linux-amd64.tar.gz
sudo mv zentinel /usr/local/bin/

macOS (Apple Silicon)

curl -LO https://github.com/zentinelproxy/zentinel/releases/latest/download/zentinel-darwin-arm64.tar.gz
tar xzf zentinel-darwin-arm64.tar.gz
sudo mv zentinel /usr/local/bin/

macOS (Intel)

curl -LO https://github.com/zentinelproxy/zentinel/releases/latest/download/zentinel-darwin-amd64.tar.gz
tar xzf zentinel-darwin-amd64.tar.gz
sudo mv zentinel /usr/local/bin/

Build from Source

Building from source requires Rust 1.85 or later.

Prerequisites

# Install Rust via rustup
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# Ensure you have Rust 1.85+
rustup update stable

Clone and Build

git clone https://github.com/zentinelproxy/zentinel.git
cd zentinel
cargo build --release

The binary will be at target/release/zentinel.

Install System-wide

sudo cp target/release/zentinel /usr/local/bin/

OCI Container

Zentinel provides official OCI container images.

Pull the Image

# Using Docker
docker pull ghcr.io/zentinelproxy/zentinel:latest

# Using Podman
podman pull ghcr.io/zentinelproxy/zentinel:latest

Run the Container

# Using Docker
docker run -d \
  --name zentinel \
  -p 8080:8080 \
  -p 9090:9090 \
  -v $(pwd)/zentinel.kdl:/etc/zentinel/zentinel.kdl:ro \
  ghcr.io/zentinelproxy/zentinel:latest

# Using Podman
podman run -d \
  --name zentinel \
  -p 8080:8080 \
  -p 9090:9090 \
  -v $(pwd)/zentinel.kdl:/etc/zentinel/zentinel.kdl:ro \
  ghcr.io/zentinelproxy/zentinel:latest

Compose File

Works with both Docker Compose and Podman Compose:

version: '3.8'

services:
  zentinel:
    image: ghcr.io/zentinelproxy/zentinel:latest
    ports:
      - "8080:8080"   # HTTP proxy
      - "9090:9090"   # Metrics
    volumes:
      - ./zentinel.kdl:/etc/zentinel/zentinel.kdl:ro
      - ./certs:/etc/zentinel/certs:ro
    restart: unless-stopped

Run with:

# Docker Compose
docker compose up -d

# Podman Compose
podman-compose up -d

Configuration File Location

By default, Zentinel looks for configuration in these locations:

  1. Path specified with -c or --config flag
  2. ./zentinel.kdl (current directory)
  3. /etc/zentinel/zentinel.kdl

Create a Basic Config

mkdir -p /etc/zentinel
cat > /etc/zentinel/zentinel.kdl << 'EOF'
server {
    worker-threads 0
}

listeners {
    listener "http" {
        address "0.0.0.0:8080"
        protocol "http"
    }
}

routes {
    route "default" {
        matches {
            path-prefix "/"
        }
        upstream "backend"
    }
}

upstreams {
    upstream "backend" {
        targets {
            target {
                address "127.0.0.1:3000"
            }
        }
    }
}
EOF

Running Zentinel

Basic Usage

# Run with default config location
zentinel

# Run with specific config file
zentinel -c /path/to/zentinel.kdl

# Validate config without running
zentinel -c zentinel.kdl --test

# Run with verbose logging
zentinel -c zentinel.kdl --log-level debug

Command Line Options

OptionDescription
-c, --config <FILE>Path to configuration file
-t, --testTest configuration and exit
--log-level <LEVEL>Log level (trace, debug, info, warn, error)
--versionPrint version information
--helpPrint help

Systemd Service

For production deployments on Linux, create a systemd service:

sudo cat > /etc/systemd/system/zentinel.service << 'EOF'
[Unit]
Description=Zentinel Reverse Proxy
After=network.target

[Service]
Type=simple
User=zentinel
Group=zentinel
ExecStart=/usr/local/bin/zentinel -c /etc/zentinel/zentinel.kdl
ExecReload=/bin/kill -HUP $MAINPID
Restart=always
RestartSec=5
LimitNOFILE=65535

[Install]
WantedBy=multi-user.target
EOF

# Create zentinel user
sudo useradd -r -s /sbin/nologin zentinel

# Set permissions
sudo chown -R zentinel:zentinel /etc/zentinel

# Enable and start
sudo systemctl daemon-reload
sudo systemctl enable zentinel
sudo systemctl start zentinel

Managing the Service

# Check status
sudo systemctl status zentinel

# View logs
sudo journalctl -u zentinel -f

# Reload configuration (graceful)
sudo systemctl reload zentinel

# Restart
sudo systemctl restart zentinel

Verifying the Installation

After starting Zentinel, verify it’s running:

# Check if listening
curl -I http://localhost:8080/

# Check metrics endpoint
curl http://localhost:9090/metrics

Next Steps