v2.31.0-dev21 b59533b

index.md RawHistoryFolder

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]
port = 8088
tls_port = 8443
registry_port = 5000
gordon_domain = "gordon.mydomain.com"

[routes]
"app.mydomain.com" = "myapp:latest"

Note: gordon_domain is the canonical key. Migrate older registry_domain values before restarting.

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]
port = 8088                              # HTTP proxy port (default: 8088)
registry_port = 5000                     # Registry port (default: 5000)
gordon_domain = "gordon.mydomain.com"    # Required: Gordon domain (registry + API)
# data_dir = "~/.gordon"                 # Default for user installations

# 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

# Deploy behavior
[deploy]
pull_policy = "if-tag-changed"           # always, if-not-present, if-tag-changed
readiness_mode = "auto"                  # auto, docker-health, delay
health_timeout = "90s"                   # Max wait for health-based readiness
readiness_delay = "5s"                   # Wait after running before ready
drain_mode = "auto"                      # auto, inflight, delay
drain_timeout = "30s"                    # Max wait for in-flight drain
drain_delay = "2s"                       # Wait after proxy invalidation before stopping the old container

# 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

[logging.container_logs]
enabled = true
dir = "~/.gordon/logs/containers"        # Default location
max_size = 100
max_backups = 3
max_age = 28

# 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                              # Bridge zerolog to OTLP logs
trace_sample_rate = 1.0                  # 0.0 = none, 1.0 = all

# Environment variables
[env]
dir = "~/.gordon/env"                    # Default location

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

# Network isolation
[network_isolation]
enabled = true                           # Per-app isolated networks
network_prefix = "gordon"                # Network name prefix
internal = false                          # Set true to block direct egress from isolated networks

# Auto-route
[auto_route]
enabled = false                          # Auto-create routes from image names

# Routes (required)
[routes]
"app.mydomain.com" = "myapp:latest"
"api.mydomain.com" = "myapi:v2.1.0"

# Network groups
[network_groups]
"backend" = ["app.mydomain.com", "api.mydomain.com"]

# Attachments
[attachments]
"app.mydomain.com" = ["postgres:latest", "redis:latest"]
"backend" = ["rabbitmq:latest"]

# 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 = []                   # Explicit external registries allowed for deploy/attachments
require_digest = false                    # Require digests for allowlisted external registries

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

Configuration Sections

Section Description Documentation
[server] Core server settings Server
[auth] Authentication and secrets backend Auth
[api.rate_limit] Rate limiting configuration Rate Limiting
[deploy] Deployment behavior Deploy
[logging] Logging configuration Logging
[telemetry] OpenTelemetry observability export Telemetry
[env] Environment variable settings Environment
[volumes] Volume management Volumes
[network_isolation] Network isolation settings Network Isolation
[auto_route] Automatic route creation Auto Route
[routes] Domain to image mapping Routes
[external_routes] Non-containerized service proxying External Routes
[network_groups] Shared service networks Network Groups
[attachments] Service dependencies Attachments
[backups] Database backups Backups
[images.prune] Scheduled image cleanup Images
Security hardening Security controls and recommended knobs Security Hardening

Default Values

