Open-Source Wikis

/

Pingora

/

Pingora

/

Getting started

cloudflare/pingora

Getting started

The canonical walkthrough is docs/quick_start.md in this repository — it builds a round-robin load balancer in about 60 lines. This page summarizes prerequisites and gives the quickest possible "hello, proxy" path.

Prerequisites

  • Rust toolchain. Pingora's MSRV is 1.84 (declared in the workspace and the README). The MSRV rolls forward roughly every six months.
  • Linux is tier-1. macOS and other Unixes mostly work for development. Windows support is "preliminary, best-effort." See pingora-core/src/protocols/windows.rs for the small Windows-only shims.
  • System libraries: Pingora needs build tooling for whichever TLS backend you pick.
    • openssl feature: OpenSSL headers + Perl 5 (for the OpenSSL build scripts).
    • boringssl feature: Clang.
    • rustls / s2n features: pure-Rust or s2n-tls system library respectively.
  • CPU: x86_64 and aarch64 are both supported.

Cloning and building

git clone https://github.com/cloudflare/pingora.git
cd pingora
cargo build
cargo test --workspace

The workspace builds without TLS by default (no default features). For a more typical setup:

cargo build -p pingora --features "proxy lb cache openssl"

There is also a Dockerfile at the repo root that produces a build environment with the right toolchain.

Running the load-balancer example

The complete code is at pingora-proxy/examples/load_balancer.rs. The minimum you need:

use async_trait::async_trait;
use pingora::prelude::*;
use std::sync::Arc;

pub struct LB(Arc<LoadBalancer<RoundRobin>>);

#[async_trait]
impl ProxyHttp for LB {
    type CTX = ();
    fn new_ctx(&self) {}

    async fn upstream_peer(
        &self,
        _session: &mut Session,
        _ctx: &mut (),
    ) -> Result<Box<HttpPeer>> {
        let upstream = self.0.select(b"", 256).unwrap();
        Ok(Box::new(HttpPeer::new(
            upstream,
            true,
            "one.one.one.one".to_string(),
        )))
    }
}

fn main() {
    let mut server = Server::new(None).unwrap();
    server.bootstrap();
    let upstreams = LoadBalancer::try_from_iter(["1.1.1.1:443", "1.0.0.1:443"]).unwrap();
    let mut lb = http_proxy_service(&server.configuration, LB(Arc::new(upstreams)));
    lb.add_tcp("0.0.0.0:6188");
    server.add_service(lb);
    server.run_forever();
}

Server::new(None) skips CLI parsing. Pass Some(Opt::parse_args()) to wire up -c/--conf, -d/--daemon, -u/--upgrade, etc.

Test it:

curl 127.0.0.1:6188 -svo /dev/null

Useful CLI options

The full list comes from pingora-core/src/server/configuration/mod.rs (the Opt struct). The important ones:

Flag Effect
-c PATH / --conf PATH Load YAML config
-d / --daemon Detach and run in background
-u / --upgrade Take over from a running instance (graceful upgrade)
-t / --test Test the config file and exit

Running the test suite

cargo test --workspace                # unit tests for everything
cargo test --workspace --features "openssl proxy lb cache"  # with TLS
cargo bench -p pingora-ketama        # benchmarks (criterion-based)

Pingora has integration tests under pingora-proxy/tests/ and pingora-core/tests/ that spin up real servers on loopback ports. Some tests are flaky in CI; see Debugging.

Using Pingora as a dependency

Add the umbrella crate plus the features you need:

[dependencies]
async-trait = "0.1"
pingora = { version = "0.8", features = ["lb", "proxy", "openssl"] }

pingora's feature flags are the easiest entry point. They turn on the right pieces of pingora-core, pingora-proxy, pingora-cache, and pingora-load-balancing for you. See the cargo features documented inline in pingora/Cargo.toml.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Getting started – Pingora wiki | Factory