Config priority
Settings are resolved in this order (highest wins):| Priority | Source |
|---|---|
| 1 | CLI flags (--port, --log-level, etc.) |
| 2 | server: block in the YAML config file |
| 3 | PROXY_HOPPER_* environment variables |
| 4 | Built-in defaults |
File structure
Duration values
All duration fields accept a suffix (1s, 5m, 2h) or a bare integer (seconds):
proxyProviders
Named groups of external proxy IPs with shared authentication and an optional region tag. At least one provider is required — IPs are declared here and referenced by pools.| Field | Type | Default | Description |
|---|---|---|---|
name | string | required | Unique identifier referenced from ipPools.ipRequests |
auth | block | — | Omit for open or IP-whitelisted proxies |
auth.type | string | basic | Auth type — currently basic |
auth.username | string | required if auth set | Username for HTTP Basic auth |
auth.password | string | "" | Password for HTTP Basic auth |
ipList | list | required | Proxy addresses — host:port or bare host |
regionTag | string | — | Region label attached to Prometheus metrics |
mutable | bool | true | When false, the provider cannot be updated or removed via the admin API |
static | bool | true | When true (default for YAML-defined providers), the provider is always overwritten from config on startup. Set false to allow API mutations while still seeding on first run |
ipPools
Named collections of proxy IPs referenced by targets. Pools decouple the IP list from the target config — multiple targets can reference the same pool while maintaining independent rotation state.ipPools fields
| Field | Type | Default | Description |
|---|---|---|---|
name | string | required | Unique identifier referenced from targets[].ipPool |
ipRequests | list | required | One or more provider draws — see below |
mutable | bool | true | When false, the pool cannot be updated or removed via the admin API |
static | bool | true | When true (default for YAML-defined pools), the pool is always overwritten from config on startup |
ipRequests fields
| Field | Type | Description |
|---|---|---|
provider | string | Name of a proxyProviders entry |
count | int | Number of IPs to take from that provider’s list (first N; graceful if provider has fewer) |
ipRequests entries combine IPs from different providers into one pool:
targets
The core routing config. Each inbound request is matched against the target list top-to-bottom — the first regex match handles the request. At least one target is required.| Field | Type | Default | Description |
|---|---|---|---|
name | string | required | Label used in logs and metrics |
regex | string | required | Python regex matched against the full destination URL |
ipPool | string | required | Name of a shared ipPools entry |
minRequestInterval | duration | 1s | How long an IP is held off the pool after any request |
maxQueueWait | duration | 30s | How long a request waits for a free IP before failing with 503 |
numRetries | int | 3 | Retry attempts on failure, each using a different IP |
ipFailuresUntilQuarantine | int | 5 | Consecutive failures before an IP is quarantined |
quarantineTime | duration | 120s | How long a quarantined IP sits out before returning |
defaultProxyPort | int | 8080 | Port used when a pool IP has no explicit port |
spoofUserAgent | bool | true | Replace the User-Agent header with a random browser UA. Override per-request with X-Proxy-Hopper-User-Agent |
mutable | bool | true | Whether this target can be updated or removed via the admin API |
static | bool | true | When true (default for YAML-defined targets), the target is always overwritten from config on startup |
identity | block | — | Per-(IP, target) client identity — see below |
identity
Attaches a persistent browser persona to each (IP, target) pair. Disabled by default — add theidentity: block to enable.
| Field | Type | Default | Description |
|---|---|---|---|
enabled | bool | false | Master switch |
cookies | bool | true | Persist and replay session cookies per IP |
rotateAfterRequests | int | — | Voluntarily rotate the identity after this many successful requests. Omit to disable |
rotateOn429 | bool | true | Rotate identity immediately on a 429 response |
warmup | block | — | Warmup request sent through a fresh identity before it enters service |
warmup.enabled | bool | true | Enable the warmup request |
warmup.path | string | / | URL path for the warmup GET request |
auth
Authentication is disabled by default. When enabled, every proxy request must include anX-Proxy-Hopper-Auth: Bearer <token> header.
See the Authentication section for full configuration guides.
| Field | Type | Default | Description |
|---|---|---|---|
enabled | bool | false | Enable authentication |
jwtSecret | string | auto-generated | Secret for signing/verifying locally-issued JWTs. Set explicitly so tokens survive restarts. |
jwtExpiryMinutes | int | 60 | JWT lifetime in minutes |
apiKeys | list | — | Service-to-service API keys |
apiKeys[].name | string | required | Identifier used in logs and error messages |
apiKeys[].key | string | required | The secret key string |
apiKeys[].targets | list | ["*"] | Target names this key can access. ["*"] = all targets. |
admin | block | — | Local admin user for the admin API |
admin.username | string | required if set | Admin username |
admin.passwordHash | string | required if set | Bcrypt hash — generate with proxy-hopper hash-password |
roles | map | — | Custom roles for JWT/OIDC users (see User-based auth) |
oidc | block | — | OIDC/SSO configuration (see SSO) |
server
All server fields can be set in three places — see Config priority. See Environment Variables for the full env var reference.| Field (YAML) | Env var | Default | Description |
|---|---|---|---|
host | PROXY_HOPPER_HOST | 0.0.0.0 | Bind address |
port | PROXY_HOPPER_PORT | 8080 | Proxy server port |
admin | PROXY_HOPPER_ADMIN | false | Enable the admin server (GraphQL API + REST endpoints) |
adminPort | PROXY_HOPPER_ADMIN_PORT | 8081 | Admin server port |
adminHost | PROXY_HOPPER_ADMIN_HOST | 0.0.0.0 | Admin server bind address |
logLevel | PROXY_HOPPER_LOG_LEVEL | INFO | TRACE | DEBUG | INFO | WARNING | ERROR |
logFormat | PROXY_HOPPER_LOG_FORMAT | text | text | json |
logFile | PROXY_HOPPER_LOG_FILE | stderr | Path to log file |
backend | PROXY_HOPPER_BACKEND | memory | memory | redis |
redisUrl | PROXY_HOPPER_REDIS_URL | redis://localhost:6379/0 | Redis connection URL |
proxyReadTimeout | PROXY_HOPPER_PROXY_READ_TIMEOUT | — | Timeout in seconds for reading the upstream response body. Omit to use aiohttp’s default |
metrics | PROXY_HOPPER_METRICS | false | Enable Prometheus /metrics endpoint |
metricsPort | PROXY_HOPPER_METRICS_PORT | 9090 | Metrics server port |
probe | PROXY_HOPPER_PROBE | true | Enable background IP health prober |
probeInterval | PROXY_HOPPER_PROBE_INTERVAL | 60 | Seconds between probe rounds |
probeTimeout | PROXY_HOPPER_PROBE_TIMEOUT | 10 | Per-probe HTTP timeout (seconds) |
probeUrls | PROXY_HOPPER_PROBE_URLS | Cloudflare + Google | Endpoints probed through each IP. Comma-separated as env var. |
debugQuarantine | PROXY_HOPPER_DEBUG_QUARANTINE | false | Log quarantine and cooldown events at DEBUG level |
debugProbes | PROXY_HOPPER_DEBUG_PROBES | false | Log probe results at DEBUG level |
debugBackend | PROXY_HOPPER_DEBUG_BACKEND | false | Log backend storage operations at DEBUG level |