{"id":13484336,"url":"https://github.com/vicanso/pingap","last_synced_at":"2026-04-12T04:05:31.511Z","repository":{"id":227065328,"uuid":"768613191","full_name":"vicanso/pingap","owner":"vicanso","description":"A reverse proxy like nginx, built on pingora, simple and efficient.","archived":false,"fork":false,"pushed_at":"2026-03-29T01:04:51.000Z","size":14986,"stargazers_count":1183,"open_issues_count":23,"forks_count":83,"subscribers_count":14,"default_branch":"main","last_synced_at":"2026-03-30T06:54:55.316Z","etag":null,"topics":["pingora","reverse-proxy"],"latest_commit_sha":null,"homepage":"https://pingap.io/pingap-zh/","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vicanso.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-03-07T12:10:20.000Z","updated_at":"2026-03-29T19:52:44.000Z","dependencies_parsed_at":"2024-03-11T12:53:38.795Z","dependency_job_id":"c2b2c57d-c660-412a-a488-da3b217ff26f","html_url":"https://github.com/vicanso/pingap","commit_stats":null,"previous_names":["vicanso/pingap"],"tags_count":124,"template":false,"template_full_name":null,"purl":"pkg:github/vicanso/pingap","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vicanso%2Fpingap","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vicanso%2Fpingap/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vicanso%2Fpingap/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vicanso%2Fpingap/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vicanso","download_url":"https://codeload.github.com/vicanso/pingap/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vicanso%2Fpingap/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31290749,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T13:12:26.723Z","status":"ssl_error","status_checked_at":"2026-04-01T13:12:25.102Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["pingora","reverse-proxy"],"created_at":"2024-07-31T17:01:22.706Z","updated_at":"2026-04-01T18:06:07.661Z","avatar_url":"https://github.com/vicanso.png","language":"Rust","funding_links":[],"categories":["Rust"],"sub_categories":[],"readme":"# pingap\n\nBefore the pingap version is stable, no pull requests will be accepted. If you have any questions, please create a new issue first.\n\n![Pingap Logo](./asset/pingap-logo.png)\n\n## Overview\n\nPingap is a high-performance reverse proxy powered by the [`Cloudflare Pingora`](https://github.com/cloudflare/pingora) . It simplifies operational management by enabling dynamic, zero-downtime configuration hot-reloading through concise TOML files and an intuitive web admin interface.\n\nIts 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.\n\n\n[中文说明](./README_zh.md) | [Examples](./examples/README.md) | [Documentation](http://pingap.io/pingap-en/)\n\n```mermaid\nflowchart LR\n  internet(\"Internet\") -- request --\u003e pingap[\"Pingap\"]\n  pingap -- proxy:pingap.io/api/* --\u003e apiUpstream[\"10.1.1.1,10.1.1.2\"]\n  pingap -- proxy:cdn.pingap.io --\u003e cdnUpstream[\"10.1.2.1,10.1.2.2\"]\n  pingap -- proxy:/* --\u003e upstream[\"10.1.3.1,10.1.3.2\"]\n```\n\n## Key Features\n\n- 🚀 High Performance \u0026 Reliability\n  - Built with Rust for memory safety and top-tier performance.\n  - Powered by Cloudflare Pingora, a battle-tested asynchronous networking library.\n  - Supports HTTP/1.1, HTTP/2, and gRPC-web proxying.\n\n- 🔧 Dynamic \u0026 Easy to Use\n  - Zero-downtime configuration changes with hot-reloading.\n  - Simple, human-readable TOML configuration files.\n  - Full-featured Web UI for intuitive, real-time management.\n  - Supports both file and etcd as configuration backends.\n  - Supports configuration history record, can restore to the history version with one click.\n\n- 🧩 Powerful Extensibility\n  - A rich plugin system to handle common gateway tasks.\n  - Advanced routing with host, path, and regex matching.\n  - Built-in service discovery via static lists, DNS, or Docker labels.\n  - Automated HTTPS with Let's Encrypt (supporting both HTTP-01 and DNS-01 challenges).\n\n- 📊 Modern Observability\n  - Native Prometheus metrics for monitoring (pull \u0026 push modes).\n  - Integrated OpenTelemetry support for distributed tracing.\n  - Highly customizable access logs with over 30 variables.\n  - Detailed performance metrics, including upstream connect time, processing time, and more.\n\n## 🚀 Getting Started\n\nThe easiest way to get started with Pingap is by using Docker Compose.\n\n1. Create a `docker-compose.yml` file:\n\n```yaml\n# docker-compose.yml\nversion: '3.8'\n\nservices:\n  pingap:\n    image: vicanso/pingap:latest # For production, use a specific version like vicanso/pingap:0.12.1-full\n    container_name: pingap-instance\n    restart: always\n    ports:\n      - \"80:80\"\n      - \"443:443\"\n    volumes:\n      # Mount a local directory to persist all configurations and data\n      - ./pingap_data:/opt/pingap\n    environment:\n      # Configure using environment variables\n      - PINGAP_CONF=/opt/pingap/conf\n      - PINGAP_ADMIN_ADDR=0.0.0.0:80/pingap\n      - PINGAP_ADMIN_USER=pingap\n      - PINGAP_ADMIN_PASSWORD=\u003cYourSecurePassword\u003e # Change this!\n    command:\n      # Start pingap and enable hot-reloading\n      - pingap\n      - --autoreload\n```\n\n2. Create a data directory and run:\n\n```bash\nmkdir pingap_data\ndocker-compose up -d\n```\n\n3. Access the Admin UI:\n\nYour Pingap instance is now running! You can access the web admin interface at http://localhost/pingap with the credentials you set.\n\nFor more detailed instructions, including running from a binary, check out our [Documentation](https://pingap.io/pingap-en/docs/getting_started).\n\n\n## Dynamic Configuration\n\nPingap is designed to adapt to configuration changes without downtime.\n\nHot 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.\n\nGraceful 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.\n\n\n## 🔧 Development\n\n```bash\nmake dev\n```\n\nIf you need a web admin, you should install nodejs and build web asssets.\n\n```bash\n# generate admin web asset\ncd web\nnpm i \ncd ..\nmake build-web\n```\n\n\n## 📝 Configuration\n\n```hcl\nserver \"test\" {\n  addr = \"127.0.0.1:6118\"\n\n  location \"github-api\" {\n    path = \"/api\"\n    proxy_set_headers = [\"Host:api.github.com\"]\n    rewrite = \"^/api/(?\u003cpath\u003e.+)$ /$1\"\n\n    upstream \"api\" {\n      addrs     = [\"api.github.com:443\"]\n      discovery = \"dns\"\n      sni       = \"api.github.com\"\n    }\n  }\n\n  location \"static\" {\n    plugin \"staticServe\" {\n      category = \"directory\"\n      path     = \"~/Downloads\"\n      step     = \"request\"\n    }\n  }\n}\n```\n\n```toml\n[upstreams.api]\naddrs = [\"api.github.com:443\"]\ndiscovery = \"dns\"\nsni = \"api.github.com\"\n\n[plugins.staticServe]\ncategory = \"directory\"\npath = \"~/Downloads\"\nstep = \"request\"\n\n[locations.github-api]\nupstream = \"api\"\npath = \"/api\"\nproxy_set_headers = [\"Host:api.github.com\"]\nrewrite = \"^/api/(?\u003cpath\u003e.+)$ /$1\"\n\n[locations.static]\nplugins = [\"staticServe\"]\n\n[servers.test]\naddr = \"127.0.0.1:6118\"\nlocations = [\"github-api\", \"static\"]\n```\n\nYou can find the relevant instructions here: [https://pingap.io/pingap-en/docs/config](https://pingap.io/pingap-en/docs/config).\n\n## 🔄 Proxy step\n\n```mermaid\ngraph TD;\n  server[\"HTTP Server\"];\n  locationA[\"Location A\"];\n  locationB[\"Location B\"];\n  locationPluginListA[\"Proxy Plugin List A\"];\n  locationPluginListB[\"Proxy Plugin List B\"];\n  upstreamA1[\"Upstream A1\"];\n  upstreamA2[\"Upstream A2\"];\n  upstreamB1[\"Upstream B1\"];\n  upstreamB2[\"Upstream B2\"];\n  locationResponsePluginListA[\"Response Plugin List A\"];\n  locationResponsePluginListB[\"Response Plugin List B\"];\n\n  start(\"New Request\") --\u003e server\n\n  server -- \"host:HostA, Path:/api/*\" --\u003e locationA\n\n  server -- \"Path:/rest/*\"--\u003e locationB\n\n  locationA -- \"Exec Proxy Plugins\" --\u003e locationPluginListA\n\n  locationB -- \"Exec Proxy Plugins\" --\u003e locationPluginListB\n\n  locationPluginListA -- \"proxy pass: 10.0.0.1:8001\" --\u003e upstreamA1\n\n  locationPluginListA -- \"proxy pass: 10.0.0.2:8001\" --\u003e upstreamA2\n\n  locationPluginListA -- \"done\" --\u003e response\n\n  locationPluginListB -- \"proxy pass: 10.0.0.1:8002\" --\u003e upstreamB1\n\n  locationPluginListB -- \"proxy pass: 10.0.0.2:8002\" --\u003e upstreamB2\n\n  locationPluginListB -- \"done\" --\u003e response\n\n  upstreamA1 -- \"Exec Response Plugins\" --\u003e locationResponsePluginListA\n  upstreamA2 -- \"Exec Response Plugins\" --\u003e locationResponsePluginListA\n\n  upstreamB1 -- \"Exec Response Plugins\" --\u003e locationResponsePluginListB\n  upstreamB2 -- \"Exec Response Plugins\" --\u003e locationResponsePluginListB\n\n  locationResponsePluginListA --\u003e response\n  locationResponsePluginListB --\u003e response\n\n  response[\"HTTP Response\"] --\u003e stop(\"Logging\");\n```\n\n## 📊 Performance\n\nCPU: M4 Pro, Thread: 1\n\n### Ping no access log\n\n```bash\nwrk 'http://127.0.0.1:6118/ping' --latency\n\nRunning 10s test @ http://127.0.0.1:6118/ping\n  2 threads and 10 connections\n  Thread Stats   Avg      Stdev     Max   +/- Stdev\n    Latency    66.41us   23.67us   1.11ms   76.54%\n    Req/Sec    73.99k     2.88k   79.77k    68.81%\n  Latency Distribution\n     50%   67.00us\n     75%   80.00us\n     90%   91.00us\n     99%  116.00us\n  1487330 requests in 10.10s, 194.32MB read\nRequests/sec: 147260.15\nTransfer/sec:     19.24MB\n```\n\n\u003cdiv align=\"center\"\u003e\n  \u003cimg width=\"200\" src=\"./asset/qrcode.jpg\" alt=\"Pingap qrcode\" /\u003e\n\u003c/div\u003e\n\n## 📦 Rust version\n\nOur current MSRV is 1.88\n\n## 📄 License\n\nThis project is Licensed under [Apache License, Version 2.0](./LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvicanso%2Fpingap","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvicanso%2Fpingap","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvicanso%2Fpingap/lists"}