Configuration Overview

Gordon uses a single TOML configuration file located at ~/.config/gordon/gordon.toml.

Configuration File Location

Location Purpose
~/.config/gordon/gordon.toml Default configuration file
Custom path via --config flag gordon serve --config /path/to/config.toml

Minimal Configuration

[server]
registry_port = 5000
gordon_domain = "gordon.mydomain.com"

[entrypoints.edge]
address = ":443"
protocol = "smart_tcp"

Application workloads live in standalone app files, not in gordon.toml — see App Manifest. Retired workload keys such as [routes], [attachments], [network_groups], [service_routes], [auto_route], and [previews] are rejected at startup. Installation-level [[services]] for standalone L4 workloads remains valid.

Note: gordon_domain is the canonical registry and Admin API host.

For a staged registry host rename, set the new server.gordon_domain and keep old Gordon registry hosts in server.legacy_registry_domains until clients move. See Server and Upgrading.

Full Configuration Reference

For a complete list of all configuration options with their default values, see the Configuration Reference.

Note: This example shows production-style paths. Default paths use ~/.gordon/ for user installations.

# Server settings
[server]
registry_port = 5000                     # Registry port (default: 5000)
gordon_domain = "gordon.mydomain.com"    # Required: Gordon domain (registry + API)
# data_dir = "~/.gordon"                 # Default for user installations

[entrypoints.edge]
address = ":443"                         # Deployment-selected public TCP socket
protocol = "smart_tcp"

# Authentication (includes secrets backend)
[auth]
enabled = true                           # Enable registry authentication (default: true)
secrets_backend = "pass"                 # "pass", "sops", or "unsafe"
token_secret = "gordon/auth/token_secret"  # Required: JWT signing secret
token_expiry = "30d"                     # Duration (1y, 30d, 2w) or 0 for never
# Token-only authentication (password login was removed in v2.30.0)

# API rate limiting
[api.rate_limit]
enabled = true                           # Enable rate limiting (default: true)
global_rps = 500                         # Max requests/second globally
per_ip_rps = 50                          # Max requests/second per IP
burst = 100                              # Burst size
trusted_proxies = []                     # IPs/CIDRs trusted for X-Forwarded-For

# Container runtime profile
[containers]
security_profile = "compat"              # compat or strict

# Logging
[logging]
level = "info"                           # trace, debug, info, warn, error
format = "console"                       # console or json

[logging.file]
enabled = true
path = "~/.gordon/logs/gordon.log"       # Default location
max_size = 100                           # MB before rotation
max_backups = 3                          # Old files to keep
max_age = 28                             # Days to keep

# Workload logs are streamed directly from the container runtime with
# `gordon apps logs APP --service SERVICE`.

# Telemetry (OpenTelemetry)
[telemetry]
enabled = true                           # Enable OTLP export (default: false)
endpoint = "http://localhost:5080/api/default"  # OTLP HTTP endpoint
auth_token = ""                          # Base64 user:password for Basic auth
traces = true                            # Export traces
metrics = true                           # Export metrics
logs = true                              # Export Gordon, access, and app logs
trace_sample_rate = 1.0                  # 0.0 = none, 1.0 = all

# Volume settings
[volumes]
auto_create = true                       # Auto-create from Dockerfile VOLUME
prefix = "gordon"                        # Volume name prefix
preserve = true                          # Keep volumes on container removal

# Installation network policy (prefix filter for `gordon daemon networks`)
[network_isolation]
enabled = true                           # Gordon-managed network policy
network_prefix = "gordon"                # Network name prefix
internal = false                          # Set true to block direct egress from isolated networks

# REMOVED in v3 (declare apps in standalone files, see ./apps.md):
# [routes], [attachments], [network_groups],
# [service_routes], [auto_route], [previews]

# Backups
[backups]
enabled = true
schedule = "daily"                        # "hourly", "daily", "weekly", "monthly"
storage_dir = "~/.gordon/backups"

[backups.retention]
hourly = 24
daily = 7
weekly = 4
monthly = 12

# Images
[images]
allowed_registries = []                   # Additional exact registry hostname+port entries
require_digest = false                    # Require SHA-256 digests for every image registry

[images.prune]
enabled = false
schedule = "daily"
keep_last = 3

Docker Hub (docker.io and registry-1.docker.io), ghcr.io, quay.io, and Gordon's registry are allowed by default. Add private or other registries with exact hostname+port entries. This hostname policy does not enforce resolved IP destinations or runtime egress; see Images.

Configuration Sections

Section Description Documentation
[server] Core server settings Server
[auth] Authentication and secrets backend Auth
[api.rate_limit] Rate limiting configuration Rate Limiting
[logging] Logging configuration Logging
[telemetry] OpenTelemetry observability export Telemetry
[volumes] Volume management Volumes
[network_isolation] Installation network policy Network Isolation
[external_routes] Non-containerized service proxying External Routes
[entrypoints], [traffic], [[network_services]], [[services]] L4 and TLS passthrough traffic plane Traffic
App files (<app>.toml) Declarative apps: services, hosts, secrets, volumes, backup targets App Manifest
[backups] Database backup storage, scheduling, and retention Backups
[images.prune] Scheduled image cleanup Images
Security hardening Security controls and recommended knobs Security Hardening

Default Values

Setting Default
server.registry_port 5000
server.data_dir ~/.gordon
server.max_blob_chunk_size "95MB"
server.max_blob_size "1GB"
auth.enabled true
auth.secrets_backend "unsafe"
auth.token_expiry "30d"
api.rate_limit.enabled true
api.rate_limit.global_rps 500
api.rate_limit.per_ip_rps 50
api.rate_limit.burst 100
api.rate_limit.trusted_proxies []
containers.security_profile "compat"
logging.level "info"
logging.format "console"
logging.file.enabled false
logging.file.max_size 100
logging.file.max_backups 3
logging.file.max_age 28
volumes.auto_create true
volumes.prefix "gordon"
volumes.preserve true
network_isolation.enabled true
network_isolation.internal false
backups.enabled false
backups.schedule "daily" ("hourly", "daily", "weekly", "monthly")
images.allowed_registries []
images.require_digest false
images.prune.enabled false
images.prune.schedule "daily"
images.prune.keep_last 3
telemetry.enabled false
telemetry.endpoint ""
telemetry.auth_token ""
telemetry.traces true
telemetry.metrics true
telemetry.logs true
telemetry.trace_sample_rate 1.0

When auth.enabled=false, Gordon runs in local-only mode: /admin/* is not registered on the TCP listener and /v2/* is loopback-only. Local gordon apps commands discover the daemon's owner-only admin socket in $XDG_RUNTIME_DIR/gordon, /run/user/<uid>/gordon, or ~/.gordon/run; the daemon itself uses the XDG location when configured and otherwise the home fallback. See Authentication.

Hot Reload

Gordon watches the configuration file and reloads automatically when changes are detected. You can also trigger a manual reload:

gordon daemon reload

Hot-reloaded (no restart needed)

Setting
server.gordon_domain (registry domain)
server.registry_port
server.max_proxy_body_size
server.max_proxy_response_size
server.max_concurrent_conns

Requires restart

Setting
entrypoints.edge.address
server.data_dir
server.max_blob_chunk_size
server.max_blob_size
auth.*

Environment Variable Override

Configuration values can be overridden with environment variables:

GORDON_LOGGING_LEVEL=debug gordon serve

Pattern: GORDON_SECTION_KEY (uppercase, underscores instead of dots)