English version | Π ΡΡΡΠΊΠ°Ρ Π²Π΅ΡΡΠΈΡ
A modern MTProto proxy manager for Telegram with a web interface, Telegram bot, and monitoring system.
Disclaimer: PopuGate is inspired by MTProxyMax β thanks to the author for the idea. This project is developed with active use of AI-assisted tools and may contain rough edges β it is a work in progress. Bug reports and pull requests are welcome.
The recommended way to run PopuGate with the built-in web interface and Nginx reverse proxy:
- Create a
docker-compose.ymlfile:
services:
popugate-backend:
image: ghcr.io/fussraider/popugate:latest
container_name: popugate-backend
restart: unless-stopped
network_mode: host
cap_add:
- NET_ADMIN
volumes:
- ./data:/data
- /var/run/docker.sock:/var/run/docker.sock
environment:
- ADMIN_PASSWORD=mysecretpassword
- POPUGATE_DATA_DIR=/data
- TZ=Europe/Moscow
popugate-web:
image: ghcr.io/fussraider/popugate-web:latest
container_name: popugate-web
restart: unless-stopped
extra_hosts:
- "host.docker.internal:host-gateway"
ports:
- "80:80"
- "8443:8443"
environment:
- DOMAIN_NAME=your-domain.com
- BACKEND_URL=http://host.docker.internal:8090/api/
volumes:
- ./certbot/conf:/etc/letsencrypt:ro
- ./certbot/www:/var/www/certbot:ro
depends_on:
- popugate-backend
certbot:
image: certbot/certbot
container_name: certbot
volumes:
- ./certbot/conf:/etc/letsencrypt
- ./certbot/www:/var/www/certbot
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"- Start the stack:
docker compose up -dBuilding images manually
# Backend
DOCKER_BUILDKIT=1 docker buildx build -t popugate . --load
# Frontend
cd web && DOCKER_BUILDKIT=1 docker buildx build -t popugate-web . --loadNote: The backend container runs in
network_mode: hostβ all ports (8090, 443, 9090, etc.) are bound directly on the host. Do not add aportssection topopugate-backend. The web container connects to the backend viahost.docker.internal(configurable via theBACKEND_URLenvironment variable).
Make sure Docker is installed and running on the server before launching. Run as root (for iptables and Docker access).
# 1. Download the latest release
wget -O popugate https://github.com/fussraider/PopuGate/releases/latest/download/popugate-linux-amd64
chmod +x popugate
# 2. Set the admin password
sudo ./popugate setup
# 3. Start the server
sudo ./popugate serverThe backend is available on port 8090, the proxy engine on port 443. To run in the background, install the systemd service (see below).
Supported platforms: Linux (Ubuntu, Debian, CentOS, RHEL, Fedora, Rocky, AlmaLinux, Alpine).
| Port | Purpose |
|---|---|
8090 |
REST API and web interface |
80 / 8443 |
Web interface HTTP/HTTPS (Docker Compose) |
443 |
Incoming MTProto connections (bound by the engine) |
9090 |
Prometheus metrics |
Proxy and metrics ports are configured individually per instance.
| Variable | Description |
|---|---|
ADMIN_PASSWORD |
Admin password (first run) |
POPUGATE_DATA_DIR |
Working directory (database, configs, caches). Also set via --data (-d) flag |
POPUGATE_DEPLOYMENT |
Deployment type (docker β set automatically in the image) |
DEBUG / GIN_MODE |
Debug mode (true/debug = debug, default is release) |
LOG_LEVEL |
Log level (debug, info, warn, error, fatal) |
BACKUP_ENCRYPTION_KEY |
Backup encryption key (64 hex characters, AES-256-GCM) |
TELEMT_VERSION |
Override the telemt engine version |
TELEMT_COMMIT |
Override the commit/ref for engine build |
TELEMT_REPO |
Override the engine repository URL |
--port <number>(-p) β HTTP server port (default:8090)--data <path>(-d) β working directory (overridesPOPUGATE_DATA_DIR)--db <path>β path to the SQLite file (default:<data-dir>/settings.db)
# Example: run with a custom configuration
sudo -E ./popugate server --port 9090 --data /var/lib/popugateWhen using Docker Compose, you can set up automatic Let's Encrypt SSL certificate issuance:
sudo ./scripts/init-ssl.sh your-domain.com your-email@example.comSpecify the domain in docker-compose.yml: DOMAIN_NAME=your-domain.com. Certificates are renewed automatically every 12 hours. Port 80 must be accessible from the internet for Let's Encrypt to work.
Anti-phishing protection: When DOMAIN_NAME is set (not localhost), nginx automatically rejects requests with unknown Host headers β unknown domains pointed at your server will receive no response. The backend also checks the Host header when the web_url setting is configured.
The web interface supports light/dark themes and bilingual UI (Russian / English).
Proxy status, active secrets, connections, traffic, quick actions (start/stop/restart), system health, real-time resource monitoring (CPU, memory, disk).
Access key management: creation, deletion, rotation, limits (connections, IPs, traffic quota), expiration, QR codes, tags, archiving, bulk operations, search, JSON export/import.
Pre-configured limit presets (connections, IPs, quota, expiration, tags) for quick application to secrets.
Independent proxies with their own port, masking domains, FakeTLS, and access tags. Multi-domain support, hot reload, logs (SSE), bulk operations.
- Anti-Blocking: Per-instance TCPMSS fragmentation to defeat DPI ClientHello reassembly, and TLS fronting content serving for active probing defense
- Zero-Downtime Reload (Swing Routing): Recreates containers on a swing port, atomically redirects traffic via iptables NAT, drains old connections gracefully, then stops the old container β all without dropping a single live connection
- Hot Config Reload: Apply secret and upstream changes to a running container instantly without any restart
- Live Logs: Real-time per-instance container log streaming via SSE
Proxy chains (SOCKS4/SOCKS5/Shadowsocks) with weight-based balancing, network interface binding, and automatic health-based failover/recovery (auto-disablement).
- Bulk Add: Verify and import multiple proxies concurrently in a multi-step wizard, featuring auto-protocol detection (
socks5://,socks4://,ss://), live exit IP detection, latency threshold filtering, and transactional batch insertion. While Middle-Proxy mode is enabled,ss://lines are skipped with a warning instead of failing the whole batch. - Shadowsocks: Egress through a Shadowsocks server via its
ss://URL. Requires Middle-Proxy mode disabled in Settings (the engine rejects Shadowsocks upstreams while Middle-Proxy /ad_tagis active; the UI and API guard against this combination).
Country-based access restrictions (blacklist/whitelist) via iptables.
Global statistics, active connections history charts, user traffic donut chart breakdown, per-secret detailed stats.
Proxy management, statistics, secret creation, QR codes, and scheduler task monitoring β right from Telegram.
Master-Slave synchronization of settings and secrets between servers over SSH.
Automatic daily backups (database, engine configs, SSH keys) with retention-based rotation. Optional AES-256-GCM encryption. Download and restore via the web interface.
Background task management: enable/disable, change schedules (cron), manual runs, execution history with error details.
Default tasks: traffic-flush, quota-check, expiry-check, health-check, upstream-health, telegram-report, replication-sync, update-check, auto-update, telemt-check, docker-host-check, token-cleanup, daily-backup, backup-cleanup, history-cleanup, quota-reset, auto-rotate.
System action logs with advanced filtering by periods, actions, and usernames.
Consolidated page for system status, resources telemetry, OS info, systemd service management, Docker integration, and update operations:
- Systemd Service: One-click install/remove, restart, and status logs.
- Docker Integration: Docker availability checks, daemon updates, and building/updating the
telemtproxy engine image. Engine updates run asynchronously in the background (with a safety timeout) and β like manual Build/Pull and Force Rebuild β can be cancelled mid-build; a collapsible Build Logs panel streams the per-run build log with a live-activity badge, and the last failed update is shown as a persistent error banner. - Updates: Auto-update scheduler task configurations (with failure Telegram alerts) and manual updates (systemd restart in binary mode, container recreation in Docker mode).
- TCP Network Tuning: One-click enable/disable of TCP BBR congestion control and TCP FastOpen kernel optimizations (sysctl) with automatic backup and rollback to original values.
Global parameters: Docker CPU/memory limits, custom IP, FakeTLS, PROXY protocol, custom Telegram URLs, Ad Tag, Middle-Proxy mode toggle, secret auto-rotation, maintenance mode, backup rotation, debug mode.
The Engine & Health card header shows a pulsing green Live badge when the real-time WebSocket status stream is connected, giving instant visual confirmation of live telemetry.
PopuGate supports native installation as a systemd service β auto-start on boot and automatic restart on crashes. Installation is available via the web interface (System section).
sudo systemctl status popugate
sudo systemctl restart popugate
sudo systemctl stop popugateThe REST API is fully documented via Swagger / OpenAPI 2.0.
- Interactive UI (self-hosted):
http://<your-server>:8090/swagger/index.html - External viewer: Swagger Petstore viewer
All protected endpoints require a Bearer JWT token in the Authorization header (obtained via POST /api/v1/auth/login).
Four endpoints stream data over WebSocket connections (not standard HTTP REST):
| Endpoint | Description |
|---|---|
GET /api/v1/proxy/status/ws |
Real-time proxy status updates (running state, instance list, traffic) |
GET /api/v1/traffic/live/ws |
Live metrics stream (connections, user metrics) |
GET /api/v1/system/resources/ws |
Server resource monitoring (CPU, RAM, disk, load) |
GET /api/v1/engine/update/ws |
Engine update progress streaming |
WebSocket connections also require the Authorization: Bearer <token> header (or ?token= query param for browser clients that cannot set headers).
make tidy # Install dependencies
make build # Build for current OS β bin/popugate
make cross-build # linux/amd64 + linux/arm64Requirements: Go 1.26+, Make.
cd web
pnpm install
pnpm run build # β web/dist/Built files are served via Nginx (see Docker Compose) or another web server that proxies to the backend.
make test # All tests (in-memory SQLite, no Docker required)
make lint # golangci-lint
make fmt # gofmt + goimports
make vulncheck # govulncheck (reachability-aware CVE scan)Tests are isolated and do not require Docker or a network environment.
Code quality is enforced with gocyclo β all functions maintain a cyclomatic complexity of β€ 15.
CI runs two blocking vulnerability scans on every push/PR:
- govulncheck β reachability-aware scan of the Go code (flags an advisory only if the vulnerable symbol is actually reached). Mirrored locally by
make vulncheck. - osv-scanner β version-based scan across all manifests, including the frontend (
web/pnpm-lock.yaml).
Both share osv-scanner.toml as the single source of truth for suppressions: every ignored advisory is listed there with the reason it is not exploitable in PopuGate. To suppress a new finding, add its ID with a rationale; anything not listed fails CI.