# Gordon example configuration # Copy this file to ~/.config/gordon/gordon.toml and adjust for your domain. [server] registry_port = 5000 gordon_domain = "gordon.example.com" # legacy_registry_domains = ["registry.example.com:5000"] # proxy_allowed_ips = ["173.245.48.0/20"] # registry_allowed_ips = [] # registry_listen_address = "" # tls_cert_file = "" # tls_key_file = "" # force_https_redirect = false # data_dir = "~/.gordon" # max_blob_chunk_size = "95MB" # max_blob_size = "1GB" # max_proxy_body_size = "512MB" # max_proxy_response_size = "1GB" # max_concurrent_connections = 10000 # "edge" is the conventional route-capable entrypoint name, but a single # custom smart_tcp or tls_mux entrypoint can also serve normal Gordon routes. [entrypoints.edge] address = ":443" protocol = "smart_tcp" # trusted_cidrs = [] # raw_fallback = "ssh-fallback" # raw_fallback_trusted_cidrs = ["100.64.0.0/10"] # allow_public_raw_fallback = false [dns] resolvers = ["1.1.1.1:53", "8.8.8.8:53"] propagation_timeout = "5m" polling_interval = "5s" [tls.acme] enabled = false email = "" challenge = "auto" obtain_batch_size = 1 [auth] enabled = true # Use "pass" or "sops" in production. The unsafe backend reads a local file # under server.data_dir/secrets and is intended for development only. secrets_backend = "pass" token_secret = "gordon/auth/token_secret" token_expiry = "30d" access_token_ttl = "15m" [api.rate_limit] enabled = true global_rps = 500 per_ip_rps = 50 burst = 100 trusted_proxies = [] [containers] # "compat" preserves broad image compatibility. "strict" enables a read-only # root filesystem and narrower Linux capabilities. security_profile = "compat" [network_isolation] # Installation network policy for Gordon-managed networks (prefix filter # for `gordon daemon networks`). Per-app isolation is removed: apps declare # `[[network.shared]]` membership in their app file instead. enabled = true network_prefix = "gordon" # Set true to create Docker internal networks without direct external egress. internal = false [volumes] auto_create = true prefix = "gordon" preserve = true [images] # Docker Hub, ghcr.io, quay.io, and Gordon's registry are always allowed. # Add other registries as exact hostname+port entries; this does not configure credentials. allowed_registries = [] # Require @sha256:<64 hex chars> for images from every registry, including Gordon. require_digest = false [images.prune] enabled = false schedule = "daily" keep_last = 3 [logging] level = "info" format = "console" [logging.file] enabled = false # path = "~/.gordon/logs/gordon.log" # max_size = 100 # max_backups = 3 # max_age = 28 [logging.access_log] enabled = false format = "json" output = "stdout" # file_path = "~/.gordon/logs/access.log" max_size = 100 max_backups = 3 max_age = 28 exclude_health_checks = true syslog_identifier = "gordon-access" # ============================================================================= # ADMINISTRATIVE APP BIND MOUNTS # ============================================================================= # A named policy is the only way an app manifest may reference a host path. # The manifest declares [[services..bind]] name = ""; direct host paths # are always rejected. allowed_apps/allowed_services are exact and non-empty, # and read_only/readonly force read-only: either side wins. # [app_mounts.app-logs] # source = "/srv/gordon/host-logs" # Required; absolute, normalized # read_only = true # Either side forcing read-only wins # allowed_apps = ["metrics-agent"] # Required; exact, non-empty # allowed_services = ["web"] # Required; exact, non-empty # root = "/srv/gordon" # Optional; defaults to the source's parent # ============================================================================= # ADMINISTRATIVE APP DEVICES (CDI) # ============================================================================= # A named device grant is the only way an app manifest may request host # devices. The manifest declares devices = [""]; raw /dev paths, # privileged containers, and runtime-specific GPU flags are never used. # Gordon resolves each name to explicit CDI IDs at activation time and # encodes them as one native CDI DeviceRequest. allowed_apps and # allowed_services are exact and non-empty: only that app+service pair # receives the grant. Aggregate "=all" selectors are rejected: name every # device explicitly. Changing a mapping never recreates a running # container; the next deploy serves the new resolution. Revoking a grant # fails subsequent deploys closed while the running service is untouched. # Supported engines: Podman 5.4+ or Docker 28.3+ with native CDI # configured (CDI specs, toolkit, device permissions on the host). # [app_devices.transcode-gpu] # cdi = ["example.com/gpu=GPU-device-uuid"] # Required; explicit, non-empty # allowed_apps = ["video"] # Required; exact, non-empty # allowed_services = ["transcoder"] # Required; exact, non-empty [telemetry] enabled = false # endpoint = "http://localhost:4318" # auth_token = "" traces = true metrics = true logs = true trace_sample_rate = 1.0 [backups.databases] enabled = false schedule = "daily" storage_dir = "" [backups.databases.retention] hourly = 0 daily = 0 weekly = 0 monthly = 0 [backups.volumes] enabled = false interval = "24h" compression = "gzip" timeout = "2h" max_concurrency = 2 # Helper image must include tar and the selected compressor. helper_image = "alpine:3.20" [backups.volumes.s3] bucket = "" region = "" prefix = "" # endpoint = "https://s3.example.com" # path_style = false # sse_algorithm = "AES256" # sse_kms_key_id = "" [backups.volumes.retention] keep = 14 # [routes] is retired (see REMOVED list below): declaring it fails boot/reload closed. # "app.example.com" = { image = "myapp:latest" } [external_routes] # "status.example.com" = "127.0.0.1:9000" # # NOTE: the pre-v3 application keys below were removed by the # declarative-apps cutover. Gordon fails boot/reload closed when any of # them is present (see validateRetiredAppConfig in internal/app/run.go). # Declare application workloads in standalone .toml files instead: # one file per app, applied with `gordon apps apply --file .toml` # and activated with `gordon apps deploy `. # # REMOVED: [routes] -> [[services..http]] in an app file # REMOVED: [attachments] -> [services.] + volumes in an app file # REMOVED: [network_groups] -> [[network.shared]] in an app file # REMOVED: app-like [[services]] -> one [services.] table per app file # (installation [[services]] below stays valid for L4 workloads) # REMOVED: [service_routes] -> [[services..http]] in an app file # REMOVED: [auto]/[auto_route] -> explicit interfaces in an app file # REMOVED: [previews] -> staging is an ordinary app file # Gordon-managed standalone L4 services. Use service:: from # traffic routers to expose published loopback ports. Standalone services # are installation-level: they live in gordon.toml, not in app files. # (App services are declared with [services.] tables in .toml files and # managed with `gordon apps`; see docs/cli/apps.md.) # [[services]] # name = "rust" # image = "registry.example.com:5000/rust:latest" # enabled = true # env_file = "/srv/gordon/services/rust.env" # # [[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"] # # [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" # # REMOVED application sections (see note under [external_routes] above): # [routes], [network_groups], [attachments] were deleted with the cutover.