Octopus
1.x
Docs/Octopus/Configuration
Open

Reading5 min
Updated31 Jul 2026
Sourcev1/configuration/index.mdx

Configuration

Octopus is configured from a single declarative file (or a set of merged files). The format is detected from the file extension: YAML (.yaml/.yml), TOML (.toml), or JSON (.json). All three deserialize into the same schema, so YAML field names, TOML keys, and JSON keys are identical.

The only required section is gateway, which must specify a listen address. Every other section has defaults and may be omitted.

Warning

Implementation status. Octopus parses the entire schema documented here, but some fields are accepted for forward-compatibility and not yet enforced at runtime. The notable ones (each flagged on its page): the grpc block is parsed but not consumed, and in the plugins array only script plugins are loaded (static/dynamic plugin loading is not yet wired). The middleware wired into the request chain today are compression, CORS (global + per-route), per-route rate limiting, script plugins, and authentication.

gateway:
  listen: "0.0.0.0:8080"

upstreams:
  - name: api
    instances:
      - id: api-1
        host: 127.0.0.1
        port: 9000

routes:
  - path: /api
    upstream: api

File formats01

The same configuration in each supported format:

yaml
gateway:
  listen: "0.0.0.0:8080"

upstreams:
  - name: api
    instances:
      - id: api-1
        host: 127.0.0.1
        port: 9000

routes:
  - path: /api
    upstream: api
Note

Durations are written in humantime form: 30s, 5m, 1h, 500ms. Sizes such as max_body_size are plain byte counts (integers), not 10MB-style strings.

Environment variable substitution02

Before parsing, Octopus expands ${VAR} references in the raw file text (in any format). Two forms are supported:

SyntaxBehavior
${VAR}Replaced with the value of VAR. Loading fails if VAR is unset.
${VAR:-default}Replaced with VAR if set, otherwise the literal default.
gateway:
  listen: "${LISTEN_ADDR:-0.0.0.0:8080}"

auth_providers:
  primary:
    type: jwt
    secret: "${JWT_SECRET}"   # required — startup fails if unset

Expansion is purely textual and happens everywhere in the file, so it works for any value (addresses, secrets, full URLs).

Loading and merging03

The gateway is started with octopus serve. The -c / --config flag accepts one or more files or directories (default: config.yaml).

# Single file
octopus serve -c config.yaml

# Multiple files, merged left to right (later wins)
octopus serve -c base.yaml -c production.yaml

# A directory — all *.yaml, *.yml, *.json, *.toml files are merged
octopus serve -c ./config.d

Merge order:

  • Multiple -c values are merged in the order given on the command line.

  • For a directory, files are collected per extension and sorted alphabetically within each extension group (the scan order is yaml, yml, json, toml), then merged.

Merge semantics (later file overrides earlier):

  • upstreams, routes, and plugins are merged by key — by name for upstreams and plugins, by path for routes. A later entry with the same key replaces the earlier one; new keys are added.

  • gateway is overlaid field by field (the later file's values win; workers: 0 is treated as "unset" and keeps the base value, and tls / internal_route_prefix fall back to the base when the overlay omits them).

  • observability from the last file replaces the earlier value wholesale.

Warning

The farp, auth, auth_providers, cors, admin, grpc, and kubernetes sections are not deep-merged. They retain the value from the first file in the merge set; later files do not override them. Keep each of these sections defined in a single file.

Validation04

Validate a configuration without starting the gateway:

octopus validate -c config.yaml

This loads and merges exactly as serve does, then runs the validator. It checks, among other things:

  • gateway.request_timeout is greater than zero (and warns if over 5 minutes).

  • gateway.max_body_size is greater than zero.

  • When gateway.tls is present: cert_file and key_file are non-empty, min_tls_version is 1.2 or 1.3, and reload_interval_secs is non-zero when cert reload is enabled.

  • Each upstream has a non-empty name; each instance has a non-empty id, non-empty host, and a non-zero port.

  • Each route path starts with /, has a non-empty upstream, and references an upstream that exists.

A valid configuration prints a summary (listen address, upstream/route/plugin counts) and exits 0; an invalid one prints the error and exits 1.

Top-level schema05

These are the fields of the root Config object. Each links to its detailed reference.

KeyTypeDefaultDescription
gatewayobjectListener, timeouts, body limits, compression, probes, TLS. Required.
upstreamsarray[]Backend services and their instances.
routesarray[]Path-based routing rules to upstreams.
pluginsarray[]Plugin instances (static or dynamic).
farpobjectdiscovery offService discovery and auto-routing.
observabilityobjectdefaultsLogging, metrics, tracing.
auth_providersmap{}Named authentication providers.
authobjectenforce offGlobal auth/authz behavior.
corsobjectnoneGlobal CORS policy.
adminobjectno authAdmin dashboard access control.
grpcobjectenabledgRPC / gRPC-Web proxying.
kubernetesobjectdisabledIn-process Gateway API controller.