How to Use OmniRoute with Docker: Complete Deployment Guide

Run OmniRoute in a container by mounting a data volume to /data, setting the DATA_DIR environment variable, and exposing port 20128 for the HTTP API and dashboard.

OmniRoute is a self-hosted AI gateway developed by diegosouzapw/OmniRoute that packages cleanly into Docker containers. The repository provides a multi-architecture Dockerfile and compose configurations for both development and production environments, making it simple to deploy on cloud VMs, Raspberry Pi, or Apple Silicon machines.

Quick Start with Docker Run

The fastest way to launch OmniRoute requires no external configuration files. The container expects a host directory mounted at /data to persist the SQLite database and configuration.

docker run -d \
  --name omniroute \
  -p 20128:20128 \
  -v $HOME/.omniroute:/data \
  -e DATA_DIR=/data \
  diegosouzapw/omniroute

This command starts the gateway on localhost:20128, storing state in your home directory so data survives container restarts.

Understanding the OmniRoute Docker Image

The Dockerfile in the repository root builds a minimal production image based on node:24.15.0-trixie-slim. During the build process, the compiled Next.js application and server code are copied into the image, and the entry point is set to the bundled CLI command omniroute serve.

Key characteristics of the image:

  • Multi-architecture support – Built for both amd64 and arm64, ensuring compatibility with x86 servers and ARM devices like Raspberry Pi or Apple Silicon Macs.
  • Minimal footprint – Uses the slim Node.js variant to reduce attack surface and image size.
  • Configurable runtime – Behavior is controlled entirely through environment variables rather than baked-in configuration files.

Docker Compose Deployment Options

For multi-service setups, the repository includes separate compose files located in the project root.

Development Setup

The standard docker-compose.yml defines three services:

  1. omniroute – The main container built from the repository Dockerfile.
  2. redis – Optional caching and WebSocket layer.
  3. caddy – Optional reverse proxy for local TLS termination.

Run the development stack with:

docker compose up -d

The API and dashboard are exposed on localhost:20128 by default.

Production Setup

The docker-compose.prod.yml variant configures separate ports for the dashboard and API, designed for reverse-proxy integration:

  • PROD_DASHBOARD_PORT=20130
  • PROD_API_PORT=20131

Launch the production configuration with:

docker compose -f docker-compose.prod.yml up -d

This exposes the dashboard at http://localhost:20130 and the API at http://localhost:20131, allowing you to place Caddy or another reverse proxy in front for HTTPS termination.

Configuration and Environment Variables

OmniRoute accepts configuration through environment variables at runtime. Critical parameters include:

  • PORT – HTTP/API server port (default: 20128).
  • DATA_DIR – Filesystem path for SQLite state and cache files (default: ~/.omniroute inside the container).
  • OMNIROUTE_BASE_PATH – Sub-path for serving the application behind a reverse proxy (e.g., /gateway).

Supply these variables via the -e flag in docker run or in a .env file referenced by your docker-compose.yml. Never copy a .env file into the image during build; always inject secrets at runtime.

Data Persistence and Volume Management

The container writes persistent state to the path specified by DATA_DIR, which defaults to /data. To prevent data loss when the container restarts, always mount a host directory to this location:

-v /host/path/to/data:/data

This volume stores:

  • The SQLite database file.
  • Cached AI responses and API keys.
  • Persisted configuration changes made through the dashboard.

If running via Docker Compose, the mounted volume ensures the database survives docker compose down operations.

Security Best Practices

According to the docs/guides/DOCKER_GUIDE.md, follow these guidelines for secure deployment:

  • Environment secrets – Pass sensitive values like API keys through environment variables injected at runtime, never committed to the image.
  • Network isolation – Avoid exposing the container directly to the host network unless necessary. Use the LOCAL_HOSTNAMES variable to configure internal DNS for inter-service communication.
  • Port exposure – Limit published ports to only those required (20128 for single-port, or 20130/20131 for split production setups).

Summary

  • Mount a volume to /data and set DATA_DIR=/data to persist the SQLite database across container restarts.
  • Use the base image built from Dockerfile (node:24.15.0-trixie-slim) with entry point omniroute serve.
  • Run quick tests with docker run, but use docker-compose.yml for development and docker-compose.prod.yml for production with separated dashboard/API ports.
  • Configure runtime behavior via PORT, DATA_DIR, and OMNIROUTE_BASE_PATH environment variables.
  • Reference docs/guides/DOCKER_GUIDE.md for detailed environment variable documentation.

Frequently Asked Questions

What is the default port for OmniRoute in Docker?

The default HTTP and API port is 20128, defined by the PORT environment variable. In production compose setups, this splits into separate ports: 20130 for the dashboard and 20131 for the API.

How do I persist data when restarting the OmniRoute container?

Mount a host directory to /data inside the container using the -v flag or a Docker Compose volume, and set the DATA_DIR environment variable to /data. This preserves the SQLite database and configuration files when the container stops or restarts.

Can I run OmniRoute on ARM64 or Apple Silicon?

Yes. The Dockerfile builds multi-architecture images supporting both amd64 and arm64, making OmniRoute compatible with Raspberry Pi devices, Apple Silicon Macs, and standard x86 cloud instances.

How do I secure my OmniRoute deployment?

Never copy a .env file into the Docker image during build. Instead, supply secrets and configuration through runtime environment variables. Use the production compose file with Caddy for TLS termination, and configure LOCAL_HOSTNAMES for secure internal service communication. Avoid publishing ports directly to the host unless specifically required for your architecture.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →