Operations
This page covers running p2proxy as a long-lived service.
systemd
A minimal unit file:
# /etc/systemd/system/p2proxy.service
[Unit]
Description=Bitping p2proxy
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
Environment=BITPING_API_KEY=<your-key>
ExecStart=/usr/local/bin/p2proxy --no-ui --config /etc/p2proxy/Config.yaml
Restart=on-failure
RestartSec=5
DynamicUser=yes
StateDirectory=p2proxy
[Install]
WantedBy=multi-user.target
Enable and start:
sudo systemctl daemon-reload
sudo systemctl enable --now p2proxy
journalctl -u p2proxy -f
DynamicUser=yes runs the daemon as a transient unprivileged user. StateDirectory=p2proxy gives it /var/lib/p2proxy for the libp2p keypair.
If you need to bind a SOCKS5 listener below port 1024, either pick a high port (recommended) or grant the binary the capability:
sudo setcap 'cap_net_bind_service=+ep' "$(which p2proxy)"
Docker
The official image is ghcr.io/bitpingapp/p2proxy:latest. NO_UI=true is set by default so the daemon doesn’t try to draw a TUI without a TTY.
docker run -d --name p2proxy \
-p 1080:1080 \
-p 9091:9091 \
-e BITPING_API_KEY=<your-key> \
-v "$PWD/Config.yaml:/app/Config.yaml:ro" \
ghcr.io/bitpingapp/p2proxy:latest
You need to expose:
- Every per-server SOCKS5 port (
-p 1080:1080, etc.) so clients on the host or network can reach it. - The metrics port (
-p 9091:9091) if you want to scrape Prometheus metrics from outside the container. - If you pin a fixed libp2p port via
listen_addrs, publish that port too — not strictly required, but it improves direct-vs-relay connectivity.
docker-compose
A reference docker-compose.yml ships in the repo. Typical shape:
services:
p2proxy:
image: ghcr.io/bitpingapp/p2proxy:latest
restart: unless-stopped
environment:
BITPING_API_KEY: $BITPING_API_KEY
ports:
- "1080:1080"
- "9091:9091" # metrics
volumes:
- ./Config.yaml:/app/Config.yaml:ro
p2proxy picks its own libp2p listen ports by default, so there’s nothing fixed to publish. If you set
listen_addrsto a fixed port, publish that port too (it improves direct-vs-relay connectivity).
Prometheus metrics
p2proxy exposes Prometheus metrics on http://localhost:9091/metrics by default (set metrics_port to change it). Useful series:
| Series | Type | Notes |
|---|---|---|
p2proxy_peers_connected |
gauge | Connected libp2p peers. |
p2proxy_sessions_active |
gauge | In-flight SOCKS5 sessions. |
p2proxy_socks_connections_total, p2proxy_sessions_initialized_total |
counter | Accepted / fully-established sessions. |
p2proxy_upload_bytes_total, p2proxy_download_bytes_total |
counter | Bytes relayed each direction. |
p2proxy_session_errors_total{stage} |
counter | Session failures by stage (handshake / request / peer-connection / data-transfer). |
p2proxy_stream_opened_total, p2proxy_stream_acquire_failed_total |
counter | Peer-stream opens / failures. |
p2proxy_ping_rtt_seconds |
histogram | Peer round-trip latency. |
p2proxy_socks_rejected_no_peer_total |
counter | Sessions rejected — no exit peer available. |
A minimal scrape config:
scrape_configs:
- job_name: p2proxy
static_configs:
- targets: ["localhost:9091"]
For dashboards, p2proxy_session_errors_total{stage} is the series you’ll watch most — a rising rate is the leading indicator of peer trouble.
Upgrading
- Homebrew:
brew upgrade --cask BitpingApp/tap/p2proxy - Debian/Ubuntu/RHEL/Alpine: download the new package from the releases page and reinstall.
- Docker: pull the new tag and recreate the container —
docker compose pull && docker compose up -d. - From source:
git pull && cargo build --release -p p2proxy.
Restart the daemon to pick up the new binary. Config.yaml is read at startup, so config changes also require a restart.
Keypair / peer identity
p2proxy persists its libp2p keypair to node_keypair.bin in the working directory by default (override with keypair_path). Under systemd with StateDirectory=p2proxy, run the daemon from /var/lib/p2proxy or point keypair_path there. Deleting this file changes your peer ID; the daemon regenerates one on next start. You usually don’t need to touch this.
Next
- Troubleshooting — symptom-driven matrix.
- Support — bug reports, security, billing.