Deployment
Run the Ingate gateway on your own infrastructure: Docker, Docker Compose, Kubernetes, or a single Go binary.
Overview
Ingate can be self-hosted as a single Go binary or Docker container. It requires PostgreSQL 14+ for log storage, prompts, and evals, and optionally Redis 7+ for rate limiting and the prompt cache. This page covers deploying the gateway itself.
Ingate Cloud
https://api.ingateai.com. See the Quickstart.Docker
Build
docker build -t ingate .Multi-stage build: Go compile, then an Alpine runtime. The final image is ~15MB and runs as the non-root user ingate (UID 1000).
Run
docker run -p 7100:7100 \
-e INGATE_DATABASE_POSTGRESQL_URL=postgres://user:pass@db:5432/ingate \
-e INGATE_DATABASE_REDIS_URL=redis://cache:6379 \
ingateDocker Compose (Full Stack)
docker compose upStarts Ingate + PostgreSQL + Redis with health-check dependencies.
Configuration in Containers
Use environment variables, which take precedence over config files:
# Server
INGATE_SERVER_PORT=7100
INGATE_SERVER_CORS_ORIGINS=https://app.example.com
INGATE_SERVER_ADMIN_AUTH=true
# Providers
INGATE_PROVIDERS_OPENAI_API_KEY=sk-...
INGATE_PROVIDERS_OPENAI_ENABLED=true
# Database
INGATE_DATABASE_POSTGRESQL_URL=postgres://...
INGATE_DATABASE_REDIS_URL=redis://...
# Auth
INGATE_AUTH_ENABLED=trueOr mount a config file:
docker run -v /path/to/ingate.yaml:/home/ingate/ingate.yaml ingateSee Configuration for the full option reference and env var mapping.
Database Migrations
Migrations are embedded in the binary and run automatically on startup. No external migration tool needed.
The tracking table schema_migrations prevents re-running applied migrations. This is safe for rolling deployments: multiple instances starting simultaneously will not conflict.
Multi-Instance Deployment
Ingate supports running multiple instances behind a load balancer.
What works automatically:
- Proxy routing (stateless)
- Logging pipeline (each instance writes to the same PostgreSQL)
- API endpoints (stateless, query the same database)
Background workers use distributed locks:
- Eval scheduler: PostgreSQL advisory lock
eval-scheduler - Retention worker: PostgreSQL advisory lock
retention-worker
Only one instance runs each background job at a time. Others skip silently.
Health Checks
GET /healthzReturns 200 when healthy, 503 when degraded. Includes per-component status.
Kubernetes Probes
livenessProbe:
httpGet:
path: /healthz
port: 7100
initialDelaySeconds: 5
periodSeconds: 15
readinessProbe:
httpGet:
path: /healthz
port: 7100
initialDelaySeconds: 3
periodSeconds: 10Managed Databases
PostgreSQL
The pgx driver supports all connection string parameters:
postgres://user:pass@host:5432/db?sslmode=require&sslrootcert=/path/to/ca.pem| Parameter | Example | Description |
|---|---|---|
sslmode | require, verify-full | SSL mode |
sslrootcert | /path/to/ca.pem | CA certificate for verification |
sslcert | /path/to/client.pem | Client certificate (mTLS) |
sslkey | /path/to/client.key | Client key (mTLS) |
Redis
redis://[:password@]host:6379[/db]
rediss://[:password@]host:6380[/db] # TLSThe rediss:// scheme enables TLS automatically.
Graceful Shutdown
On SIGTERM or SIGINT, Ingate shuts down in order:
- Stop accepting new HTTP connections (30s drain timeout)
- Drain eval pipeline (process buffered tasks)
- Drain logging pipeline (flush to PostgreSQL)
- Close database connections
Container orchestrators should set terminationGracePeriodSeconds: 45 to allow a full drain.
Resource Requirements
| Profile | CPU / RAM | PostgreSQL | Redis |
|---|---|---|---|
| Minimal (development) | 1 CPU, 256MB RAM | Shared instance | Optional |
| Production (per instance) | 2 CPU, 512MB RAM | Dedicated or managed (10+ connections) | Shared or managed (rate limiting + cache) |
Ingate's memory footprint scales with:
- Logging pipeline buffer (
logging.buffer_size× ~2KB per entry) - Eval pipeline buffer (256 × ~1KB per task)
- Active concurrent proxy connections