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.