Skip to content

Gate - API Gateway

This directory contains the configuration system for the Gate application (Surkyl API Gateway).

Gate uses a flexible, hierarchical configuration system powered by config-rs that supports:

  • Multiple config formats: YAML, TOML, JSON
  • Environment variable overrides with GATE_ prefix
  • Hierarchical loading (dev → user → system → env)
  • File glob support for per-domain server configurations
  • Type-safe configuration with Rust structs

File: gate.config.{yml|yaml|toml|json}

The main gate configuration controls server behavior, TLS, observability, and global routes.

Directory: servers/**/*.{yml|yaml|toml|json}

Server configurations define virtual hosts, proxies, redirects, and per-domain routing rules.

Configuration files are loaded in priority order (highest to lowest):

  1. Environment Variables (highest priority)

    • Prefix: GATE_
    • Example: GATE_SERVER__HTTP_PORT=8080
  2. Repository Config (development)

    • Path: {repo_root}/configs/gate/gate.config.yml
    • Used during local development
  3. User Config (installation)

    • Path: ~/.config/gate/gate.config.yml
    • Used in production/user installs
  4. System Config (system-wide)

    • Path: /etc/gate/gate.config.yml
    • Optional system-wide defaults
  5. Default Values (fallback)

    • Hardcoded in Rust structs

Environment variables use the GATE_ prefix and double underscores (__) for nesting:

Terminal window
# Override server settings
GATE_SERVER__HOST=127.0.0.1
GATE_SERVER__HTTP_PORT=8080
GATE_SERVER__HTTPS_PORT=8443
# Enable TLS
GATE_TLS__ENABLED=true
GATE_TLS__AUTO_REDIRECT_HTTP=true
GATE_TLS__CERT_PATH=/certs/server.crt
GATE_TLS__KEY_PATH=/certs/server.key
# Configure logging
GATE_OBSERVABILITY__LOGGING__LEVEL=debug
GATE_OBSERVABILITY__LOGGING__FORMAT=json
# Enable metrics
GATE_OBSERVABILITY__METRICS__ENABLED=true
GATE_OBSERVABILITY__METRICS__PORT=9090
# Custom servers directory
GATE_SERVERS_DIR=/custom/path/to/servers
server:
host: 0.0.0.0 # Bind address
http_port: 80 # HTTP port
https_port: 443 # HTTPS port
max_connections: 10000 # Max concurrent connections
worker_threads: null # null = auto-detect CPU cores
shutdown_timeout: 30 # Graceful shutdown timeout (seconds)
connection_timeout: 30 # Connection timeout (seconds)
request_timeout: 60 # Request timeout (seconds)
keep_alive_timeout: 75 # Keep-alive timeout (seconds)
tls:
enabled: false # Enable HTTPS
auto_redirect_http: false # Auto-redirect HTTP to HTTPS
cert_path: /path/to/cert.pem # TLS certificate path
key_path: /path/to/key.pem # TLS private key path
min_version: '1.2' # Minimum TLS version (1.0, 1.1, 1.2, 1.3)
max_version: '1.3' # Maximum TLS version
observability:
logging:
level: info # trace, debug, info, warn, error
format: json # json, text
output: stdout # stdout, file
metrics:
enabled: true
endpoint: /metrics
port: 9090 # Optional separate metrics port
tracing:
enabled: false
sampling_rate: 0.1 # 10% of requests
endpoint: http://tempo:4317

Routes available on all virtual hosts:

global_routes:
- path: /_health
handler: health
- path: /coming-soon
handler: coming-soon
- path: /under-maintenance
handler: maintenance

Server configs define per-domain routing, backends, and middleware.

servers/api.surkyl.com.yml:

name: api-service
hosts:
- api.surkyl.com
- apis.surkyl.com
backend:
service_type: proxy
proxy:
servers:
- url: http://localhost:8000
weight: 100
max_requests: 1000
backup: false
- url: http://localhost:8001
weight: 50
max_requests: 500
backup: true
load_balancer:
strategy: round_robin # round_robin, least_connections, ip_hash
sticky_sessions: false
cookie_name: session_id # For sticky sessions
cookie_ttl: 3600 # Cookie TTL in seconds
health_check:
enabled: true
path: /health
interval: 10 # Check interval (seconds)
timeout: 3 # Check timeout (seconds)
healthy_threshold: 2 # Consecutive successes to mark healthy
unhealthy_threshold: 3 # Consecutive failures to mark unhealthy
timeout: 30 # Proxy timeout (seconds)
retry:
attempts: 3
backoff: exponential # fixed, exponential
base_delay: 100 # milliseconds
middleware:
- security-headers
- rate-limit
- cors
routes: []

