v3.1.0 d676137

services.md RawHistoryFolder

Standalone Services

Standalone services are Gordon-managed containers for non-HTTP workloads such as game servers, databases, or TCP/UDP daemons. Gordon creates, starts, restarts, reconciles, and removes these containers from the [[services]] configuration during startup and reload.

Standalone services are separate from HTTP [routes]. Route normal web apps with [routes]; use [[services]] when Gordon must manage a long-running container that is reached by explicit L4 traffic routers.

Example

[[services]]
name = "rust"
image = "registry.example.com:5000/rust:latest"
enabled = true
env_file = "/srv/gordon/services/rust.env"

[services.readiness]
type = "log"
path = "/steamcmd/rust/server.log"
contains = "Server startup complete"
timeout = "2m"

[[services.ports]]
name = "game"
container = 28015
protocol = "udp"
publish = "127.0.0.1:38015"

[[services.ports]]
name = "rcon"
container = 28016
protocol = "tcp"
publish = "127.0.0.1:38016"
trusted_cidrs = ["100.64.0.0/10"]

The publish address is the host-side bind address that Gordon's traffic manager dials; use loopback for private backends. Expose services through [traffic] routers instead of binding service containers directly to a public interface.

Traffic routing

Use service:<service>:<port-name> from TCP, UDP, or TLS passthrough routers:

[entrypoints.rust]
address = "0.0.0.0:28015"
protocol = "udp"

[[traffic.udp.routers]]
name = "rust-game"
entrypoint = "rust"
service = "service:rust:game"

[entrypoints.rcon]
address = "0.0.0.0:28016"
protocol = "tcp"
trusted_cidrs = ["100.64.0.0/10"]

[[traffic.tcp.routers]]
name = "rust-rcon"
entrypoint = "rcon"
service = "service:rust:rcon"

Ports named rcon default to private. Private ports require non-empty trusted_cidrs on both the service port and target entrypoint, and the CIDR sets must match. To intentionally expose an RCON port publicly, set public = true on that port.

Volumes

Explicit volumes are optional:

[[services.volumes]]
source = "rust-data"
target = "/steamcmd/rust"
read_only = false

When [[services.volumes]] is omitted, Gordon inspects the image VOLUME metadata and creates deterministic Gordon-managed named volumes for those paths. If the image has no VOLUME metadata, the service is stateless unless the image writes inside its own filesystem.

Gordon tracks image-discovered managed volumes and only removes those managed volumes when cleanup.preserve_volumes = false. Explicit named volumes and bind mounts are not deleted as managed image volumes.

Cleanup

[services.cleanup]
preserve_volumes = true
remove_container = true

By default Gordon removes old or disabled service containers while preserving volumes. Set preserve_volumes = false only for disposable managed image volumes.

source
1# Standalone Services
2
3Standalone services are Gordon-managed containers for non-HTTP workloads such as game servers, databases, or TCP/UDP daemons. Gordon creates, starts, restarts, reconciles, and removes these containers from the `[[services]]` configuration during startup and reload.
4
5Standalone services are separate from HTTP `[routes]`. Route normal web apps with `[routes]`; use `[[services]]` when Gordon must manage a long-running container that is reached by explicit L4 traffic routers.
6
7## Example
8
9```toml
10[[services]]
11name = "rust"
12image = "registry.example.com:5000/rust:latest"
13enabled = true
14env_file = "/srv/gordon/services/rust.env"
15
16[services.readiness]
17type = "log"
18path = "/steamcmd/rust/server.log"
19contains = "Server startup complete"
20timeout = "2m"
21
22[[services.ports]]
23name = "game"
24container = 28015
25protocol = "udp"
26publish = "127.0.0.1:38015"
27
28[[services.ports]]
29name = "rcon"
30container = 28016
31protocol = "tcp"
32publish = "127.0.0.1:38016"
33trusted_cidrs = ["100.64.0.0/10"]
34```
35
36The `publish` address is the host-side bind address that Gordon's traffic manager dials; use loopback for private backends. Expose services through `[traffic]` routers instead of binding service containers directly to a public interface.
37
38## Traffic routing
39
40Use `service:<service>:<port-name>` from TCP, UDP, or TLS passthrough routers:
41
42```toml
43[entrypoints.rust]
44address = "0.0.0.0:28015"
45protocol = "udp"
46
47[[traffic.udp.routers]]
48name = "rust-game"
49entrypoint = "rust"
50service = "service:rust:game"
51
52[entrypoints.rcon]
53address = "0.0.0.0:28016"
54protocol = "tcp"
55trusted_cidrs = ["100.64.0.0/10"]
56
57[[traffic.tcp.routers]]
58name = "rust-rcon"
59entrypoint = "rcon"
60service = "service:rust:rcon"
61```
62
63Ports named `rcon` default to private. Private ports require non-empty `trusted_cidrs` on both the service port and target entrypoint, and the CIDR sets must match. To intentionally expose an RCON port publicly, set `public = true` on that port.
64
65## Volumes
66
67Explicit volumes are optional:
68
69```toml
70[[services.volumes]]
71source = "rust-data"
72target = "/steamcmd/rust"
73read_only = false
74```
75
76When `[[services.volumes]]` is omitted, Gordon inspects the image `VOLUME` metadata and creates deterministic Gordon-managed named volumes for those paths. If the image has no `VOLUME` metadata, the service is stateless unless the image writes inside its own filesystem.
77
78Gordon tracks image-discovered managed volumes and only removes those managed volumes when `cleanup.preserve_volumes = false`. Explicit named volumes and bind mounts are not deleted as managed image volumes.
79
80## Cleanup
81
82```toml
83[services.cleanup]
84preserve_volumes = true
85remove_container = true
86```
87
88By default Gordon removes old or disabled service containers while preserving volumes. Set `preserve_volumes = false` only for disposable managed image volumes.
89
90## Related
91
92- [Traffic Plane Configuration](./traffic.md)
93- [Configuration Reference](./reference.md)
94- [CLI traffic status](../cli/daemon.md#gordon-daemon-traffic)

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