Command-line interface for running a Psiphon Conduit node - a volunteer-run proxy that relays traffic for users in censored regions.
Want to run a Conduit station? Get the latest CLI release: https://github.com/Psiphon-Inc/conduit/releases
Our official CLI releases include an embedded psiphon config.
Contact Psiphon (conduit-oss@psiphon.ca) to discuss custom configuration values.
Conduit deployment guide: GUIDE.md
Use the official Docker image, which includes an embedded Psiphon config. Docker Compose is a convenient way to run Conduit if you prefer a declarative setup.
docker compose upThe compose file enables Prometheus metrics on :9090 inside the container. To scrape from the host, publish the port or run Prometheus on the same Docker network and scrape conduit:9090.
# Build with embedded config (recommended)
docker build -t conduit \
--build-arg PSIPHON_CONFIG=psiphon_config.json \
-f Dockerfile.embedded .Important: The Psiphon broker tracks proxy reputation by key. Always use a persistent volume to preserve your key across container restarts, otherwise you'll start with zero reputation and may not receive client connections.
# Using a named volume (recommended)
docker run -d --name conduit \
-v conduit-data:/home/conduit/data \
--restart unless-stopped \
conduit
# Or using a host directory
mkdir -p /path/to/data && chown 1000:1000 /path/to/data
docker run -d --name conduit \
-v /path/to/data:/home/conduit/data \
--restart unless-stopped \
conduitIf you prefer to mount the config at runtime:
docker build -t conduit .
docker run -d --name conduit \
-v conduit-data:/home/conduit/data \
-v /path/to/psiphon_config.json:/config.json:ro \
--restart unless-stopped \
conduit start --psiphon-config /config.json# First time setup (clones required dependencies)
make setup
# Build
make build
# Run
./dist/conduit start --psiphon-config /path/to/psiphon_config.json- Go 1.24.x (Go 1.25+ is not supported due to psiphon-tls compatibility)
- Psiphon network configuration file (JSON)
The Makefile will automatically install Go 1.24.3 if not present.
Conduit requires a Psiphon network configuration file containing connection parameters. See psiphon_config.example.json for the expected format.
Contact Psiphon (conduit-oss@psiphon.ca) to obtain valid configuration values.
# Start with default settings
conduit start
# Customize limits
conduit start --max-clients 500 --bandwidth 10
# Enable Prometheus metrics
conduit start --metrics-addr :9090
# Verbose output (info messages)
conduit start -v
# Debug output (everything)
conduit start --psiphon-config ./psiphon_config.json -vv| Flag | Default | Description |
|---|---|---|
--psiphon-config, -c |
- | Path to Psiphon network configuration file |
--max-clients, -m |
50 | Maximum concurrent clients |
--bandwidth, -b |
40 | Bandwidth limit per peer in Mbps (-1 for unlimited) |
--data-dir, -d |
./data |
Directory for keys and state |
--stats-file, -s |
- | Persist stats to JSON file |
--metrics-addr |
- | Prometheus metrics listen address (e.g., :9090) |
--geo |
false | Enable client geolocation tracking |
-v |
- | Verbose output (use -vv for debug) |
For bandwidth-constrained environments (e.g., VPS with monthly quotas), Conduit supports automatic throttling via a separate supervisor monitor.
To use traffic throttling with Docker, use the limited-bandwidth compose file:
docker compose -f docker-compose.limited-bandwidth.yml up -dEdit docker-compose.limited-bandwidth.yml to set your limits:
command:
[
"--traffic-limit", "500", # Total quota in GB
"--traffic-period", "30", # Time period in days
"--bandwidth-threshold", "80", # Throttle at 80% usage
"--min-connections", "10", # Reduced capacity when throttled
"--min-bandwidth", "10", # Reduced bandwidth when throttled
"--", # Separator
"start", # Conduit command
... # Conduit flags
]The supervisor monitors bandwidth usage and:
- Runs Conduit at full capacity initially.
- When the threshold is reached (e.g., 400GB of 500GB), it restarts Conduit with reduced capacity.
- When the period ends, it resets usage and restarts Conduit at full capacity.
- Ensures minimum limits (100GB/7days) to protect reputation.
Track where your clients are connecting from:
conduit start --geo --stats-file stats.json --psiphon-config ./psiphon_config.jsonOn first run, the GeoLite2 database (~6MB) is automatically downloaded. Stats are updated in real-time as clients connect and disconnect.
Example stats.json:
{
"connectingClients": 5,
"connectedClients": 12,
"totalBytesUp": 1234567,
"totalBytesDown": 9876543,
"uptimeSeconds": 3600,
"isLive": true,
"geo": [
{
"code": "IR",
"country": "Iran",
"count": 3,
"count_total": 47,
"bytes_up": 524288000,
"bytes_down": 2684354560
},
{
"code": "CN",
"country": "China",
"count": 1,
"count_total": 23,
"bytes_up": 314572800,
"bytes_down": 1610612736
},
{
"code": "RELAY",
"country": "Unknown (TURN Relay)",
"count": 1,
"count_total": 8,
"bytes_up": 52428800,
"bytes_down": 268435456
}
],
"timestamp": "2026-01-25T15:44:00Z"
}| Field | Description |
|---|---|
count |
Currently connected clients |
count_total |
Total unique clients since start |
bytes_up |
Total bytes uploaded since start |
bytes_down |
Total bytes downloaded since start |
Notes:
-
Connections through TURN relay servers appear as
RELAYsince the actual client country cannot be determined. -
The
connectedClientsfield is reported by the Psiphon broker and may differ slightly from the sum of geocountvalues, which are tracked locally via WebRTC callbacks. -
Bandwidth (
bytes_up/bytes_down) is attributed to a country when the connection closes. Active connections contribute tototalBytesUp/totalBytesDownbut won't appear in geo stats until they disconnect. -
traffic_state.json- Traffic usage tracking (when throttling is enabled) Tracks current period start time, bytes used, and throttle state. Persists across restarts.
# Build for current platform
make build
make build-monitor
# Build with embedded config (single-binary distribution)
make build-embedded PSIPHON_CONFIG=./psiphon_config.json
# Build for all platforms
make build-all
# Individual platform builds
make build-linux # Linux amd64
make build-linux-arm # Linux arm64
make build-darwin # macOS Intel
make build-darwin-arm # macOS Apple Silicon
make build-windows # Windows amd64Binaries are output to dist/.
Keys and state are stored in the data directory (default: ./data):
conduit_key.json- Node identity keypair The Psiphon broker tracks proxy reputation by key. Always use a persistent volume to preserve your key across container restarts, otherwise you'll start with zero reputation and may not receive client connections for some time.
GNU General Public License v3.0