servers/cdn.surkyl.com.yml:

name: cdn-static
hosts:
- cdn.surkyl.com
backend:
service_type: static
static_files:
root: /var/www/cdn
index: index.html
fallback: 404.html
cache_control: 'public, max-age=31536000, immutable'
spa_mode: false # SPA mode (fallback to index.html)
middleware:
- compress
- cache-headers

servers/redirect.yml:

name: www-redirect
hosts:
- www.surkyl.com
backend:
service_type: redirect
redirect:
target: https://surkyl.com
permanent: true # 301 (permanent) vs 302 (temporary)
preserve_path: true # Preserve request path
preserve_query: true # Preserve query parameters

Define specific routes within a server:

name: app-service
hosts:
- app.surkyl.com
backend:
service_type: proxy
proxy:
servers:
- url: http://localhost:3000
routes:
- path: /api/*
methods: [GET, POST, PUT, DELETE]
backend:
service_type: proxy
proxy:
servers:
- url: http://localhost:8000
middleware:
- auth-required
- rate-limit-api
priority: 100
- path: /static/*
backend:
service_type: static
static_files:
root: /var/www/static
middleware:
- compress
priority: 50
configs/gate/
├── gate.config.yml # Main gate config (dev)
├── gate.config.sample.yml # Sample/template
├── servers/ # Server configurations
│ ├── surkyl.com.yml
│ ├── api.surkyl.com.yml
│ ├── cdn.surkyl.com.yml
│ └── tenants/ # Organized by category
│ ├── tenant1.yml
│ └── tenant2.yml

Gate automatically discovers all *.{yml,yaml,toml,json} files in:

  • {repo_root}/configs/gate/servers/**/*
  • ~/.config/gate/servers/**/*
  • /etc/gate/servers/**/*

You can organize server configs in subdirectories for better management.

Gate prevents conflicts by checking for duplicate hosts across all server configs. If a host is defined multiple times, the first occurrence wins and subsequent ones are skipped with a warning.

Server configurations must include:

  • name: Unique identifier for the server
  • hosts: At least one hostname (non-empty)
Terminal window
# Run with default dev config
nx serve gate
# Override port via environment
GATE_SERVER__HTTP_PORT=8080 nx serve gate
# Use custom config file
GATE_CONFIG_PATH=/path/to/config.yml nx serve gate
~/.config/gate/gate.config.yml
server:
host: 0.0.0.0
http_port: 80
https_port: 443
tls:
enabled: true
auto_redirect_http: true
cert_path: /etc/letsencrypt/live/surkyl.com/fullchain.pem
key_path: /etc/letsencrypt/live/surkyl.com/privkey.pem
observability:
logging:
level: info
format: json
metrics:
enabled: true
tracing:
enabled: true
endpoint: http://tempo:4317
  1. Check file permissions (must be readable)
  2. Verify file format is valid YAML/TOML/JSON
  3. Check logs for config path being used
  4. Use RUST_LOG=gate=debug for detailed logging
  1. Ensure GATE_ prefix is used
  2. Use double underscores (__) for nesting
  3. Check variable name matches config structure
  4. Environment variables override file configs

If you see warnings about duplicate hosts:

  1. Search all server configs for the host
  2. Remove or rename duplicate entries
  3. Consider using separate environments/profiles

Override the default servers directory:

# In gate.config.yml
servers_dir: /custom/path/to/servers

Or via environment:

Terminal window
GATE_SERVERS_DIR=/custom/path/to/servers gate

Gate will support hot-reloading of configuration files without restart (planned feature).

  • Config Crate: config-rs documentation
  • Sample Configs: See gate.config.sample.yml and config.full.sample.yml
  • Code: apps/gate/src/config/

For issues or questions:

  • Check the sample configs in this directory
  • Review the comprehensive config.full.sample.yml
  • File an issue in the repository