Skip to content

Deployment

Janus is designed as a local-first, single-user gateway. This page covers Docker deployment and production-oriented configuration.

Docker

Pull pre-built image

Multi-arch images (amd64 + arm64) are published to GitHub Container Registry:

docker pull ghcr.io/amanverasia/janus:latest
mkdir -p janus-data
janus config-init --path janus-data/config.yaml
# Edit janus-data/config.yaml — add providers, API keys via ${ENV_VAR}

docker compose up -d

The compose file mounts ./janus-data to /home/janus/.janus inside the container. This persists:

  • config.yaml — seed config (loaded once on first startup)
  • janus.db — SQLite database (providers, combos, usage, inventory, etc.)

The image runs the app as user janus (uid 1000). On first docker compose up, Docker may create ./janus-data on the host as root, which blocks SQLite from opening janus.db. The container entrypoint fixes ownership of the mounted data directory on each start (no manual chown needed).

If you still hit permission errors (e.g. host uid is not 1000), fix ownership once:

sudo chown -R 1000:1000 janus-data

Or, without sudo, using a throwaway root container:

docker run --rm -u 0 -v "$(pwd)/janus-data:/data" alpine sh -c 'chown -R 1000:1000 /data'

Environment variables from your host .env file are passed through for ${ENV_VAR} resolution in config:

OPENAI_API_KEY=sk-...
ANTHROPIC_API_KEY=sk-ant-...
GEMINI_API_KEY=...
INVENTORY_ENCRYPTION_KEY=...
INVENTORY_PUSH_TOKEN=...

Build from source

git clone https://github.com/amanverasia/Janus.git
cd Janus
docker compose up -d --build

Default bind address

The Docker image binds to 0.0.0.0:20128 (all interfaces). Enable API key auth when exposing Janus beyond localhost:

server:
  host: 0.0.0.0
  require_api_key: true

Or toggle require_api_key at runtime from the dashboard Settings page.

Remote access

API endpoints

When host: 0.0.0.0, clients connect to http://<host>:20128/v1/.... Require API keys and use TLS termination (reverse proxy) for anything beyond a trusted LAN.

Dashboard authentication

Loopback clients (127.0.0.1, localhost) access the dashboard without auth. Remote clients are redirected to /dashboard/login and must authenticate with a valid Janus API key (sets an httponly cookie). See Dashboard — Authentication.

Reverse proxy

Janus does not terminate TLS itself. Put nginx, Caddy, or Traefik in front:

location / {
    proxy_pass http://127.0.0.1:20128;
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_buffering off;   # important for SSE streaming
}

For streaming (stream: true), disable proxy buffering.

Data backup

Back up the entire data directory:

tar czf janus-backup.tar.gz janus-data/

The SQLite database is the source of truth after first startup. Restoring janus.db restores providers, combos, pricing overrides, usage history, budgets, inventory keys, and cooldown state.

Health check

curl http://localhost:20128/v1/health
# {"status": "ok"}

The root URL / redirects to /dashboard.