All-in-one FRP/NPS tunnel control panel with one Docker container and unified users.
1.1K
Source repository: https://github.com/qwernot/tunnel-control
Docker image: darkver8/tunnel-control:latest
Tunnel Control is an all-in-one tunnel control panel that embeds FRP server and NPS server-side capabilities into a single tunnel-control process and a single Docker container.
The goal is to keep only one control panel:
docker pull darkver8/tunnel-control:latest
The container runs one main process:
tunnel-control
This process starts:
Linux servers should use host networking because FRP/NPS need to listen on dynamic user ports.
mkdir -p tunnel-control
cd tunnel-control
cat > compose.yml <<'EOF'
services:
tunnel-stack:
image: darkver8/tunnel-control:latest
container_name: tunnel-stack
restart: unless-stopped
network_mode: host
environment:
PUBLIC_ADDR: your-server-ip-or-domain
ADMIN_USER: admin
ADMIN_PASSWORD: change-this-password
FRP_BIND_PORT: 17000
FRP_HTTP_PORT: 9081
FRP_HTTPS_PORT: 9444
NPS_BRIDGE_PORT: 18024
NPS_TLS_BRIDGE_PORT: 18025
NPS_HTTP_PORT: 9080
NPS_HTTPS_PORT: 9443
USER_PORT_RANGE: 10000-20000
volumes:
- ./data:/app/data
EOF
docker compose up -d
Open the panel:
http://your-server-ip:8088
On first start, if there is no enabled admin user, the container creates one from ADMIN_USER and ADMIN_PASSWORD.
8088/tcp Web control panel
17000/tcp FRP client access port
18024/tcp NPS bridge
18025/tcp NPS TLS bridge
9080/tcp NPS HTTP proxy
9443/tcp NPS HTTPS proxy
9081/tcp FRP HTTP vhost
9444/tcp FRP HTTPS vhost
10000-20000/tcp User TCP/SOCKS5 tunnel port range
10000-20000/udp User UDP tunnel port range
FRP dashboard and NPS dashboard are disabled by default:
FRP_DASHBOARD_PORT=0
NPS_WEB_PORT=0
frpc.toml and npc command per userTCP, UDP, and SOCKS5 use port pools:
HTTP and HTTPS use domain pools:
app.example.com*.example.comfrpc.tomlHTTP entry ports are separate for FRP and NPS:
NPS HTTP: http://domain:9080
NPS HTTPS: https://domain:9443
FRP HTTP: http://domain:9081
FRP HTTPS: https://domain:9444
In production, map 80/443 to these ports with firewall rules, port forwarding, or a reverse proxy.
Persistent data is stored under /app/data; mount it to the host:
data/
control/tunnel-control.json
frp/frps-users.json
nps/conf/
export/
Back up the data directory to preserve users, tunnels, and engine config.
docker compose ps
docker compose logs -f tunnel-stack
docker compose restart tunnel-stack
docker compose down
Health check:
curl http://127.0.0.1:8088/healthz
go test ./...
go build -o tunnel-control ./cmd/tunnel-control
docker build -t darkver8/tunnel-control:latest .
Content type
Image
Digest
sha256:49d13a081…
Size
13.2 MB
Last updated
4 months ago
docker pull darkver8/tunnel-control