Skip to main content

Config priority

Settings are resolved in this order (highest wins):
PrioritySource
1CLI flags (--port, --log-level, etc.)
2server: block in the YAML config file
3PROXY_HOPPER_* environment variables
4Built-in defaults

File structure

proxyProviders:   # optional — named proxy suppliers with credentials and region tags
  - ...

ipPools:          # optional — named pools that draw IPs from providers
  - ...

targets:          # required — URL-matching routing rules
  - ...

auth:             # optional — authentication for proxy access
  ...

server:           # optional — all fields have defaults
  ...

Duration values

All duration fields accept a suffix (1s, 5m, 2h) or a bare integer (seconds):
minRequestInterval: 1s    # one second
maxQueueWait: 30s         # thirty seconds
quarantineTime: 2m        # two minutes

proxyProviders

Named groups of external proxy IPs with shared authentication and an optional region tag. Defining providers is optional — targets can also list IPs inline via ipList.
FieldTypeDefaultDescription
namestringrequiredUnique identifier referenced from ipPools.ipRequests
authblockOmit for open or IP-whitelisted proxies
auth.typestringbasicAuth type — currently basic
auth.usernamestringrequired if auth setUsername for HTTP Basic auth
auth.passwordstring""Password for HTTP Basic auth
ipListlistrequiredProxy addresses — host:port or bare host
regionTagstringRegion label attached to Prometheus metrics
proxyProviders:
  - name: provider-us
    auth:
      type: basic
      username: user
      password: secret
    ipList:
      - "10.0.0.1:3128"
      - "10.0.0.2:3128"
    regionTag: US-East

  - name: provider-open           # no auth — IP whitelisted
    ipList:
      - "10.1.0.1:3128"
    regionTag: EU-West

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 definition while maintaining independent rotation state. Defining pools is optional — targets can also list IPs inline.
ipPools:
  - name: pool-name
    ipRequests:              # draw IPs from providers (randomly sampled at startup)
      - provider: name
        count: 5
    ipList:                  # or list IPs inline (can be combined with ipRequests)
      - "host:port"

ipRequests fields

FieldTypeDescription
providerstringName of a proxyProviders entry
countintNumber of IPs to randomly sample from that provider’s list
ipPools:
  - name: global-pool
    ipRequests:
      - provider: provider-us
        count: 5
      - provider: provider-au
        count: 5
Inline IPs in ipPools.ipList have no provider metadata — they won’t appear with provider or region labels in Prometheus metrics.

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.
FieldTypeDefaultDescription
namestringrequiredLabel used in logs and metrics
regexstringrequiredPython regex matched against the full destination URL
ipPoolstringrequired*Name of a shared ipPools entry
ipListlistrequired*Inline proxy addresses — host:port or bare host
defaultProxyPortint8080Port applied to bare IPs in ipList
minRequestIntervalduration1sHow long an IP is held off the pool after any request
maxQueueWaitduration30sHow long a request waits for a free IP before failing with 503
numRetriesint3Retry attempts on failure, each using a different IP
ipFailuresUntilQuarantineint5Consecutive failures before an IP is quarantined
quarantineTimeduration120sHow long a quarantined IP sits out before returning
identityblockPer-(IP, target) client identity — see below
* Exactly one of ipPool or ipList must be provided per target.
targets:
  - name: google-apis
    regex: '\.googleapis\.com'
    ipPool: us-pool
    minRequestInterval: 5s
    maxQueueWait: 30s
    numRetries: 3
    ipFailuresUntilQuarantine: 5
    quarantineTime: 10m

  - name: general
    regex: '.*'
    ipPool: us-pool
    minRequestInterval: 1s
    maxQueueWait: 30s
    numRetries: 3
    ipFailuresUntilQuarantine: 5
    quarantineTime: 2m

identity

Attaches a persistent browser persona to each (IP, target) pair. Disabled by default — add the identity: block to enable.
FieldTypeDefaultDescription
enabledboolfalseMaster switch
cookiesbooltruePersist and replay session cookies per IP
profilestringrandomFixed fingerprint profile name. Omit to pick a random profile per identity. Valid values: chrome-windows, chrome-macos, safari-macos, firefox-windows, firefox-linux
rotateAfterRequestsintVoluntarily rotate the identity after this many successful requests. Omit to disable
rotateOn429booltrueRotate identity immediately on a 429 response
warmupblockWarmup request sent through a fresh identity before it enters service
warmup.enabledbooltrueEnable the warmup request
warmup.pathstring/URL path for the warmup GET request
identity:
  enabled: true
  cookies: true
  # profile: chrome-windows   # omit for random per identity
  rotateAfterRequests: 100
  rotateOn429: true
  warmup:
    enabled: true
    path: /
