Files
jarvis-selfhost/.env.example
T
2026-08-21 15:54:16 +02:00

157 lines
8.4 KiB
Bash

# Jarvis — configuration. Copy to `.env` beside the compose file and fill in.
#
# cp .env.example .env
#
# Nothing here has a safe placeholder value: the four secrets must be generated, and the two URLs
# must be yours. The compose file refuses to start rather than booting with something wrong.
# ---------------------------------------------------------------------------
# Where your instance lives
# ---------------------------------------------------------------------------
# The address a browser reaches Jarvis on, scheme included and no trailing slash.
#
# This is the CORS decision. It accepts exactly ONE origin — not a list — and every request from
# anywhere else is refused, which presents as a sign-in page that cannot sign in.
WEB_ORIGIN=https://jarvis.example.com
# The address enrolled machines dial. Defaults to WEB_ORIGIN, which is right for a single-origin
# deployment. Set it separately only if the app and the API answer on different hostnames.
#PUBLIC_URL=https://jarvis.example.com
# Host port the web container publishes. Put your TLS terminator in front of it.
JARVIS_PORT=8080
# How many proxies rewrite X-Forwarded-For before a request reaches the API.
#
# One is the web container's own nginx, which is always there. So: 1 if nothing else fronts it, 2 if
# your own reverse proxy does — which is the usual case and the default. Raising it is the dangerous
# direction, because the API then trusts that many hops of a header the client can forge, and a caller
# can choose the address that lands in the audit log and in the session list.
TRUST_PROXY_HOPS=2
# ---------------------------------------------------------------------------
# Secrets — generate every one of these, never copy them from anywhere
# ---------------------------------------------------------------------------
# Postgres. Only ever used inside the compose network.
# openssl rand -base64 24
POSTGRES_PASSWORD=
# Session signing. Two different values, at least 16 characters each.
# openssl rand -base64 48
JWT_ACCESS_SECRET=
JWT_REFRESH_SECRET=
# THE ONE YOU CANNOT LOSE.
#
# Must decode to exactly 32 bytes:
# openssl rand -base64 32
#
# Every credential in the vault — SSH keys, API secrets, Microsoft 365 client secrets — is encrypted
# under this key with AES-256-GCM, and so is everything Jarvis seals OUTSIDE the vault: the Microsoft
# Graph client secret it sends its own mail with, this instance's licence identity key, every
# authenticator-app secret, and every terminal recording. It is not stored anywhere but here.
#
# Change it or lose it and none of that data can be read again, by you or by anyone. A database backup
# does not save you: the backup holds the ciphertext. Back this value up separately from the database,
# somewhere you would still have it if this host were gone. An instance whose key has changed keeps
# LOOKING configured — the rows are all there — and fails on every reveal.
VAULT_MASTER_KEY=
# ---------------------------------------------------------------------------
# The model
# ---------------------------------------------------------------------------
# Any OpenAI-compatible endpoint: OpenAI, a self-hosted gateway, a local server.
#OPENAI_BASE_URL=https://api.openai.com/v1
# Required. Jarvis will not start without it.
OPENAI_API_KEY=
# Must be a model your endpoint actually serves, and it should be a good one — this model is deciding
# what to run on production infrastructure.
#OPENAI_MODEL=gpt-4o
# minimal | low | medium | high. Higher costs latency and tokens and is worth it for real work.
#OPENAI_THINKING_LEVEL=medium
# ---------------------------------------------------------------------------
# Channels and pinning (optional, recommended in production)
# ---------------------------------------------------------------------------
# Every image tracks the `stable` channel unless you set these, so `docker compose pull && up -d`
# upgrades you to whatever has most recently been promoted. `stable` moves only after a build has
# run on the publisher's own instance; `dev` moves on every build and nothing has tried it yet.
# `latest` is a second name for `stable`, kept so nothing that already used it has to change.
#
# Which channel you are on is yours to state, because nothing in the image knows it — a channel is
# decided after a build and moves afterwards. Set it and the app shows it beside the version
# numbers; leave it empty if you pin below, because then you follow no channel.
#JARVIS_CHANNEL=stable
# Pinning makes an upgrade a decision instead of a side effect of pulling. The app reports its real
# version either way — a channel tag is a second name on the same image, not a build that forgot
# its number.
#
# THERE IS NO EXAMPLE NUMBER HERE ON PURPOSE. Pin the version you are ALREADY RUNNING, which the app
# footer shows as `web … · api …`. Nothing in the publishing path bumps a number written into this
# file, so any number printed here is one that went stale while nobody was looking — and moving the
# api pin BACKWARDS runs an old build against a schema that has already been migrated forward.
#JARVIS_IMAGE_API=git.luxit.be/luxit/jarvis-api:<the api version in your footer>
#JARVIS_IMAGE_WEB=git.luxit.be/luxit/jarvis-web:<the web version in your footer>
# Only read when the agent overlay is enabled, just below. Its version is the AGENT's, and moves
# independently of the two above — a Jarvis release usually does not change the agent at all.
#
# PIN THIS ONE FIRST if you pin only one. The two above change what your own server runs; this one
# changes what runs on every machine you administer. Pinning it decides which build your instance
# publishes; a separate UPDATE POLICY decides when a machine takes it, and its default is "let the
# agent decide" — which in practice means the next time its service starts. Set that policy
# instance-wide under Settings → Platform → General, per organization under Settings → Organization →
# Agent updates. An enrolled agent also refuses any version that is not strictly newer, so moving
# this back stops a rollout rather than reversing it on machines that already took the update.
#
# The app footer does not carry this number. Each enrolled machine reports the build it runs, on the
# Agents page — that is the one to pin.
#JARVIS_IMAGE_AGENT=git.luxit.be/luxit/jarvis-agent-dist:<version>
# ---------------------------------------------------------------------------
# The Jarvis agent (optional)
# ---------------------------------------------------------------------------
# Enrolling a machine downloads a compiled binary, which the api serves from a directory it can
# only read. `docker-compose.agent.yml` supplies that directory as a pullable image, so the release
# arrives the same way the rest of the stack does. Uncomment this and every later `docker compose`
# command picks up both files with no extra flags:
#
#COMPOSE_FILE=docker-compose.yml:docker-compose.agent.yml
#
# Leaving it off is a supported state, not a broken one: everything except the agent works, and the
# installer answers 503 saying no build is published. The SSH, Proxmox, Microsoft 365 and MikroTik
# connectors all reach machines without it.
#
# AGENT_RELEASE_DIR is set by that overlay and should NOT be set here — a value in this file would
# point the api at a path nothing populates, turning the honest 503 into a 404 per platform.
#AGENT_HEARTBEAT_INTERVAL_SEC=30
#RUN_SHUTDOWN_GRACE_SEC=25
# ---------------------------------------------------------------------------
# Licence (optional — without one you get the community edition)
# ---------------------------------------------------------------------------
# Leave this empty and the instance runs the COMMUNITY EDITION: 1 organization, 3 users, 5 agents,
# 10 assets, no expiry, nothing to renew, and nothing reported to anybody. Every feature works inside
# those numbers. A full limit refuses the NEXT thing of that kind and touches nothing already there.
#
# A key raises the limits — ask antoine@luxit.be for one. It is verified offline, on this machine. A
# licensed instance then reports counts and its own address to your provider; the README lists every
# field it sends. A key that expires or is withdrawn drops back to the allowances above, never to
# nothing.
#
# This value SEEDS the database on first boot and does not govern it afterwards: a renewal arrives
# through the check-in and is stored, so leaving an old key here cannot roll you back. To replace a
# key, use Settings → Licence.
#JARVIS_LICENSE_KEY=