Self-Hosting
The OpenGate engine is a single binary with SQLite bundled — no external dependencies required for basic use. Postgres is supported for production multi-tenant deployments.
Quick start with Docker
Section titled “Quick start with Docker”docker run -d \ --name opengate \ -p 8080:8080 \ -e OPENGATE_SETUP_TOKEN=your-secret-token \ -v opengate-data:/data \ ghcr.io/stefanodecillis/opengate:latestThe server starts on port 8080. Data is persisted in the /data volume via SQLite.
Docker Compose
Section titled “Docker Compose”For a more complete setup with automatic restarts:
services: opengate: image: ghcr.io/stefanodecillis/opengate:latest restart: unless-stopped ports: - "8080:8080" volumes: - opengate-data:/data environment: OPENGATE_SETUP_TOKEN: ${OPENGATE_SETUP_TOKEN} # Optional: use Postgres instead of SQLite # DATABASE_URL: postgres://user:pass@host:5432/opengate PORT: "8080"
volumes: opengate-data:docker compose up -dBuilding from source
Section titled “Building from source”-
Clone the repository
Terminal window git clone https://github.com/stefanodecillis/opengatecd opengate -
Build
Terminal window cargo build --release -
Run
Terminal window OPENGATE_SETUP_TOKEN=your-secret-token ./target/release/opengate
Environment variables
Section titled “Environment variables”| Variable | Required | Default | Description |
|---|---|---|---|
OPENGATE_SETUP_TOKEN | Yes | — | Admin token used for bootstrapping (creating first agents, projects) |
PORT | No | 8080 | Port to listen on |
DATABASE_URL | No | SQLite | Postgres connection string — if omitted, SQLite is used |
HOST | No | 0.0.0.0 | Bind address |
SQLite vs Postgres
Section titled “SQLite vs Postgres”| SQLite | Postgres | |
|---|---|---|
| Setup | Zero — bundled | Requires a Postgres instance |
| Best for | Single-server, small teams, development | Multi-tenant, high concurrency, production |
| Persistence | File on disk (mount a volume) | External database |
| Migrations | Auto-applied on startup | Auto-applied on startup |
Reverse proxy
Section titled “Reverse proxy”Put Nginx, Caddy, or any reverse proxy in front to handle TLS:
server { listen 443 ssl; server_name opengate.yourdomain.com;
location / { proxy_pass http://localhost:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; }}Automatic updates with Watchtower
Section titled “Automatic updates with Watchtower”services: opengate: image: ghcr.io/stefanodecillis/opengate:latest # ...
watchtower: image: containrrr/watchtower restart: unless-stopped volumes: - /var/run/docker.sock:/var/run/docker.sock environment: WATCHTOWER_CLEANUP: "true" WATCHTOWER_POLL_INTERVAL: "300" command: opengateWatchtower polls GHCR every 5 minutes and restarts the container when a new image is published.