Skip to content

Gate Configuration

Complete guide to configuring the Gate API Gateway.

Terminal window
# Development (repository)
cp configs/gate/gate.config.sample.yml configs/gate/gate.config.yml
# Production (user directory)
mkdir -p ~/.config/gate/servers
cp configs/gate/gate.config.sample.yml ~/.config/gate/gate.config.yml
Terminal window
# Open in your editor
vim ~/.config/gate/gate.config.yml
Terminal window
# Development
nx serve gate
# Production
gate

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

Locations (checked in order):

  1. {repository}/configs/gate/gate.config.yml (development)
  2. ~/.config/gate/gate.config.yml (user install)
  3. /etc/gate/gate.config.yml (system-wide)

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

Locations (all loaded):

  1. {repository}/configs/gate/servers/**/*
  2. ~/.config/gate/servers/**/*
  3. /etc/gate/servers/**/*

Note: Gate uses glob patterns to automatically discover all config files in these directories.

All configuration options can be overridden using environment variables with the GATE_ prefix.

  • Prefix: GATE_
  • Nesting: Double underscore __
  • Example: GATE_SERVER__HTTP_PORT=8080
Terminal window
# Server configuration
export GATE_SERVER__HOST="127.0.0.1"
export GATE_SERVER__HTTP_PORT=8080
export GATE_SERVER__HTTPS_PORT=8443
export GATE_SERVER__MAX_CONNECTIONS=5000
export GATE_SERVER__WORKER_THREADS=4
# TLS/HTTPS
export GATE_TLS__ENABLED=true
export GATE_TLS__AUTO_REDIRECT_HTTP=true
export GATE_TLS__CERT_PATH="/etc/letsencrypt/live/example.com/fullchain.pem"
export GATE_TLS__KEY_PATH="/etc/letsencrypt/live/example.com/privkey.pem"
export GATE_TLS__MIN_VERSION="1.2"
export GATE_TLS__MAX_VERSION="1.3"
# Logging
export GATE_OBSERVABILITY__LOGGING__LEVEL="debug"
export GATE_OBSERVABILITY__LOGGING__FORMAT="json"
export GATE_OBSERVABILITY__LOGGING__OUTPUT="stdout"
# Metrics
export GATE_OBSERVABILITY__METRICS__ENABLED=true
export GATE_OBSERVABILITY__METRICS__ENDPOINT="/metrics"
export GATE_OBSERVABILITY__METRICS__PORT=9090
# Tracing
export GATE_OBSERVABILITY__TRACING__ENABLED=true
export GATE_OBSERVABILITY__TRACING__SAMPLING_RATE=0.1
export GATE_OBSERVABILITY__TRACING__ENDPOINT="http://tempo:4317"
# Custom servers directory
export GATE_SERVERS_DIR="/custom/path/to/servers"

Environment variables have the highest priority and will override any file-based configuration.

server:
# Bind address
host: 0.0.0.0
# HTTP port
http_port: 80
# HTTPS port (when TLS is enabled)
https_port: 443
# Maximum concurrent connections
max_connections: 10000
# Worker threads (null = auto-detect CPU cores)
worker_threads: null
# Graceful shutdown timeout (seconds)
shutdown_timeout: 30
# Connection timeout (seconds)
connection_timeout: 30
# Request timeout (seconds)
request_timeout: 60
# Keep-alive timeout (seconds)
keep_alive_timeout: 75
TimeoutDescriptionDefaultWhen to Adjust
connection_timeoutTime to establish connection30sLong-distance clients
request_timeoutTime to complete request60sLong-running APIs
keep_alive_timeoutTime to keep idle connections75sMobile clients
shutdown_timeoutTime for graceful shutdown30sLong requests
# Auto-detect (recommended for most cases)
worker_threads: null
# Fixed number (useful for containerized environments)
worker_threads: 4
# Match CPU cores
worker_threads: 8

When to set manually:

  • Containerized environments with CPU limits
  • Shared hosting with resource constraints
  • Optimizing for specific workloads
