Baike.dev
All toolsAI codingTrendingOpen sourceNewsSubmit
Log in
< Back to tools
P

pingap

> 编程语言
Open source

A reverse proxy like nginx, built on pingora, simple and efficient.

1.3K stars0 likes0 views
WebsiteGitHub

About

A reverse proxy like nginx, built on pingora, simple and efficient.

pingap

Before the pingap version is stable, no pull requests will be accepted. If you have any questions, please create a new issue first.

Overview

Pingap is a high-performance reverse proxy powered by the Cloudflare Pingora . It simplifies operational management by enabling dynamic, zero-downtime configuration hot-reloading through concise TOML files and an intuitive web admin interface.

Its core strength lies in a powerful plugin system, offering over twenty out-of-the-box features for Authentication (JWT, Key Auth), Security (CSRF, IP/Referer/UA Restrictions), Traffic Control (Rate Limiting, Caching), Content Modification (Redirects, Content Substitution), and Observability (Request ID). This makes Pingap not just a proxy, but a flexible and extensible application gateway, engineered to effortlessly handle complex scenarios from API protection to modern web application deployments.

中文说明 | Documentation · 中文文档 | Examples | Plugins | Crates

flowchart LR
  internet("Internet") -- request --> pingap["Pingap"]
  pingap -- proxy:pingap.io/api/* --> apiUpstream["10.1.1.1,10.1.1.2"]
  pingap -- proxy:cdn.pingap.io --> cdnUpstream["10.1.2.1,10.1.2.2"]
  pingap -- proxy:/* --> upstream["10.1.3.1,10.1.3.2"]

Key Features

  • High Performance & Reliability

  • Built with Rust for memory safety and top-tier performance.

  • Powered by Cloudflare Pingora, a battle-tested asynchronous networking library.

  • Supports HTTP/1.1, HTTP/2, and gRPC-web proxying.

  • Dynamic & Easy to Use

  • Zero-downtime configuration changes with hot-reloading.

  • Simple, human-readable TOML configuration files.

  • Full-featured Web UI for intuitive, real-time management.

  • Supports both file and etcd as configuration backends.

  • Supports configuration history record, can restore to the history version with one click.

  • Powerful Extensibility

  • A rich plugin system to handle common gateway tasks.

  • Advanced routing with host, path, and regex matching.

  • Built-in service discovery via static lists, DNS, or Docker labels.

  • Automated HTTPS with Let's Encrypt (supporting both HTTP-01 and DNS-01 challenges).

  • Modern Observability

  • Native Prometheus metrics for monitoring (pull & push modes).

  • Integrated OpenTelemetry support for distributed tracing.

  • Highly customizable access logs with over 30 variables.

  • Detailed performance metrics, including upstream connect time, processing time, and more.

Getting Started

The easiest way to get started with Pingap is by using Docker Compose.

  1. Create a docker-compose.yml file:
…
  1. Create a data directory and run:
mkdir pingap_data
docker-compose up -d
  1. Access the Admin UI:

Your Pingap instance is now running! You can access the web admin interface at http://localhost/pingap with the credentials you set.

Install the binary via curl

For Linux and macOS, you can install the latest pre-built binary to /usr/local/bin/pingap with one command:

curl -sSL https://raw.githubusercontent.com/vicanso/pingap/main/install.sh | sh

Optional environment variables:

  • PINGAP_FULL=1 — install the -full build (all optional features enabled)
  • PINGAP_LIBC=gnu — on Linux, use the glibc build instead of the default musl static build
  • PINGAP_TLS=rustls — on Linux, install the -rustls-full build (rustls TLS backend, all optional features, no OpenSSL); see TLS backend
# Full-featured build
curl -sSL https://raw.githubusercontent.com/vicanso/pingap/main/install.sh | PINGAP_FULL=1 sh

Supported targets: Linux x86_64/arm64, Darwin x86_64/arm64. See the releases page for all available assets.

For more detailed instructions, including running from a binary, check out our Documentation.

Start a proxy without a config file

A single command is enough to serve a domain over https and forward it to a backend:

# certificate requested from let's encrypt
pingap --domain=pingap.io --upstream=192.168.1.1:3000

# or bring your own certificate
pingap --domain=pingap.io --upstream=192.168.1.1:3000 --cert=/etc/ssl/pingap.io

Without --cert, Pingap asks Let's Encrypt for a certificate through the HTTP-01 challenge, so pingap.io must resolve to this host and port 80 must be reachable from the internet. The issued certificate is kept in ~/.pingap/acme/.toml and reused on restart — issuing is rate limited, so do not delete it. Everything else still comes from the command line: changing --upstream takes effect on the next start without touching the certificate.

--cert accepts the certificate itself or the directory holding it — the common fullchain.pem / privkey.pem, cert.pem / key.pem and tls.crt / tls.key layouts are detected automatically, use --key for anything else. The listener defaults to 0.0.0.0:443 when there is a certificate and 0.0.0.0:80 when there is neither a certificate nor a domain, and --addr overrides it. --upstream takes a comma separated list of backends, --domain a comma separated list of hosts (omit it to serve every host over plain http). Requests for a host that is not listed are answered with 404.

The configuration is generated on every start, so it cannot be edited through the admin UI: for anything beyond a single server use --conf, which cannot be combined with these flags.

Dynamic Configuration

Pingap is designed to adapt to configuration changes without downtime.

Hot Reload (--autoreload): For most changes—like updating upstreams, locations, or plugins—Pingap applies the new configuration within 10 seconds without a restart. This is the recommended mode for containerized environments.

Graceful Restart (-a or --autorestart): For fundamental changes (like modifying server listen ports), this mode performs a full, zero-downtime restart, ensuring no requests are dropped.

The hand-over is readiness-driven rather than timed: the replacement is started with -d -u, reports back over a unix socket next to the upgrade socket the moment it is ready to take over the listeners, and only then does the running process send itself SIGQUIT. If the replacement exits, its daemon dies, or basic.restart_ready_timeout (default 1m) passes first, the restart is abandoned and the running process keeps serving.

Development

make dev

If you need a web admin, you should install nodejs and build web asssets.

# generate admin web asset
cd web
npm i 
cd ..
make build-web

TLS backend

The default build terminates TLS with OpenSSL, compiled from source by the openssl crate. To build with rustls instead, which drops the OpenSSL source build (a C compiler is still needed: rustls' crypto providers, ring and aws-lc-rs, contain C and assembly):

cargo build --release --no-default-features --features tls-rustls
# with the optional features as well
cargo build --release --no-default-features --features tls-rustls,full

The rustls build rejects the per-server tls_min_version, tls_max_version, tls_cipher_list and tls_ciphersuites settings at config validation (startup, --test, auto-restart): it always offers TLS 1.2 and 1.3 with rustls' default cipher suites. The admin UI disables those fields when the running binary is a rustls build. Everything else, including dynamic SNI certificates, self-signed CA issuance, ACME and the upstream ca option, behaves the same. Pre-built images carry the same variant: vicanso/pingap:rustls-full (and :-rustls-full for a release), alongside :latest and :full. One difference to know about when verifying upstreams: rustls (webpki) rejects a server certificate that carries CA:TRUE, which OpenSSL accepts, so a backend using a quick openssl req -x509 self-signed certificate needs a proper leaf signed by a CA (or a self-signed leaf without the CA flag) before the upstream ca option can trust it. --version (long form), the startup log and the admin home page all report which backend a binary was built with.

Configuration

server "test" {
  addr = "127.0.0.1:6118"

  location "github-api" {
    path = "/api"
    proxy_set_headers = ["Host:api.github.com"]
    rewrite = "^/api/(?.+)$ /$1"

    upstream "api" {
      addrs     = ["api.github.com:443"]
      discovery = "dns"
      sni       = "api.github.com"
    }
  }

  location "static" {
    plugin "staticServe" {
      category = "directory"
      path     = "~/Downloads"
      step     = "request"
    }
  }
}
[upstreams.api]
addrs = ["api.github.com:443"]
discovery = "dns"
sni = "api.github.com"

[plugins.staticServe]
category = "directory"
path = "~/Downloads"
step = "request"

[locations.github-api]
upstream = "api"
path = "/api"
proxy_set_headers = ["Host:api.github.com"]
rewrite = "^/api/(?.+)$ /$1"

[locations.static]
plugins = ["staticServe"]

[servers.test]
addr = "127.0.0.1:6118"
locations = ["github-api", "static"]

You can find the relevant instructions here: https://pingap.io/crates/config.

Proxy step

…

Performance

CPU: M4 Pro, Thread: 1

Ping no access log

wrk 'http://127.0.0.1:6118/ping' --latency

Running 10s test @ http://127.0.0.1:6118/ping
  2 threads and 10 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    66.41us   23.67us   1.11ms   76.54%
    Req/Sec    73.99k     2.88k   79.77k    68.81%
  Latency Distribution
     50%   67.00us
     75%   80.00us
     90%   91.00us
     99%  116.00us
  1487330 requests in 10.10s, 194.32MB read
Requests/sec: 147260.15
Transfer/sec:     19.24MB

Rust version

Our current MSRV is 1.96

License

This project is Licensed under Apache License, Version 2.0.

Issues· 0 open

View all issuesOpen on GitHub

No open issues yet, or sync has not completed.

> Tags

Rustpingorareverse-proxy

No comments yet. Be the first to share.

> Details

PublishedAug 1, 2026
UpdatedSep 17, 2026
Category编程语言
PricingOpen source

> Related tools

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言