v2.10.0 893d8fa

auto-route.md RawHistoryFolder

Auto Route Configuration

Gordon supports two methods for automatic route creation:

  1. Image Name Detection - Routes from domain-like image names
  2. Image Labels - Routes from Dockerfile labels (recommended)

Configuration

[auto_route]
enabled = true

Options

Option Type Default Description
enabled bool false Enable automatic route creation

How It Works

When auto-route is enabled, Gordon automatically creates routes for images with domain-like names:

# Push an image with a domain name
docker push registry.mydomain.com/app.example.com:latest

Gordon automatically:

  1. Detects app.example.com looks like a domain
  2. Creates a route: app.example.com → app.example.com:latest
  3. Deploys the container
  4. Routes traffic to it

Domain Detection

Gordon recognizes image names as domains when they:

  • Contain at least one dot (.)
  • Don't start or end with a dot
  • Look like valid hostnames
Image Name Detected as Domain?
app.example.com Yes
myapp.dev Yes
staging.api.io Yes
myapp No (no dots)
.invalid No (starts with dot)
myapp. No (ends with dot)

Use Cases

Simplified Deployment

Without auto-route:

# Must define each route in config
[routes]
"app.example.com" = "app.example.com:latest"

With auto-route:

[auto_route]
enabled = true
# No routes needed - just push!
docker push registry.mydomain.com/app.example.com:latest
# Route automatically created

Development Workflow

# Create a new app instantly
docker build -t myapp .
docker tag myapp registry.mydomain.com/newapp.mydomain.com:latest
docker push registry.mydomain.com/newapp.mydomain.com:latest
# newapp.mydomain.com is now live!

Multi-Tenant SaaS

# Quickly provision customer subdomains
docker push registry.mydomain.com/acme.saas.com:latest
docker push registry.mydomain.com/beta.saas.com:latest
docker push registry.mydomain.com/gamma.saas.com:latest

Combining with Manual Routes

Auto-route works alongside manual routes:

[auto_route]
enabled = true

[routes]
# Pinned versions override auto-route
"api.mydomain.com" = "myapi:v2.1.0"
  • api.mydomain.com uses the manually configured myapi:v2.1.0
  • Other domain-named images create automatic routes

Priority Order

  1. Manual routes in [routes] take precedence
  2. Auto-routes are created for domain-named images without manual routes

Examples

Enable Auto-Route

[auto_route]
enabled = true

Development with Auto-Route

[server]
gordon_domain = "gordon.local"

[auto_route]
enabled = true

# No routes defined - all come from image names

Usage:

docker push gordon.local/myapp.local:latest
docker push gordon.local/api.local:latest
# Both routes created automatically

Production with Auto-Route

[auto_route]
enabled = true

[routes]
# Critical services with pinned versions
"api.company.com" = "company-api:v2.1.0"
"app.company.com" = "company-app:v1.5.0"

# Other services can use auto-route

Limitations (Image Name Detection)

  • Auto-routes always use the pushed image tag
  • No support for HTTP-only routes (all HTTPS)
  • No automatic attachment configuration
  • Cannot pin versions (always uses pushed tag)

For more control, define routes manually in [routes] or use image labels.


The preferred method for automatic routing uses Dockerfile labels. This gives you full control over routing behavior directly in your application.

Supported Labels

Label Description Example
gordon.domains Comma-separated list of domains app.example.com,www.app.example.com
gordon.port Container port to proxy 3000
gordon.health Health check endpoint path /health
gordon.env-file Path to .env file in image /app/.env.example

Dockerfile Example

FROM node:20-alpine
WORKDIR /app
COPY . .
RUN npm install

# Gordon routing labels
LABEL gordon.domains="myapp.example.com,www.myapp.example.com"
LABEL gordon.port="3000"
LABEL gordon.health="/api/health"
LABEL gordon.env-file="/app/.env.example"

EXPOSE 3000
CMD ["npm", "start"]

How It Works

When you push an image with Gordon labels:

  1. Gordon reads the gordon.domains label
  2. Creates routes for each domain automatically
  3. Uses gordon.port for the proxy target (or first EXPOSE port)
  4. Configures health checks if gordon.health is set
  5. Extracts environment variables from gordon.env-file if specified

Label Priority

Labels take precedence over image name detection:

  1. Labels present → Use gordon.domains for routing
  2. No labels → Fall back to image name detection (if enabled)
  3. Manual routes → Always take highest priority