tls:
enabled: true
auto_redirect_http: true
cert_path: /etc/letsencrypt/live/example.com/fullchain.pem
key_path: /etc/letsencrypt/live/example.com/privkey.pem
min_version: '1.2'
max_version: '1.3'
Terminal window
# Install certbot
sudo apt-get install certbot
# Obtain certificate
sudo certbot certonly --standalone -d example.com -d www.example.com
# Configure Gate
tls:
enabled: true
auto_redirect_http: true
cert_path: /etc/letsencrypt/live/example.com/fullchain.pem
key_path: /etc/letsencrypt/live/example.com/privkey.pem
Terminal window
# Generate self-signed certificate
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes
tls:
enabled: true
auto_redirect_http: false # Don't force HTTPS in dev
cert_path: ./certs/cert.pem
key_path: ./certs/key.pem
VersionSecurityCompatibilityRecommendation
1.0⚠️ DeprecatedHigh❌ Avoid
1.1⚠️ DeprecatedMedium❌ Avoid
1.2✅ SecureHigh✅ Minimum
1.3✅ Most SecureModern browsers✅ Preferred

Recommended Configuration:

tls:
min_version: '1.2' # Support modern & legacy clients
max_version: '1.3' # Use latest security

High Security:

tls:
min_version: '1.3' # TLS 1.3 only
max_version: '1.3'
observability:
logging:
# Log level: trace, debug, info, warn, error
level: info
# Format: json, text
format: json
# Output: stdout, file
output: stdout

Log Levels:

LevelUse CaseVolume
traceDeep debuggingVery High
debugDevelopmentHigh
infoProductionMedium
warnProduction (quiet)Low
errorProduction (minimal)Very Low

Development:

logging:
level: debug
format: text
output: stdout

Production:

logging:
level: info
format: json
output: stdout

With RUST_LOG:

You can also use the RUST_LOG environment variable for more granular control:

Terminal window
# Gate at debug, everything else at info
RUST_LOG=gate=debug,hypers=debug,tower_http=info
# Specific module debugging
RUST_LOG=gate::config=trace,gate=debug
# Production
RUST_LOG=gate=info,hypers=info,tower_http=warn
observability:
metrics:
enabled: true
endpoint: /metrics
port: 9090 # Optional: separate port for metrics

Accessing Metrics:

Terminal window
# Same port as application
curl http://localhost:80/metrics
# Separate metrics port
curl http://localhost:9090/metrics

Integration with Prometheus:

prometheus.yml
scrape_configs:
- job_name: 'gate'
static_configs:
- targets: ['localhost:9090']
observability:
tracing:
enabled: true
sampling_rate: 0.1 # 10% of requests
endpoint: http://tempo:4317

Sampling Rates:

RateUse CaseOverhead
1.0DevelopmentHigh
0.1Production (10%)Medium
0.01Production (1%)Low

Integration with Grafana Tempo:

tracing:
enabled: true
sampling_rate: 0.1
endpoint: http://tempo:4317

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

~/.config/gate/servers/api.example.com.yml:

name: api-service
hosts:
- api.example.com
- apis.example.com
backend:
service_type: proxy
proxy:
# Backend servers
servers:
- url: http://localhost:8000
weight: 100
max_requests: 1000
backup: false
- url: http://localhost:8001
weight: 100
max_requests: 1000
backup: false
- url: http://localhost:8002
weight: 50
max_requests: 500
backup: true # Only used when others fail
# Load balancing
load_balancer:
strategy: round_robin # round_robin, least_connections, ip_hash
sticky_sessions: false
cookie_name: session_id
cookie_ttl: 3600
# Health checks
health_check:
enabled: true
path: /health
interval: 10 # seconds
timeout: 3 # seconds
healthy_threshold: 2
unhealthy_threshold: 3
# Timeouts and retries
timeout: 30
retry:
attempts: 3
backoff: exponential # fixed, exponential
base_delay: 100 # milliseconds
middleware:
- security-headers
- rate-limit
- cors

~/.config/gate/servers/www.example.com.yml:

name: website
hosts:
- example.com
- www.example.com
backend:
service_type: static
static_files:
root: /var/www/example.com
index: index.html
fallback: 404.html
cache_control: 'public, max-age=3600'
spa_mode: false
middleware:
- compress
- cache-headers
name: spa-app
hosts:
- app.example.com
backend:
service_type: static
static_files:
root: /var/www/app
index: index.html
spa_mode: true # All routes fallback to index.html
cache_control: 'no-cache'
middleware:
- compress

~/.config/gate/servers/redirect.yml:

name: www-redirect
hosts:
- www.example.com
backend:
service_type: redirect
redirect:
target: https://example.com
permanent: true # 301 vs 302
preserve_path: true # example.com/foo → example.com/foo
preserve_query: true # Keep ?param=value

~/.config/gate/servers/app.example.com.yml:

name: app-service
hosts:
- app.example.com
# Default backend (serves SPA)
backend:
service_type: static
static_files:
root: /var/www/app
index: index.html
spa_mode: true
# Route-specific backends
routes:
# API routes → backend service
- path: /api/*
methods: [GET, POST, PUT, DELETE, PATCH]
backend:
service_type: proxy
proxy:
servers:
- url: http://localhost:8000
middleware:
- auth-required
- rate-limit-api
priority: 100
# Static assets → CDN
- path: /static/*
backend:
service_type: static
static_files:
root: /var/www/app/static
cache_control: 'public, max-age=31536000, immutable'
middleware:
- compress
priority: 90
# WebSocket → separate service
- path: /ws/*
backend:
service_type: proxy
proxy:
servers:
- url: http://localhost:9000
priority: 95

Override default server configuration directories:

Via config file:

servers_dir: /custom/path/to/servers

Via environment:

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

Organize server configs in subdirectories:

~/.config/gate/servers/
├── production/
│ ├── api.yml
│ ├── web.yml
│ └── cdn.yml
├── staging/
│ ├── api.yml
│ └── web.yml
└── tenants/
├── customer1.yml
├── customer2.yml
└── customer3.yml

All files are loaded regardless of directory structure.

Development:

Terminal window
# Use repo config
cd /path/to/repo
nx serve gate

Staging:

Terminal window
# Use staging config
export GATE_SERVERS_DIR=~/.config/gate-staging/servers
gate

Production:

Terminal window
# Use production config
gate # Loads from ~/.config/gate/

docker-compose.yml:

version: '3.8'
services:
gate:
image: gate:latest
ports:
- '80:80'
- '443:443'
environment:
- GATE_SERVER__HTTP_PORT=80
- GATE_SERVER__HTTPS_PORT=443
- GATE_TLS__ENABLED=true
- GATE_TLS__CERT_PATH=/certs/fullchain.pem
- GATE_TLS__KEY_PATH=/certs/privkey.pem
- GATE_OBSERVABILITY__LOGGING__LEVEL=info
volumes:
- ./config.yml:/etc/gate/gate.config.yml:ro
- ./servers:/etc/gate/servers:ro
- /etc/letsencrypt:/certs:ro
restart: unless-stopped

ConfigMap:

apiVersion: v1
kind: ConfigMap
metadata:
name: gate-config
data:
gate.config.yml: |
server:
host: 0.0.0.0
http_port: 80
observability:
logging:
level: info
format: json

Deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
name: gate
spec:
replicas: 3
template:
spec:
containers:
- name: gate
image: gate:latest
ports:
- containerPort: 80
env:
- name: GATE_TLS__ENABLED
value: 'true'
- name: GATE_TLS__CERT_PATH
value: /certs/tls.crt
- name: GATE_TLS__KEY_PATH
value: /certs/tls.key
volumeMounts:
- name: config
mountPath: /etc/gate
- name: tls
mountPath: /certs
volumes:
- name: config
configMap:
name: gate-config
- name: tls
secret:
secretName: gate-tls

View what config is being used:

Set log level to debug to see which config files are loaded:

Terminal window
GATE_OBSERVABILITY__LOGGING__LEVEL=debug gate

Output will show:

📋 Loaded config from: "/home/user/.config/gate/gate.config.yml"
🌐 Loading server configs from: "/home/user/.config/gate/servers"
🌐 Loaded 5 server configuration(s)

Validate configuration:

Terminal window
# Check if Gate can load config
gate --help # (future: gate config validate)

High-traffic sites:

server:
max_connections: 50000
worker_threads: 16
keep_alive_timeout: 30

Resource-constrained environments:

server:
max_connections: 1000
worker_threads: 2
keep_alive_timeout: 120

WebSocket-heavy workloads:

server:
keep_alive_timeout: 300 # 5 minutes
request_timeout: 600 # 10 minutes

For issues or questions:

  • Check the README.md
  • Review sample configs in this directory
  • File an issue in the repository