See Client Identities for the full concept guide.

auth

Authentication is disabled by default. When enabled, every proxy request must include an X-Proxy-Hopper-Auth: Bearer <token> header. See the Authentication section for full configuration guides.
FieldTypeDefaultDescription
enabledboolfalseEnable authentication
jwtSecretstringauto-generatedSecret for signing/verifying locally-issued JWTs. Set explicitly so tokens survive restarts.
jwtExpiryMinutesint60JWT lifetime in minutes
apiKeyslistService-to-service API keys
apiKeys[].namestringrequiredIdentifier used in logs and error messages
apiKeys[].keystringrequiredThe secret key string
apiKeys[].targetslist["*"]Target names this key can access. ["*"] = all targets.
adminblockLocal admin user for the admin API
admin.usernamestringrequired if setAdmin username
admin.passwordHashstringrequired if setBcrypt hash — generate with proxy-hopper hash-password
rolesmapCustom roles for JWT/OIDC users (see User-based auth)
oidcblockOIDC/SSO configuration (see SSO)
auth:
  enabled: true
  jwtSecret: "change-me-to-a-long-random-string"
  jwtExpiryMinutes: 60

  apiKeys:
    - name: my-service
      key: "ph_changeme"
      targets: ["*"]          # allow all targets

    - name: reporting-service
      key: "ph_reporting_key"
      targets: ["analytics"]  # restrict to one target

  admin:
    username: admin
    passwordHash: "$2b$12$..."  # proxy-hopper hash-password <password>

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 varDefaultDescription
hostPROXY_HOPPER_HOST0.0.0.0Bind address
portPROXY_HOPPER_PORT8080Proxy server port
adminPortPROXY_HOPPER_ADMIN_PORT8081Admin API port (when admin is enabled)
logLevelPROXY_HOPPER_LOG_LEVELINFOTRACE | DEBUG | INFO | WARNING | ERROR
logFormatPROXY_HOPPER_LOG_FORMATtexttext | json
logFilePROXY_HOPPER_LOG_FILEstderrPath to log file
backendPROXY_HOPPER_BACKENDmemorymemory | redis
redisUrlPROXY_HOPPER_REDIS_URLredis://localhost:6379/0Redis connection URL
metricsPROXY_HOPPER_METRICSfalseEnable Prometheus /metrics endpoint
metricsPortPROXY_HOPPER_METRICS_PORT9090Metrics server port
probePROXY_HOPPER_PROBEtrueEnable background IP health prober
probeIntervalPROXY_HOPPER_PROBE_INTERVAL60Seconds between probe rounds
probeTimeoutPROXY_HOPPER_PROBE_TIMEOUT10Per-probe HTTP timeout (seconds)
probeUrlsPROXY_HOPPER_PROBE_URLSCloudflare + GoogleEndpoints probed through each IP. Comma-separated as env var.
server:
  host: 0.0.0.0
  port: 8080
  logLevel: INFO
  logFormat: json
  backend: memory
  redisUrl: redis://localhost:6379/0
  metrics: true
  metricsPort: 9090

CLI flags

CLI flags override all other sources and cover the most operationally useful overrides:
proxy-hopper run --config config.yaml [OPTIONS]

  --config / -c PATH       Path to YAML config file  [required]
  --host TEXT              Bind address
  --port INT               Proxy server port
  --log-level CHOICE       TRACE|DEBUG|INFO|WARNING|ERROR
  --log-format CHOICE      text|json
  --log-file PATH          Write logs to file instead of stderr
  --metrics / --no-metrics Enable Prometheus /metrics
  --metrics-port INT       Metrics server port
  --backend CHOICE         memory|redis
  --redis-url TEXT         Redis connection URL
  --probe / --no-probe     Enable background IP health prober
  --probe-interval FLOAT   Seconds between probe rounds
  --probe-timeout FLOAT    Per-probe HTTP timeout
  --probe-urls TEXT        Comma-separated probe endpoints

proxy-hopper validate --config config.yaml
  Validates the config file and prints a summary without starting the server.

proxy-hopper hash-password <password>
  Generates a bcrypt hash suitable for auth.admin.passwordHash.