Setting Default
server.port 8088
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 []
deploy.pull_policy "if-tag-changed"
deploy.readiness_mode "auto"
deploy.health_timeout "90s"
deploy.readiness_delay "5s"
deploy.drain_mode "auto"
deploy.drain_timeout "30s"
deploy.drain_delay "2s"
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
logging.container_logs.enabled true
volumes.auto_create true
volumes.prefix "gordon"
volumes.preserve true
network_isolation.enabled true
network_isolation.internal false
auto_route.enabled 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 disabled and /v2/* is loopback-only.

Hot Reload

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

gordon 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

Note: Routes are hot-reloaded from the config file. You can still use the API or CLI (gordon routes add/update/remove) for live route changes.

Requires restart

Setting
server.port
server.data_dir
server.max_blob_chunk_size
server.max_blob_size
auth.*
deploy.readiness_mode
deploy.readiness_delay
deploy.health_timeout
deploy.drain_mode
deploy.drain_timeout

Environment Variable Override

Configuration values can be overridden with environment variables:

GORDON_SERVER_PORT=8088 gordon serve
GORDON_LOGGING_LEVEL=debug gordon serve

Pattern: GORDON_SECTION_KEY (uppercase, underscores instead of dots)

source
1# Configuration Overview
2
3Gordon uses a single TOML configuration file located at `~/.config/gordon/gordon.toml`.
4
5## Configuration File Location
6
7| Location | Purpose |
8|----------|---------|
9| `~/.config/gordon/gordon.toml` | Default configuration file |
10| Custom path via `--config` flag | `gordon serve --config /path/to/config.toml` |
11
12## Minimal Configuration
13
14```toml
15[server]
16port = 8088
17tls_port = 8443
18registry_port = 5000
19gordon_domain = "gordon.mydomain.com"
20
21[routes]
22"app.mydomain.com" = "myapp:latest"
23```
24
25> **Note:** `gordon_domain` is the canonical key. Migrate older `registry_domain` values before restarting.
26>
27> 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).
28
29## Full Configuration Reference
30
31For a complete list of all configuration options with their default values, see the [Configuration Reference](./reference.md).
32
33> **Note:** This example shows production-style paths. Default paths use `~/.gordon/` for user installations.
34
35```toml
36# Server settings
37[server]
38port = 8088                              # HTTP proxy port (default: 8088)
39registry_port = 5000                     # Registry port (default: 5000)
40gordon_domain = "gordon.mydomain.com"    # Required: Gordon domain (registry + API)
41# data_dir = "~/.gordon"                 # Default for user installations
42
43# Authentication (includes secrets backend)
44[auth]
45enabled = true                           # Enable registry authentication (default: true)
46secrets_backend = "pass"                 # "pass", "sops", or "unsafe"
47token_secret = "gordon/auth/token_secret"  # Required: JWT signing secret
48token_expiry = "30d"                     # Duration (1y, 30d, 2w) or 0 for never
49# Token-only authentication (password login was removed in v2.30.0)
50
51# API rate limiting
52[api.rate_limit]
53enabled = true                           # Enable rate limiting (default: true)
54global_rps = 500                         # Max requests/second globally
55per_ip_rps = 50                          # Max requests/second per IP
56burst = 100                              # Burst size
57trusted_proxies = []                     # IPs/CIDRs trusted for X-Forwarded-For
58
59# Deploy behavior
60[deploy]
61pull_policy = "if-tag-changed"           # always, if-not-present, if-tag-changed
62readiness_mode = "auto"                  # auto, docker-health, delay
63health_timeout = "90s"                   # Max wait for health-based readiness
64readiness_delay = "5s"                   # Wait after running before ready
65drain_mode = "auto"                      # auto, inflight, delay
66drain_timeout = "30s"                    # Max wait for in-flight drain
67drain_delay = "2s"                       # Wait after proxy invalidation before stopping the old container
68
69# Container runtime profile
70[containers]
71security_profile = "compat"              # compat or strict
72
73# Logging
74[logging]
75level = "info"                           # trace, debug, info, warn, error
76format = "console"                       # console or json
77
78[logging.file]
79enabled = true
80path = "~/.gordon/logs/gordon.log"       # Default location
81max_size = 100                           # MB before rotation
82max_backups = 3                          # Old files to keep
83max_age = 28                             # Days to keep
84
85[logging.container_logs]
86enabled = true
87dir = "~/.gordon/logs/containers"        # Default location
88max_size = 100
89max_backups = 3
90max_age = 28
91
92# Telemetry (OpenTelemetry)
93[telemetry]
94enabled = true                           # Enable OTLP export (default: false)
95endpoint = "http://localhost:5080/api/default"  # OTLP HTTP endpoint
96auth_token = ""                          # Base64 user:password for Basic auth
97traces = true                            # Export traces
98metrics = true                           # Export metrics
99logs = true                              # Bridge zerolog to OTLP logs
100trace_sample_rate = 1.0                  # 0.0 = none, 1.0 = all
101
102# Environment variables
103[env]
104dir = "~/.gordon/env"                    # Default location
105
106# Volume settings
107[volumes]
108auto_create = true                       # Auto-create from Dockerfile VOLUME
109prefix = "gordon"                        # Volume name prefix
110preserve = true                          # Keep volumes on container removal
111
112# Network isolation
113[network_isolation]
114enabled = true                           # Per-app isolated networks
115network_prefix = "gordon"                # Network name prefix
116internal = false                          # Set true to block direct egress from isolated networks
117
118# Auto-route
119[auto_route]
120enabled = false                          # Auto-create routes from image names
121
122# Routes (required)
123[routes]
124"app.mydomain.com" = "myapp:latest"
125"api.mydomain.com" = "myapi:v2.1.0"
126
127# Network groups
128[network_groups]
129"backend" = ["app.mydomain.com", "api.mydomain.com"]
130
131# Attachments
132[attachments]
133"app.mydomain.com" = ["postgres:latest", "redis:latest"]
134"backend" = ["rabbitmq:latest"]
135
136# Backups
137[backups]
138enabled = true
139schedule = "daily"                        # "hourly", "daily", "weekly", "monthly"
140storage_dir = "~/.gordon/backups"
141
142[backups.retention]
143hourly = 24
144daily = 7
145weekly = 4
146monthly = 12
147
148# Images
149[images]
150allowed_registries = []                   # Explicit external registries allowed for deploy/attachments
151require_digest = false                    # Require digests for allowlisted external registries
152
153[images.prune]
154enabled = false
155schedule = "daily"
156keep_last = 3
157```
158
159## Configuration Sections
160
161| Section | Description | Documentation |
162|---------|-------------|---------------|
163| `[server]` | Core server settings | [Server](./server.md) |
164| `[auth]` | Authentication and secrets backend | [Auth](./auth.md) |
165| `[api.rate_limit]` | Rate limiting configuration | [Rate Limiting](./rate-limiting.md) |
166| `[deploy]` | Deployment behavior | [Deploy](./deploy.md) |
167| `[logging]` | Logging configuration | [Logging](./logging.md) |
168| `[telemetry]` | OpenTelemetry observability export | [Telemetry](./telemetry.md) |
169| `[env]` | Environment variable settings | [Environment](./env.md) |
170| `[volumes]` | Volume management | [Volumes](./volumes.md) |
171| `[network_isolation]` | Network isolation settings | [Network Isolation](./network-isolation.md) |
172| `[auto_route]` | Automatic route creation | [Auto Route](./auto-route.md) |
173| `[routes]` | Domain to image mapping | [Routes](./routes.md) |
174| `[external_routes]` | Non-containerized service proxying | [External Routes](./external-routes.md) |
175| `[network_groups]` | Shared service networks | [Network Groups](./network-groups.md) |
176| `[attachments]` | Service dependencies | [Attachments](./attachments.md) |
177| `[backups]` | Database backups | [Backups](./backups.md) |
178| `[images.prune]` | Scheduled image cleanup | [Images](./images.md) |
179| Security hardening | Security controls and recommended knobs | [Security Hardening](./security-hardening.md) |
180
181## Default Values
182
183| Setting | Default |
184|---------|---------|
185| `server.port` | `8088` |
186| `server.registry_port` | `5000` |
187| `server.data_dir` | `~/.gordon` |
188| `server.max_blob_chunk_size` | `"95MB"` |
189| `server.max_blob_size` | `"1GB"` |
190| `auth.enabled` | `true` |
191| `auth.secrets_backend` | `"unsafe"` |
192| `auth.token_expiry` | `"30d"` |
193| `api.rate_limit.enabled` | `true` |
194| `api.rate_limit.global_rps` | `500` |
195| `api.rate_limit.per_ip_rps` | `50` |
196| `api.rate_limit.burst` | `100` |
197| `api.rate_limit.trusted_proxies` | `[]` |
198| `deploy.pull_policy` | `"if-tag-changed"` |
199| `deploy.readiness_mode` | `"auto"` |
200| `deploy.health_timeout` | `"90s"` |
201| `deploy.readiness_delay` | `"5s"` |
202| `deploy.drain_mode` | `"auto"` |
203| `deploy.drain_timeout` | `"30s"` |
204| `deploy.drain_delay` | `"2s"` |
205| `containers.security_profile` | `"compat"` |
206| `logging.level` | `"info"` |
207| `logging.format` | `"console"` |
208| `logging.file.enabled` | `false` |
209| `logging.file.max_size` | `100` |
210| `logging.file.max_backups` | `3` |
211| `logging.file.max_age` | `28` |
212| `logging.container_logs.enabled` | `true` |
213| `volumes.auto_create` | `true` |
214| `volumes.prefix` | `"gordon"` |
215| `volumes.preserve` | `true` |
216| `network_isolation.enabled` | `true` |
217| `network_isolation.internal` | `false` |
218| `auto_route.enabled` | `false` |
219| `backups.enabled` | `false` |
220| `backups.schedule` | `"daily"` (`"hourly"`, `"daily"`, `"weekly"`, `"monthly"`) |
221| `images.allowed_registries` | `[]` |
222| `images.require_digest` | `false` |
223| `images.prune.enabled` | `false` |
224| `images.prune.schedule` | `"daily"` |
225| `images.prune.keep_last` | `3` |
226| `telemetry.enabled` | `false` |
227| `telemetry.endpoint` | `""` |
228| `telemetry.auth_token` | `""` |
229| `telemetry.traces` | `true` |
230| `telemetry.metrics` | `true` |
231| `telemetry.logs` | `true` |
232| `telemetry.trace_sample_rate` | `1.0` |
233
234When `auth.enabled=false`, Gordon runs in local-only mode: `/admin/*` is disabled and `/v2/*` is loopback-only.
235
236## Hot Reload
237
238Gordon watches the configuration file and reloads automatically when changes are detected. You can also trigger a manual reload:
239
240```bash
241gordon reload
242```
243
244### Hot-reloaded (no restart needed)
245
246| Setting |
247|---------|
248| `server.gordon_domain` (registry domain) |
249| `server.registry_port` |
250| `server.max_proxy_body_size` |
251| `server.max_proxy_response_size` |
252| `server.max_concurrent_conns` |
253
254> **Note:** Routes are hot-reloaded from the config file. You can still use the API or CLI (`gordon routes add/update/remove`) for live route changes.
255
256### Requires restart
257
258| Setting |
259|---------|
260| `server.port` |
261| `server.data_dir` |
262| `server.max_blob_chunk_size` |
263| `server.max_blob_size` |
264| `auth.*` |
265| `deploy.readiness_mode` |
266| `deploy.readiness_delay` |
267| `deploy.health_timeout` |
268| `deploy.drain_mode` |
269| `deploy.drain_timeout` |
270
271## Environment Variable Override
272
273Configuration values can be overridden with environment variables:
274
275```bash
276GORDON_SERVER_PORT=8088 gordon serve
277GORDON_LOGGING_LEVEL=debug gordon serve
278```
279
280Pattern: `GORDON_SECTION_KEY` (uppercase, underscores instead of dots)
281
282## Related
283
284- [Server Configuration](./server.md)
285- [Routes Configuration](./routes.md)
286- [External Routes](./external-routes.md)
287- [Authentication](./auth.md)
288- [Telemetry](./telemetry.md)
289- [Backups](./backups.md)
290- [Images](./images.md)

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 7

Tags 106

↑↓ moveenter openesc close