Quick start

Running in five minutes, protected in ten

Two supported paths: the bundled compose stack for evaluation, or a source build for production deployments you control.

Path A Docker Compose Path B Build from source Time ~5 minutes Store PostgreSQL 14+

Before you start

The compose path only needs Docker. A source build needs the Rust and Node toolchains plus protoc.

Docker

Engine 24+ with Compose v2

Runs the control plane, one agent and PostgreSQL together.

PostgreSQL

14+ (16 recommended)

Required by the control plane for sites, rules and versions.

Ports

9080 · 9090 · 80 · 443

9080 serves the API and dashboard, 9090 the gRPC control plane.

TLS

Self-signed on first boot

Replace it or trust it before you expose the console.

Quick start

Docker Compose

The compose file starts PingWAF in all-in-one mode next to PostgreSQL and pulls the published image.

  1. Clone the repository

    The compose file and the example TOML config live in the repository root.

    bash
    git clone https://github.com/shuaiZend/PingWAF.git
    cd PingWAF
  2. Start the stack

    Set JWT_SECRET and ADMIN_PASSWORD first if this host is reachable by anyone else.

    bash
    export JWT_SECRET="$(openssl rand -hex 32)"
    export ADMIN_PASSWORD="$(openssl rand -hex 16)"
    docker compose up -d
  3. Open the dashboard

    The console is served over HTTPS with a certificate generated on first boot, so the browser warns until you trust it or upload your own under Settings.

    bash
    curl --connect-timeout 2 --max-time 3 http://localhost:9080/healthz
    # {"status":"ok","database":"up"}
  4. Add your first site

    Create a site with the hostname you will point at the agent, then enable the protections you want for that hostname only.

Prebuilt binaries are published for Linux amd64/arm64; the Docker image covers both architectures.
localhost:9080/sites
Site list in the PingWAF console with traffic and protection state
The site list is where enforcement starts: one row per hostname.

Quick start

Build from source

Use this path when you need a custom build, a different feature set, or an auditable binary.

  1. Install the toolchain

    protoc is mandatory: without it the proto crate falls back to placeholders and downstream crates fail to compile.

    bash
    # macOS
    brew install protobuf
    
    # Debian / Ubuntu
    sudo apt install protobuf-compiler cmake
  2. Build the dashboard

    The console is embedded into the binary, so it must be built first.

    bash
    cd web && npm ci && npm run build && cd ..
  3. Build the binary

    The full feature set includes the WAF engine, challenges and certificate automation.

    bash
    cargo build --release --bin pingwaf --features full
  4. Run all-in-one

    Point it at a PostgreSQL instance; the schema is created on first boot.

    bash
    ./target/release/pingwaf all-in-one \
      --db-url "postgres://pingwaf:pingwaf@localhost:5432/pingwaf"
On Linux you can skip the build: curl -fsSL https://raw.githubusercontent.com/shuaiZend/PingWAF/main/install.sh | sudo bash -s -- --mode all-in-one
localhost:9080/agents
Agent fleet page listing enrolled edge agents and heartbeat state
A source build can run as the control plane, then enroll agents from the fleet page.

First sign-in

The control plane seeds an administrator on first boot. The dashboard forces a password change before it is usable.

defaults.env

Dashboard https://localhost:9080
Email admin@pingwaf.local
Password pingwaf123
JWT secret ≥ 16 characters

Change the defaults before exposing anything

PINGWAF_JWT_SECRET and PINGWAF_ADMIN_PASSWORD have working defaults. Set both, set PINGWAF_ALLOW_REGISTRATION=false, and keep 9080 on a private network or behind a VPN.
bash
export PINGWAF_JWT_SECRET="$(openssl rand -hex 32)"
export PINGWAF_ADMIN_PASSWORD="$(openssl rand -hex 16)"
export PINGWAF_ALLOW_REGISTRATION=false
localhost:9080/login
PingWAF sign-in page with email and password fields
Sign in with the seeded administrator account; passkeys can be bound later from Settings.

Next steps

Once the control plane answers, the rest is configuration.

Create a site

A site binds a hostname to origin pools, routes and the protections you enable for it.

Site model

Connect edge agents

Run pingwaf server on the control node and pingwaf agent on each edge node; agents register over gRPC :9090.

Distributed deployment

Turn protections on

Enable the WAF engine, CC shield or bot policy per site — nothing is enforced until you do.

Capabilities

Ship logs somewhere

Send request logs to Elasticsearch and keep raw captures in PostgreSQL for replay.

Observability

If something does not start

The build fails in pingwaf-proto

protoc is missing. Install protobuf-compiler (or brew install protobuf) and rebuild — the crate silently falls back to placeholder files without it.

The browser refuses the dashboard certificate

The console is HTTPS with a self-signed certificate. Trust the downloaded certificate, or upload your own under Settings → Control plane HTTPS. Set PINGWAF_TLS_SANS to the hostname you use.

An agent never appears in the fleet

Check that the agent can reach the gRPC control plane on :9090 (PINGWAF_SERVER_URL) and that it is not blocked by a firewall or TLS-terminating proxy.

Port 443 is closed

443 opens only after a certificate is issued or uploaded for a site. Until then the agent serves plain HTTP on port 80.

Need the long version?

The deployment and architecture documents cover systemd, distributed topologies, configuration precedence and the full environment variable reference.