
Ein Reverse-Proxy wie nginx, basierend auf Pingora, einfach und effizient.
Bevor die Version von pingap stabil ist, werden keine Pull-Requests akzeptiert. Wenn Sie Fragen haben, erstellen Sie bitte zuerst ein neues Issue.

Pingap ist ein Hochleistungs-Reverse-Proxy, der von Cloudflare Pingora unterstützt wird. Er vereinfacht das operative Management durch dynamisches, unterbrechungsfreies Hot-Reloading der Konfiguration über prägnante TOML-Dateien und eine intuitive Weboberfläche.
Seine Kernstärke liegt in einem leistungsstarken Plugin-System, das über zwanzig sofort einsatzbereite Funktionen für Authentifizierung (JWT, Key Auth), Sicherheit (CSRF, IP-/Referer-/UA-Einschränkungen), Verkehrssteuerung (Rate Limiting, Caching), Inhaltsmodifikation (Weiterleitungen, Inhaltsersetzung) und Beobachtbarkeit (Request ID) bietet. Das macht Pingap nicht nur zu einem Proxy, sondern zu einem flexiblen und erweiterbaren Anwendungs-Gateway, das entwickelt wurde, um komplexe Szenarien vom API-Schutz bis zu modernen Webanwendungsbereitstellungen mühelos zu bewältigen.
中文说明 | Dokumentation · 中文文档 | Beispiele | 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"]
🚀 Hohe Leistung & Zuverlässigkeit
🔧 Dynamisch & einfach zu bedienen
🧩 Leistungsstarke Erweiterbarkeit
📊 Moderne Observability
Der einfachste Weg, mit Pingap zu starten, ist die Verwendung von Docker Compose.
docker-compose.yml-Datei:# docker-compose.yml
version: '3.8'
services:
pingap:
image: vicanso/pingap:latest # For production, use a specific version like vicanso/pingap:0.12.1-full
container_name: pingap-instance
restart: always
ports:
- "80:80"
- "443:443"
volumes:
# Mount a local directory to persist all configurations and data
- ./pingap_data:/opt/pingap
environment:
# Configure using environment variables
- PINGAP_CONF=/opt/pingap/conf
- PINGAP_ADMIN_ADDR=0.0.0.0:80/pingap
- PINGAP_ADMIN_USER=pingap
- PINGAP_ADMIN_PASSWORD=<YourSecurePassword> # Change this!
command:
# Start pingap and enable hot-reloading
- pingap
- --autoreload
mkdir pingap_data
docker-compose up -d
Ihre Pingap-Instanz ist jetzt in Betrieb! Sie können auf die Web-Admin-Oberfläche unter http://localhost/pingap mit den von Ihnen festgelegten Anmeldedaten zugreifen.
Für Linux und macOS können Sie die neueste vorgefertigte Binärdatei mit einem Befehl unter /usr/local/bin/pingap installieren:
curl -sSL https://raw.githubusercontent.com/vicanso/pingap/main/install.sh | sh
Optionale Umgebungsvariablen:
PINGAP_FULL=1 — installiert die -full-Version (alle optionalen Funktionen aktiviert)PINGAP_LIBC=gnu — unter Linux die glibc-Version anstelle der standardmäßigen statischen musl-Version verwenden# Voll ausgestattete Version
curl -sSL https://raw.githubusercontent.com/vicanso/pingap/main/install.sh | PINGAP_FULL=1 sh
Unterstützte Ziele: Linux x86_64/arm64, Darwin x86_64/arm64. Alle verfügbaren Assets finden Sie auf der Releases-Seite.
Detailliertere Anweisungen, einschließlich der Ausführung über eine Binärdatei, finden Sie in unserer Dokumentation.
Ein einziger Befehl genügt, um eine Domain über HTTPS zu bedienen und an ein Backend weiterzuleiten:
# Zertifikat von Let's Encrypt anfordern
pingap --domain=pingap.io --upstream=192.168.1.1:3000
# oder eigenes Zertifikat verwenden
pingap --domain=pingap.io --upstream=192.168.1.1:3000 --cert=/etc/ssl/pingap.io
Ohne --cert fordert Pingap über die HTTP-01-Challenge ein Zertifikat von Let's Encrypt an. pingap.io muss also auf diesen Host zeigen und Port 80 muss aus dem Internet erreichbar sein. Das ausgestellte Zertifikat wird unter ~/.pingap/acme/<domains>.toml gespeichert und beim Neustart wiederverwendet – die Ausstellung ist ratenbegrenzt, also löschen Sie es nicht. Alles andere wird weiterhin über die Befehlszeile gesteuert: Eine Änderung von --upstream wird beim nächsten Start wirksam, ohne das Zertifikat anzutasten.
--cert akzeptiert entweder das Zertifikat selbst oder das Verzeichnis, in dem es liegt – die gängigen Layouts fullchain.pem / privkey.pem, cert.pem / key.pem und tls.crt / tls.key werden automatisch erkannt; für alles andere verwenden Sie --key. Der Listener verwendet standardmäßig 0.0.0.0:443, wenn ein Zertifikat vorhanden ist, und 0.0.0.0:80, wenn weder Zertifikat noch Domain angegeben sind; --addr überschreibt dies. --upstream akzeptiert eine kommagetrennte Liste von Backends, --domain eine kommagetrennte Liste von Hosts (lassen Sie es weg, um jeden Host über einfaches HTTP zu bedienen).
Die Konfiguration wird bei jedem Start neu generiert und kann daher nicht über die Admin-Oberfläche bearbeitet werden: Verwenden Sie für alles, was über einen einzelnen Server hinausgeht, --conf, das nicht mit diesen Flags kombiniert werden kann.
Pingap ist darauf ausgelegt, sich ohne Ausfallzeiten an Konfigurationsänderungen anzupassen.
Hot Reload (--autoreload): Bei den meisten Änderungen – etwa beim Aktualisieren von Upstreams, Locations oder Plugins – übernimmt Pingap die neue Konfiguration innerhalb von 10 Sekunden ohne Neustart. Dies ist der empfohlene Modus für containerisierte Umgebungen.
Graceful Restart (-a oder --autorestart): Bei grundlegenden Änderungen (wie dem Ändern von Server-Listening-Ports) führt dieser Modus einen vollständigen Neustart ohne Ausfallzeiten durch und stellt sicher, dass keine Anfragen verloren gehen.
make dev
Wenn Sie eine Weboberfläche benötigen, sollten Sie Node.js installieren und die Web-Assets erstellen.
# generate admin web asset
cd web
npm i
cd ..
make build-web
server "test" {
addr = "127.0.0.1:6118"
location "github-api" {
path = "/api"
proxy_set_headers = ["Host:api.github.com"]
rewrite = "^/api/(?<path>.+)$ /$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/(?<path>.+)$ /$1"
[locations.static]
plugins = ["staticServe"]
[servers.test]
addr = "127.0.0.1:6118"
locations = ["github-api", "static"]
Die entsprechenden Anweisungen finden Sie hier: https://pingap.io/crates/config.
graph TD;
server["HTTP Server"];
locationA["Location A"];
locationB["Location B"];
locationPluginListA["Proxy Plugin List A"];
locationPluginListB["Proxy Plugin List B"];
upstreamA1["Upstream A1"];
upstreamA2["Upstream A2"];
upstreamB1["Upstream B1"];
upstreamB2["Upstream B2"];
locationResponsePluginListA["Response Plugin List A"];
locationResponsePluginListB["Response Plugin List B"];
start("New Request") --> server
server -- "host:HostA, Path:/api/*" --> locationA
server -- "Path:/rest/*"--> locationB
locationA -- "Exec Proxy Plugins" --> locationPluginListA
locationB -- "Exec Proxy Plugins" --> locationPluginListB
locationPluginListA -- "proxy pass: 10.0.0.1:8001" --> upstreamA1
locationPluginListA -- "proxy pass: 10.0.0.2:8001" --> upstreamA2
locationPluginListA -- "done" --> response
locationPluginListB -- "proxy pass: 10.0.0.1:8002" --> upstreamB1
locationPluginListB -- "proxy pass: 10.0.0.2:8002" --> upstreamB2
locationPluginListB -- "done" --> response
upstreamA1 -- "Exec Response Plugins" --> locationResponsePluginListA
upstreamA2 -- "Exec Response Plugins" --> locationResponsePluginListA
upstreamB1 -- "Exec Response Plugins" --> locationResponsePluginListB
upstreamB2 -- "Exec Response Plugins" --> locationResponsePluginListB
locationResponsePluginListA --> response
locationResponsePluginListB --> response
response["HTTP Response"] --> stop("Logging");
CPU: M4 Pro, Thread: 1
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
Unsere aktuelle MSRV ist 1.88
Dieses Projekt ist unter der Apache License, Version 2.0 lizenziert.