v2.2.6 c872d45

routes.md RawHistoryFolder

Routes Configuration

Routes map domains to container images.

Configuration

[routes]
"app.mydomain.com" = "myapp:latest"
"api.mydomain.com" = "myapi:v2.1.0"
"admin.mydomain.com" = "admin-panel:v1.0.0"

Syntax

[routes]
"<domain>" = "<image>:<tag>"
Component Description
domain Fully qualified domain name
image Container image name (as pushed to Gordon's registry)
tag Image tag (version, latest, etc.)

Route Types

HTTPS Routes (Default)

Standard routes expect HTTPS traffic (terminated by Cloudflare or similar):

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

HTTP-Only Routes

For internal or development routes without HTTPS:

[routes]
"http://internal.local" = "internal-app:latest"

The http:// prefix tells Gordon not to expect HTTPS.

Version Strategies

Latest Tag

Always deploy the most recent push:

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

Pinned Version

Deploy a specific version:

[routes]
"app.mydomain.com" = "myapp:v2.1.0"

Update the config to deploy a new version:

[routes]
"app.mydomain.com" = "myapp:v2.2.0"  # Changed

Semantic Versioning

Use different routes for different versions:

[routes]
"app.mydomain.com" = "myapp:v2.1.0"        # Production
"staging.mydomain.com" = "myapp:staging"    # Staging
"canary.mydomain.com" = "myapp:canary"      # Canary

Multiple Routes

Same Image, Different Domains

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

Multiple Services

[routes]
"app.mydomain.com" = "frontend:latest"
"api.mydomain.com" = "backend:v2.1.0"
"docs.mydomain.com" = "documentation:latest"
"status.mydomain.com" = "status-page:v1.0.0"

How Routing Works

  1. Request arrives for app.mydomain.com
  2. Gordon looks up the route in configuration
  3. Finds running container for myapp:latest
  4. Proxies request to container's exposed port
  5. Returns response to client
Client ─> Gordon Proxy ─> Container
          (port 80)       (exposed port)

Deployment Flow

When you push an image:

docker push registry.mydomain.com/myapp:latest
  1. Gordon receives the image
  2. Checks routes for any that use myapp:latest
  3. Deploys new container for each matching route
  4. Updates proxy to route traffic to new container
  5. Stops old container

Hot Reload

Routes reload automatically when the config file changes:

# Edit config
vim ~/.config/gordon/gordon.toml

# Add new route
[routes]
"newapp.mydomain.com" = "newapp:latest"

# Save - Gordon reloads automatically

Or trigger manually:

gordon reload

Examples

Development Setup

[routes]
"app.local" = "myapp:latest"
"api.local" = "myapi:latest"

Add to /etc/hosts:

127.0.0.1  app.local api.local registry.local

Production Setup

[routes]
"app.company.com" = "company-app:v2.1.0"
"api.company.com" = "company-api:v1.5.2"
"admin.company.com" = "admin-panel:v1.0.1"
"docs.company.com" = "company-docs:latest"

Multi-Tenant SaaS

[routes]
# Platform services
"app.saas-platform.com" = "saas-frontend:v2.1.0"
"api.saas-platform.com" = "saas-api:v3.2.1"

# Customer subdomains
"acme.saas-platform.com" = "saas-app:v2.1.0"
"beta.saas-platform.com" = "saas-app:v2.1.0"

# Customer custom domains
"portal.acme-corp.com" = "saas-app:v2.1.0"

External Services

For non-containerized services (databases, legacy apps, etc.), see External Routes.

source
1# Routes Configuration
2
3Routes map domains to container images.
4
5## Configuration
6
7```toml
8[routes]
9"app.mydomain.com" = "myapp:latest"
10"api.mydomain.com" = "myapi:v2.1.0"
11"admin.mydomain.com" = "admin-panel:v1.0.0"
12```
13
14## Syntax
15
16```toml
17[routes]
18"<domain>" = "<image>:<tag>"
19```
20
21| Component | Description |
22|-----------|-------------|
23| `domain` | Fully qualified domain name |
24| `image` | Container image name (as pushed to Gordon's registry) |
25| `tag` | Image tag (version, `latest`, etc.) |
26
27## Route Types
28
29### HTTPS Routes (Default)
30
31Standard routes expect HTTPS traffic (terminated by Cloudflare or similar):
32
33```toml
34[routes]
35"app.mydomain.com" = "myapp:latest"
36```
37
38### HTTP-Only Routes
39
40For internal or development routes without HTTPS:
41
42```toml
43[routes]
44"http://internal.local" = "internal-app:latest"
45```
46
47The `http://` prefix tells Gordon not to expect HTTPS.
48
49## Version Strategies
50
51### Latest Tag
52
53Always deploy the most recent push:
54
55```toml
56[routes]
57"app.mydomain.com" = "myapp:latest"
58```
59
60### Pinned Version
61
62Deploy a specific version:
63
64```toml
65[routes]
66"app.mydomain.com" = "myapp:v2.1.0"
67```
68
69Update the config to deploy a new version:
70
71```toml
72[routes]
73"app.mydomain.com" = "myapp:v2.2.0"  # Changed
74```
75
76### Semantic Versioning
77
78Use different routes for different versions:
79
80```toml
81[routes]
82"app.mydomain.com" = "myapp:v2.1.0"        # Production
83"staging.mydomain.com" = "myapp:staging"    # Staging
84"canary.mydomain.com" = "myapp:canary"      # Canary
85```
86
87## Multiple Routes
88
89### Same Image, Different Domains
90
91```toml
92[routes]
93"app.mydomain.com" = "myapp:latest"
94"www.mydomain.com" = "myapp:latest"
95"mydomain.com" = "myapp:latest"
96```
97
98### Multiple Services
99
100```toml
101[routes]
102"app.mydomain.com" = "frontend:latest"
103"api.mydomain.com" = "backend:v2.1.0"
104"docs.mydomain.com" = "documentation:latest"
105"status.mydomain.com" = "status-page:v1.0.0"
106```
107
108## How Routing Works
109
1101. Request arrives for `app.mydomain.com`
1112. Gordon looks up the route in configuration
1123. Finds running container for `myapp:latest`
1134. Proxies request to container's exposed port
1145. Returns response to client
115
116```
117Client ─> Gordon Proxy ─> Container
118          (port 80)       (exposed port)
119```
120
121## Deployment Flow
122
123When you push an image:
124
125```bash
126docker push registry.mydomain.com/myapp:latest
127```
128
1291. Gordon receives the image
1302. Checks routes for any that use `myapp:latest`
1313. Deploys new container for each matching route
1324. Updates proxy to route traffic to new container
1335. Stops old container
134
135## Hot Reload
136
137Routes reload automatically when the config file changes:
138
139```bash
140# Edit config
141vim ~/.config/gordon/gordon.toml
142
143# Add new route
144[routes]
145"newapp.mydomain.com" = "newapp:latest"
146
147# Save - Gordon reloads automatically
148```
149
150Or trigger manually:
151
152```bash
153gordon reload
154```
155
156## Examples
157
158### Development Setup
159
160```toml
161[routes]
162"app.local" = "myapp:latest"
163"api.local" = "myapi:latest"
164```
165
166Add to `/etc/hosts`:
167```
168127.0.0.1  app.local api.local registry.local
169```
170
171### Production Setup
172
173```toml
174[routes]
175"app.company.com" = "company-app:v2.1.0"
176"api.company.com" = "company-api:v1.5.2"
177"admin.company.com" = "admin-panel:v1.0.1"
178"docs.company.com" = "company-docs:latest"
179```
180
181### Multi-Tenant SaaS
182
183```toml
184[routes]
185# Platform services
186"app.saas-platform.com" = "saas-frontend:v2.1.0"
187"api.saas-platform.com" = "saas-api:v3.2.1"
188
189# Customer subdomains
190"acme.saas-platform.com" = "saas-app:v2.1.0"
191"beta.saas-platform.com" = "saas-app:v2.1.0"
192
193# Customer custom domains
194"portal.acme-corp.com" = "saas-app:v2.1.0"
195```
196
197## External Services
198
199For non-containerized services (databases, legacy apps, etc.), see [External Routes](./external-routes.md).
200
201## Related
202
203- [Configuration Overview](./index.md)
204- [Auto Route](./auto-route.md)
205- [Attachments](./attachments.md)
206- [External Routes](./external-routes.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