# 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 ```toml [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](./apps.md). 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](./server.md#gordon-domain) and [Upgrading](../upgrading.md#staged-registry-host-rename). ## Full Configuration Reference For a complete list of all configuration options with their default values, see the [Configuration Reference](./reference.md). > **Note:** This example shows production-style paths. Default paths use `~/.gordon/` for user installations. ```toml # 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](./images.md). ## Configuration Sections | Section | Description | Documentation | |---------|-------------|---------------| | `[server]` | Core server settings | [Server](./server.md) | | `[auth]` | Authentication and secrets backend | [Auth](./auth.md) | | `[api.rate_limit]` | Rate limiting configuration | [Rate Limiting](./rate-limiting.md) | | `[logging]` | Logging configuration | [Logging](./logging.md) | | `[telemetry]` | OpenTelemetry observability export | [Telemetry](./telemetry.md) | | `[volumes]` | Volume management | [Volumes](./volumes.md) | | `[network_isolation]` | Installation network policy | [Network Isolation](./network-isolation.md) | | `[external_routes]` | Non-containerized service proxying | [External Routes](./external-routes.md) | | `[entrypoints]`, `[traffic]`, `[[network_services]]`, `[[services]]` | L4 and TLS passthrough traffic plane | [Traffic](./traffic.md) | | App files (`.toml`) | Declarative apps: services, hosts, secrets, volumes, backup targets | [App Manifest](./apps.md) | | `[backups]` | Database backup storage, scheduling, and retention | [Backups](./backups.md) | | `[images.prune]` | Scheduled image cleanup | [Images](./images.md) | | Security hardening | Security controls and recommended knobs | [Security Hardening](./security-hardening.md) | ## Default Values | Setting | Default | |---------|---------| | `server.registry_port` | `5000` | | `server.data_dir` | `~/.gordon` | | `server.max_blob_chunk_size` | `"95MB"` | | `server.max_blob_size` | `"1GB"` | | `server.http.read_header_timeout` | `"10s"` | | `server.http.read_timeout` | `"5m"` | | `server.http.write_timeout` | `"5m"` | | `server.http.idle_timeout` | `"120s"` | | `traffic.http.read_header_timeout` | `"5s"` | | `traffic.http.idle_timeout` | `"30s"` | | `traffic.http.transfer_idle_timeout` | `"2m"` | | `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.databases.enabled` | `false` | | `backups.databases.schedule` | `"daily"` (`"hourly"`, `"daily"`, `"weekly"`, `"monthly"`) | | `backups.databases.time` | `""` (preset default, server local time) | | `backups.volumes.enabled` | `false` | | `backups.volumes.schedule` | `"daily"` | | `backups.volumes.time` | `""` (preset default, server local time) | | `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//gordon`, or `~/.gordon/run`; the daemon itself uses the XDG location when configured and otherwise the home fallback. See [Authentication](./auth.md#local-only-mode). ## Hot Reload Gordon watches the configuration file and reloads automatically when changes are detected. You can also trigger a manual reload: ```bash 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` | | `traffic.http.*` (new connections after the traffic graph is applied) | ### Requires restart | Setting | |---------| | `entrypoints.edge.address` | | `server.data_dir` | | `server.max_blob_chunk_size` | | `server.max_blob_size` | | `server.http.*` | | `auth.*` | ## Environment Variable Override Configuration values can be overridden with environment variables: ```bash GORDON_LOGGING_LEVEL=debug gordon serve ``` Pattern: `GORDON_SECTION_KEY` (uppercase, underscores instead of dots) ## Related - [Server Configuration](./server.md) - [App Manifest](./apps.md) - [External Routes](./external-routes.md) - [Standalone Services](./services.md) - [Traffic Plane](./traffic.md) - [Authentication](./auth.md) - [Telemetry](./telemetry.md) - [Backups](./backups.md) - [Images](./images.md)