Configure Pangolin using the config.yml file with detailed settings for all components
The config.yml file controls all aspects of your Pangolin deployment, including server settings, domain configuration, email setup, and security options. This file is mounted at config/config.yml in your Docker container.
To get started, create a basic configuration file with the essential settings:
Minimal Pangolin configuration:
config.yml
gerbil: start_port: 51820 base_endpoint: "pangolin.example.com" # REPLACE WITH YOUR DOMAIN # Optional network settings (defaults shown): # subnet_group: "100.89.137.0/20" # block_size: 24 # site_block_size: 30app: dashboard_url: "https://pangolin.example.com" # REPLACE WITH YOUR DOMAIN log_level: "info" telemetry: anonymous_usage: truedomains: domain1: base_domain: "example.com" # REPLACE WITH YOUR DOMAIN cert_resolver: "letsencrypt"server: secret: "your-strong-secret" # REPLACE cors: origins: ["https://pangolin.example.com"] # REPLACE WITH YOUR DOMAIN methods: ["GET", "POST", "PUT", "DELETE", "PATCH"] allowed_headers: ["X-CSRF-Token", "Content-Type"] credentials: falseflags: require_email_verification: false disable_signup_without_invite: true disable_user_create_org: false allow_raw_resources: true
Generate a strong secret for server.secret. Use at least 32 characters with a mix of letters, numbers, and special characters.
If you need to CHANGE the server secret after the server has been started you must use the pangctl rotate-server-secret command to re-encrypt sensitive data. Follow docs here.
Server ports, networking, and authentication settings.
Show ServerHide Server
external_portinteger
The port for the front-end API that handles external requests.
Example: 3000
internal_portinteger
The port for the internal private-facing API.
Example: 3001
next_portinteger
The port for the frontend server (Next.js).
Example: 3002
integration_portinteger
The port for the integration API (optional).
Example: 3003
ai_gateway_portinteger
The port for the AI Gateway service.
Example: 3005
Default: 3005
internal_hostnamestring
The hostname of the Pangolin container for internal communication.
Example: pangolin
If using Docker Compose, this should match your container name.
session_cookie_namestring
The name of the session cookie for storing authentication tokens.
Example: p_session_token
Default: p_session_token
resource_access_token_paramstring
Query parameter name for passing access tokens in requests.
Example: p_token
Default: p_token
resource_access_token_headersobject
HTTP headers for passing access tokens in requests.
Show HeadersHide Headers
idstring
Header name for access token ID.
Example: P-Access-Token-Id
tokenstring
Header name for access token.
Example: P-Access-Token
remote_headersobject
Names of the HTTP headers Badger injects into proxied requests to identify an authenticated user or virtual API key. Also used by the AI Gateway to attach the identified user to a request once it has passed Badger's session/key verification.
Show Remote HeadersHide Remote Headers
user_idstring
Header name for the authenticated user's ID.
Default: Remote-User-Id
virtual_api_key_idstring
Header name for the virtual API key ID.
Default: Remote-Virtual-Api-Key-Id
userstring
Header name for the authenticated username.
Default: Remote-User
emailstring
Header name for the authenticated user's email.
Default: Remote-Email
namestring
Header name for the authenticated user's display name.
Number of proxy headers to trust for client IP detection.
Example: 1
Default: 1
Use 1 if running behind a single reverse proxy like Traefik.
trust_ipsarray of strings
IP ranges, in CIDR format, of the upstream proxies or load balancers that Badger trusts to supply the real client IP.
Example: ["10.0.0.0/8", "172.16.0.0/12"]
Default: []
By default Badger trusts Cloudflare's IP ranges and reads the client IP from the CF-Connecting-IP header. Setting one or more ranges here replaces the Cloudflare ranges, so only the ranges you list are trusted. Use this when a proxy other than Cloudflare sits in front of Pangolin.
Only list addresses of proxies you control. Any request arriving from a trusted range can set the client IP that Pangolin uses for rules and logging.
custom_ip_headerstring
Name of the HTTP header Badger reads the real client IP from when a request arrives from a trusted IP range.
Example: X-Real-Ip
Default: "" (uses CF-Connecting-IP)
The header is only honored for requests from a trusted source: the ranges in trust_ips, or Cloudflare's ranges when trust_ips is empty. The header value is used as-is, so choose a header your proxy sets to a single IP address. If the header is missing, Badger falls back to CF-Connecting-IP and then to the connection's remote address.
Whether to have Badger stamp the resolved client IP into a dedicated X-Pangolin-Client-Ip header on the site-resource AI Gateway route.
Default: false
Environment Variable: ENABLE_AI_GATEWAY_CLIENT_IP_HEADER (or ENABLE_AI_GATEWAY_CLIENT_IP_HEADER_FILE to read the value from a file — see Reading secrets from a file)
Useful when an intermediary proxy sits between Traefik and the AI Gateway and overwrites X-Forwarded-For/X-Real-Ip instead of appending to them. Requires a Badger version that supports realIpHeader.
dashboard_session_length_hoursinteger
Dashboard session duration in hours.
Example: 720 (30 days)
Default: 720
resource_session_length_hoursinteger
Resource session duration in hours.
Example: 720 (30 days)
Default: 720
secretstringrequired
Secret key for encrypting sensitive data.
Environment Variable: SERVER_SECRET (or SERVER_SECRET_FILE to read the value from a file — see Reading secrets from a file)
Generate a strong, random secret. This is used for encrypting sensitive data and should be kept secure.
If you need to CHANGE the server secret after the server has been started you must use the pangctl rotate-server-secret command to re-encrypt sensitive data. Follow docs here.
maxmind_db_pathstring
Path to the MaxMind GeoIP database file for geolocation features.
Example: ./config/GeoLite2-Country.mmdb
Used for IP geolocation functionality. Requires a MaxMind GeoLite2 or GeoIP2 database file.
maxmind_asn_pathstring
Path to the MaxMind ASN database file for ASN lookups.
Example: ./config/GeoLite2-ASN.mmdb
Sibling setting to maxmind_db_path. Used to resolve the ASN for an IP address.
Gerbil tunnel controller settings for WireGuard tunneling.
Show GerbilHide Gerbil
base_endpointstringrequired
Domain name included in WireGuard configuration for tunnel connections.
Example: pangolin.example.com
exit_node_namestring
Name of the exit node record that identifies this server's own Gerbil exit node.
Used to look up (or create, if missing) this instance's exit node in the database. Useful when running multiple exit nodes so this server can find its own.
start_portinteger
Starting port for WireGuard tunnels. When changing, a full stack restart including sites and clients is required.
Example: 51820
clients_start_portinteger
Starting port for client WireGuard relay and hole punch port. When changing, a full stack restart including sites and clients is required.
Example: 21820
subnet_groupstring
IP address CIDR range for Gerbil exit node subnets.
Default: 100.89.137.0/20
The default uses the CGNAT range to avoid conflicts with typical private networks.
If you change this on an existing install you will need to delete the exit node to refresh it in the database which is best practice. Use the pangctl command to clear the exit nodes.
block_sizeinteger
Block size for Gerbil exit node CIDR ranges.
Default: 24
A /24 block provides 256 IP addresses for the Gerbil network.
If you change this on an existing install you will need to delete the exit node to refresh it in the database which is best practice. Use the pangctl command to clear the exit nodes.
site_block_sizeinteger
Block size for site CIDR ranges connected to Gerbil.
Default: 30
A /30 block provides 4 IP addresses per site. Consider using /29 (8 IPs) or /28 (16 IPs) for sites with heavy WireGuard usage.
If you change this on an existing install you will need to delete the exit node to refresh it in the database which is best practice. Use the pangctl command to clear the exit nodes.
Whether to require email verification for new users.
Default: false
Only enable this if you have email configuration set up.
enable_acme_cert_syncbooleandefault: true
Enable automatic synchronization of ACME certificates for TLS termination on private resources.
flags: enable_acme_cert_sync: true
disable_signup_without_inviteboolean
Whether to disable public user registration.
Default: false
Users can still sign up with valid invites when enabled.
disable_user_create_orgboolean
Whether to prevent users from creating organizations.
Default: false
Server admins can always create organizations.
allow_raw_resourcesboolean
Whether to allow raw TCP/UDP resource creation.
Default: true
If set to false, users will only be able to create http/https resources.
enable_integration_apiboolean
Whether to enable the integration API.
Default: false
disable_local_sitesboolean
Whether to disable local site creation and management.
Default: false
When enabled, users cannot create sites that connect to local networks.
disable_basic_wireguard_sitesboolean
Whether to disable basic WireGuard site functionality.
Default: false
When enabled, only advanced WireGuard configurations are allowed.
disable_product_help_bannersboolean
Whether to disable product help banners in the UI at the top of screens.
Default: false
disable_config_managed_domainsboolean
Whether to disable domains managed through the configuration file.
Default: false
When enabled, only domains created through the UI are allowed.
disable_enterprise_featuresboolean
Whether to disable features that are only available in the Enterprise Edition from showing in the UI.
Default: false
When enabled, Enterprise-only features are hidden from the UI.
disable_private_http_placeholderboolean
When set to true Pangolin will not generate publicly facing placeholder pages for private HTTP resources. This can impact the ability for Pangolin to generate nessicary certificates.
Default: false
disable_virtual_api_keys_uiboolean
Whether to hide the virtual API keys UI.
Default: false
When enabled, virtual API key management is hidden from the dashboard.
Read-only replica database configurations for load balancing.
Environment Variable: POSTGRES_REPLICA_CONNECTION_STRINGS, a comma-separated list of connection strings (or POSTGRES_REPLICA_CONNECTION_STRINGS_FILE to read the same comma-separated list from a file — see Reading secrets from a file)
Show Replica ConfigurationHide Replica Configuration
Maximum number of connections to the primary database.
Default: 20
Example: 50
max_replica_connectionsinteger
Maximum number of connections to replica databases.
Default: 10
Example: 25
idle_timeout_msinteger
Time in milliseconds before idle connections are closed.
Default: 30000 (30 seconds)
Example: 60000
connection_timeout_msinteger
Time in milliseconds to wait for a database connection.
Default: 5000 (5 seconds)
Example: 10000
jit_modeboolean
Whether to allow Postgres query JIT compilation on pooled connections.
Default: true
Set to false when connecting through a pooler (e.g. PgBouncer) that rejects the JIT startup option. When disabled, SET jit = off is run on each new connection.
Configuration for an optional, separate PostgreSQL database dedicated to logs, kept apart from the main application database.
Show PostgreSQL LogsHide PostgreSQL Logs
connection_stringstring
Connection string for the dedicated logs database.
Environment Variable: POSTGRES_LOGS_CONNECTION_STRING (or POSTGRES_LOGS_CONNECTION_STRING_FILE to read the value from a file — see Reading secrets from a file)
If not set, logging falls back to the main postgres database.
replicasarray of objects
Read-only replica configurations for the logs database.
Environment Variable: POSTGRES_LOGS_REPLICA_CONNECTION_STRINGS, a comma-separated list of connection strings (or POSTGRES_LOGS_REPLICA_CONNECTION_STRINGS_FILE to read the same comma-separated list from a file — see Reading secrets from a file)
Show Replica ConfigurationHide Replica Configuration
connection_stringstringrequired
Connection string for the read replica logs database.
The ACME config for syncing the certs used to be in the private config file but has moved to the public config file here. Please update config accordingly.
acmeobject
Configuration for ACME certificate synchronization. Used in conjunction with flags.enable_acme_cert_sync to synchronize TLS certificates issued by Traefik (or another ACME client) into Pangolin for use on private resources.
Path to the acme.json file or a directory containing more than one acme json file produced by Traefik (or another ACME client). Pangolin reads this file to extract certificates for synchronization and will look for all files in the specified directory if a directory is provided. The file must be in the format produced by Traefik's ACME integration. This file is typically mounted as a volume from your ACME client container.
The catalog feeds Known Models pickers, wildcard discovery, provider selection, and usage pricing. See Model Catalog for the JSON format, catalog providers, and how budgets use pricing.
aiobject
AI Gateway catalog settings. Omit this block to use the defaults.
Show AIHide AI
model_catalogobject
Where Pangolin loads the model catalog from, and how often it refreshes.
Path to a local catalog JSON file. When set, this file is the base catalog instead of upstream_url.
ai: model_catalog: file: "config/ai-models.json"
merge_filestring
Path to a local JSON file whose entries are merged into the base catalog. Base entries win on duplicates; the merge file only adds models that are not already present.
Lower bound, in hours, for the jittered background refresh interval.
refresh_interval_max_hoursnumberdefault: 12
Upper bound, in hours, for the jittered background refresh interval. Pangolin waits a random duration between min and max so many instances do not hit the upstream at the same moment.
For any variable marked "Supports _FILE" above, you can set <VARIABLE>_FILE instead of <VARIABLE> to a path on disk, and Pangolin will read that file and use its (trimmed) contents as the value. This is the standard way to consume Docker/Swarm secrets — for example a secret mounted at /run/secrets/server_secret — without ever putting the raw value in config.yml, a .env file, or the container's visible environment.
Setting both <VARIABLE> and <VARIABLE>_FILE at the same time is an error.