Gateway Deployment

This page covers running the gateway in production: starting with a specific config file, managing the process, verifying health, and deploying via Docker.

Starting the gateway

rivano-gateway start --port 8080 --file /etc/rivano/rivano.yaml
FlagDefaultDescription
--port <port>8080Override the port from the config file
--file <path>./rivano.yamlPath to the config file

The process runs in the foreground. Use a process manager (systemd, PM2, or Docker) to run it as a service.

Stopping the gateway

rivano-gateway stop

This sends SIGTERM to the running gateway process and waits for in-flight requests to drain before shutting down. The PID is read from .rivano-gateway.pid in the current working directory.

Checking status

rivano-gateway status

Output (running):

Gateway status: running
PID:            12345
Port:           8080
Uptime:         2h 14m
Requests:       4,821 (97.8% success)
Provider:       openai (primary)
Cloud sync:     connected

Output (not running):

Gateway status: stopped

Check a specific port:

rivano-gateway status --port 9090

Validate config before starting

Run validation without starting the gateway:

rivano-gateway validate --file /etc/rivano/rivano.yaml
# ✔ rivano.yaml is valid

Returns exit code 1 if the config is invalid. Use this in your deployment pipeline before rolling out a config change.

Health check endpoint

The gateway exposes a health endpoint at GET /health:

curl http://localhost:8080/health

Response (healthy):

{
  "status": "ok",
  "uptime": 8052,
  "provider": "openai",
  "cloudSync": true
}

Response (degraded):

{
  "status": "degraded",
  "uptime": 8052,
  "provider": "openai",
  "cloudSync": false,
  "message": "Control plane unreachable — operating offline with cached policies"
}

The /health endpoint returns 200 OK even when degraded (cloud sync down). It returns 503 Service Unavailable only if the gateway cannot route to any provider.

Response headers

Every response from the gateway includes these headers:

HeaderExampleDescription
X-Rivano-ProvideropenaiProvider that handled the request
X-Rivano-Latency312Total gateway processing time in ms
X-Rivano-Trace-Idtrace_xyz789Trace ID for this request

Use X-Rivano-Trace-Id in your application logs to correlate application errors with Rivano trace data.

Docker deployment

FROM node:20-alpine

RUN npm install -g @rivano/gateway

WORKDIR /app
COPY rivano.yaml ./

EXPOSE 8080

CMD ["rivano-gateway", "start", "--file", "/app/rivano.yaml"]

Build and run:

docker build -t my-rivano-gateway .

docker run -d \
  --name rivano-gateway \
  -p 8080:8080 \
  -e OPENAI_API_KEY=sk-... \
  -e RIVANO_API_KEY=rv_... \
  my-rivano-gateway

Docker Compose example

version: "3.8"

services:
  rivano-gateway:
    image: my-rivano-gateway
    ports:
      - "8080:8080"
    environment:
      OPENAI_API_KEY: ${OPENAI_API_KEY}
      ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY}
      RIVANO_API_KEY: ${RIVANO_API_KEY}
    volumes:
      - ./rivano.yaml:/app/rivano.yaml:ro
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
      interval: 30s
      timeout: 5s
      retries: 3
💡

Pass provider API keys as environment variables and reference them with ${VAR_NAME} in rivano.yaml. This keeps secrets out of your container image and config files.

systemd service

[Unit]
Description=Rivano Gateway
After=network.target

[Service]
Type=simple
User=rivano
WorkingDirectory=/etc/rivano
ExecStart=/usr/local/bin/rivano-gateway start --file /etc/rivano/rivano.yaml
Restart=on-failure
RestartSec=5
EnvironmentFile=/etc/rivano/env

[Install]
WantedBy=multi-user.target