| title | Getting Started |
|---|---|
| sidebar_position | 1 |
Build from source (requires Go 1.25+):
go build -o runway ./cmd/runway/Set version and build time at compile:
go build -ldflags "-X main.version=1.0.0 -X main.buildTime=$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
-o runway ./cmd/runway/Pre-built multi-arch images (linux/amd64, linux/arm64) are available on GHCR:
docker run -p 8080:8080 -p 8081:8081 \
-v $(pwd)/configs:/app/configs:ro \
ghcr.io/wudi/runway:latestTags follow semver on release (e.g. v1.2.3, 1.2) and latest + sha-<commit> on every push to master.
Build locally with Make:
make docker-build
make docker-runStart the full stack (runway + mock backends) with Compose:
make compose-upEnable infrastructure services using profiles:
# Start with Redis (for distributed rate limiting / cache)
make compose-up-redis
# Start with OpenTelemetry collector (for tracing)
make compose-up-otel
# Start with all infrastructure
make compose-up-allBuild multi-architecture images (linux/amd64 + linux/arm64) and push to a registry:
make docker-buildxStop everything:
make compose-down| Flag | Default | Description |
|---|---|---|
-config |
configs/runway.yaml |
Path to configuration file |
-version |
— | Print version and build time, then exit |
-validate |
— | Validate configuration file and exit (non-zero on error) |
The smallest working config requires one listener and one route:
listeners:
- id: "http"
address: ":8080"
protocol: "http"
routes:
- id: "my-app"
path: "/api"
path_prefix: true
backends:
- url: "http://localhost:9000"Start the runway:
./runway -config my-config.yamlCheck your config for errors without starting the server:
./runway -validate -config my-config.yaml
# Prints "Configuration is valid" and exits 0, or prints error and exits 1| Signal | Effect |
|---|---|
SIGHUP |
Reload configuration from disk (zero-downtime) |
SIGINT / SIGTERM |
Graceful shutdown |
Reload example:
kill -HUP $(pidof runway)See Admin API for HTTP-based reload via POST /reload.
YAML values support ${VAR} syntax for environment variable substitution:
authentication:
jwt:
secret: "${JWT_SECRET}"
api_key:
keys:
- key: "${API_KEY_PROD}"
client_id: "prod-client"Unset variables are kept as-is in the config (e.g., ${MISSING_VAR} remains literally ${MISSING_VAR}).
When not specified, the gateway applies these defaults:
- Listener timeouts: 30s read, 30s write, 60s idle
- Registry:
memorytype - API key header:
X-API-Key - JWT algorithm:
HS256 - Log level:
info, output tostdout - Admin API: Enabled on port 8081
- Core Concepts — understand the request processing pipeline
- Configuration Reference — full schema reference
- Examples — production-ready configuration templates