Multi-Domain Example

# Single image serving multiple domains
LABEL gordon.domains="api.example.com,api.staging.example.com"

Both domains will route to the same container.

Environment File Extraction

The gordon.env-file label tells Gordon where to find a template .env file:

# Include a .env.example in your image
COPY .env.example /app/.env.example
LABEL gordon.env-file="/app/.env.example"

Gordon will:

  1. Extract the file from the image
  2. Store it in the env directory
  3. Use the variables for container deployment

Best Practices

  1. Always set gordon.port - Don't rely on EXPOSE detection
  2. Use gordon.health - Enables reliable deployment verification
  3. Include .env.example - Self-documenting environment requirements
  4. Separate domains with commas - No spaces around commas

Example: Complete Setup

FROM golang:1.25-alpine AS builder
WORKDIR /app
COPY . .
RUN go build -o server

FROM alpine:3.21
WORKDIR /app
COPY --from=builder /app/server .
COPY .env.example .

# Gordon labels
LABEL gordon.domains="api.mycompany.com"
LABEL gordon.port="8080"
LABEL gordon.health="/health"
LABEL gordon.env-file="/app/.env.example"

EXPOSE 8080
CMD ["./server"]
# Push and Gordon handles everything
docker push registry.mycompany.com/api:latest
# Route automatically created: api.mycompany.com → container:8080
source
1# Auto Route Configuration
2
3Gordon supports two methods for automatic route creation:
4
51. **Image Name Detection** - Routes from domain-like image names
62. **Image Labels** - Routes from Dockerfile labels (recommended)
7
8## Configuration
9
10```toml
11[auto_route]
12enabled = true
13```
14
15## Options
16
17| Option | Type | Default | Description |
18|--------|------|---------|-------------|
19| `enabled` | bool | `false` | Enable automatic route creation |
20
21## How It Works
22
23When auto-route is enabled, Gordon automatically creates routes for images with domain-like names:
24
25```bash
26# Push an image with a domain name
27docker push registry.mydomain.com/app.example.com:latest
28```
29
30Gordon automatically:
311. Detects `app.example.com` looks like a domain
322. Creates a route: `app.example.com` → `app.example.com:latest`
333. Deploys the container
344. Routes traffic to it
35
36## Domain Detection
37
38Gordon recognizes image names as domains when they:
39
40- Contain at least one dot (`.`)
41- Don't start or end with a dot
42- Look like valid hostnames
43
44| Image Name | Detected as Domain? |
45|------------|-------------------|
46| `app.example.com` | Yes |
47| `myapp.dev` | Yes |
48| `staging.api.io` | Yes |
49| `myapp` | No (no dots) |
50| `.invalid` | No (starts with dot) |
51| `myapp.` | No (ends with dot) |
52
53## Use Cases
54
55### Simplified Deployment
56
57Without auto-route:
58```toml
59# Must define each route in config
60[routes]
61"app.example.com" = "app.example.com:latest"
62```
63
64With auto-route:
65```toml
66[auto_route]
67enabled = true
68# No routes needed - just push!
69```
70
71```bash
72docker push registry.mydomain.com/app.example.com:latest
73# Route automatically created
74```
75
76### Development Workflow
77
78```bash
79# Create a new app instantly
80docker build -t myapp .
81docker tag myapp registry.mydomain.com/newapp.mydomain.com:latest
82docker push registry.mydomain.com/newapp.mydomain.com:latest
83# newapp.mydomain.com is now live!
84```
85
86### Multi-Tenant SaaS
87
88```bash
89# Quickly provision customer subdomains
90docker push registry.mydomain.com/acme.saas.com:latest
91docker push registry.mydomain.com/beta.saas.com:latest
92docker push registry.mydomain.com/gamma.saas.com:latest
93```
94
95## Combining with Manual Routes
96
97Auto-route works alongside manual routes:
98
99```toml
100[auto_route]
101enabled = true
102
103[routes]
104# Pinned versions override auto-route
105"api.mydomain.com" = "myapi:v2.1.0"
106```
107
108- `api.mydomain.com` uses the manually configured `myapi:v2.1.0`
109- Other domain-named images create automatic routes
110
111## Priority Order
112
1131. **Manual routes** in `[routes]` take precedence
1142. **Auto-routes** are created for domain-named images without manual routes
115
116## Examples
117
118### Enable Auto-Route
119
120```toml
121[auto_route]
122enabled = true
123```
124
125### Development with Auto-Route
126
127```toml
128[server]
129gordon_domain = "gordon.local"
130
131[auto_route]
132enabled = true
133
134# No routes defined - all come from image names
135```
136
137Usage:
138```bash
139docker push gordon.local/myapp.local:latest
140docker push gordon.local/api.local:latest
141# Both routes created automatically
142```
143
144### Production with Auto-Route
145
146```toml
147[auto_route]
148enabled = true
149
150[routes]
151# Critical services with pinned versions
152"api.company.com" = "company-api:v2.1.0"
153"app.company.com" = "company-app:v1.5.0"
154
155# Other services can use auto-route
156```
157
158## Limitations (Image Name Detection)
159
160- Auto-routes always use the pushed image tag
161- No support for HTTP-only routes (all HTTPS)
162- No automatic attachment configuration
163- Cannot pin versions (always uses pushed tag)
164
165For more control, define routes manually in `[routes]` or use image labels.
166
167---
168
169## Image Labels (Recommended)
170
171The preferred method for automatic routing uses Dockerfile labels. This gives you full control over routing behavior directly in your application.
172
173### Supported Labels
174
175| Label | Description | Example |
176|-------|-------------|---------|
177| `gordon.domains` | Comma-separated list of domains | `app.example.com,www.app.example.com` |
178| `gordon.port` | Container port to proxy | `3000` |
179| `gordon.health` | Health check endpoint path | `/health` |
180| `gordon.env-file` | Path to .env file in image | `/app/.env.example` |
181
182### Dockerfile Example
183
184```dockerfile
185FROM node:20-alpine
186WORKDIR /app
187COPY . .
188RUN npm install
189
190# Gordon routing labels
191LABEL gordon.domains="myapp.example.com,www.myapp.example.com"
192LABEL gordon.port="3000"
193LABEL gordon.health="/api/health"
194LABEL gordon.env-file="/app/.env.example"
195
196EXPOSE 3000
197CMD ["npm", "start"]
198```
199
200### How It Works
201
202When you push an image with Gordon labels:
203
2041. Gordon reads the `gordon.domains` label
2052. Creates routes for each domain automatically
2063. Uses `gordon.port` for the proxy target (or first EXPOSE port)
2074. Configures health checks if `gordon.health` is set
2085. Extracts environment variables from `gordon.env-file` if specified
209
210### Label Priority
211
212Labels take precedence over image name detection:
213
2141. **Labels present** → Use `gordon.domains` for routing
2152. **No labels** → Fall back to image name detection (if enabled)
2163. **Manual routes** → Always take highest priority
217
218### Multi-Domain Example
219
220```dockerfile
221# Single image serving multiple domains
222LABEL gordon.domains="api.example.com,api.staging.example.com"
223```
224
225Both domains will route to the same container.
226
227### Environment File Extraction
228
229The `gordon.env-file` label tells Gordon where to find a template `.env` file:
230
231```dockerfile
232# Include a .env.example in your image
233COPY .env.example /app/.env.example
234LABEL gordon.env-file="/app/.env.example"
235```
236
237Gordon will:
2381. Extract the file from the image
2392. Store it in the env directory
2403. Use the variables for container deployment
241
242### Best Practices
243
2441. **Always set `gordon.port`** - Don't rely on EXPOSE detection
2452. **Use `gordon.health`** - Enables reliable deployment verification
2463. **Include `.env.example`** - Self-documenting environment requirements
2474. **Separate domains with commas** - No spaces around commas
248
249### Example: Complete Setup
250
251```dockerfile
252FROM golang:1.25-alpine AS builder
253WORKDIR /app
254COPY . .
255RUN go build -o server
256
257FROM alpine:3.21
258WORKDIR /app
259COPY --from=builder /app/server .
260COPY .env.example .
261
262# Gordon labels
263LABEL gordon.domains="api.mycompany.com"
264LABEL gordon.port="8080"
265LABEL gordon.health="/health"
266LABEL gordon.env-file="/app/.env.example"
267
268EXPOSE 8080
269CMD ["./server"]
270```
271
272```bash
273# Push and Gordon handles everything
274docker push registry.mycompany.com/api:latest
275# Route automatically created: api.mycompany.com → container:8080
276```
277
278## Related
279
280- [Routes](./routes.md)
281- [Configuration Overview](./index.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