Skip to main content

Server configuration

The MiniPAM server reads all of its settings from one YAML file, config.yml, when it starts. Restart the server after you change it.

Where the file lives​

Each install method keeps the file in its own place:

Installed withYour fileHow the server finds it
Dockerminipam-config.ymlMounted over /app/app-server/config.yml in the container.
Sourceapp-server/config.local.ymlPassed with --config config.local.yml.

The server looks for the file in this order:

  1. --config PATH on the command line;
  2. the MINIPAM_CONFIG environment variable;
  3. config.yml next to cli.py.

If you name a file with --config or MINIPAM_CONFIG and it does not exist, the server stops with an error. If you name none and there is no config.yml next to cli.py, the server starts with every setting at its default.

Relative paths inside the file, such as the database location, are resolved from the directory that contains the file.

MiniPAM ignores keys it does not know instead of rejecting them. If a setting seems to have no effect, check its spelling and indentation against the full example.

Settings that can change while MiniPAM runs, such as retention, are not in this file. They are under Administration → System → Settings; see System tools and settings.

Full example​

Every key is optional: a key you leave out takes the value shown here.

The Docker image ships a shorter file. It sets the paths the container needs (the database location to /var/lib/minipam/database.db and frontend-directory to /opt/minipam/ui) and a few keys at their default values. Everything it leaves out takes the default shown here. Copy it out with docker run --rm minipam-server cat config.yml, as in the quick start.

config.yml
# Development aid. Logs SQLite query plans for queries slower than 100 ms. Leave it off in production.
dev-mode: false

server:
# The SQLite file that holds all MiniPAM data. Created on first start and migrated on upgrades.
# A relative path is resolved from the directory of this file. See "Database" below.
database:
location: bin/data/database.db
metrics-retention-days: 120 # days of usage history to keep (1 to 1825); needs a restart

services:
# The single HTTP port that serves the web interface, the REST API, live events, and agents.
# See "Web server" below.
web-api:
enabled: true
listen:
http: 0.0.0.0:8091 # use 127.0.0.1:8091 behind a reverse proxy on the same host
frontend-directory: ../app-ui/dist # not set by default; omit it to serve only the API

# Sign-in and session cookies. See "Authentication" below.
authentication:
# Single-use secret for creating the first admin from the browser. MiniPAM rejects it once the
# first admin exists. Generate one with `openssl rand -hex 32`, then set it back to "".
bootstrap-token: ""
session-duration: 24h # how long a sign-in lasts; accepts h, m, s, and combinations such as 1h30m
session-renewal-interval: 4h # how often an active session is extended
cookie-name: minipam_session
cookie-samesite: lax # the session cookie's SameSite policy
trust-proxy-headers: false # true only when MiniPAM is reachable solely through your proxy

# Where log lines go and how much detail they carry. See "Logging" below.
logging:
# Level per stream: DEBUG, INFO, WARNING, ERROR, or CRITICAL.
streams:
api: { level: INFO } # work done for web and API requests
agent: { level: INFO } # agent connections and their results
background: { level: INFO } # background jobs and schedules
module-levels: {} # level per Python logger, for example { db.sql: DEBUG }
console:
enabled: true # stdout, with WARNING and up on stderr
color: auto # auto, always, or never
files:
enabled: false # also write rotating log files
directory: bin/logs
max-bytes: 10485760 # rotate at 10 MiB
backup-count: 5 # rotated files to keep
exclusions: [] # known noisy messages to drop everywhere
# The in-memory history shown under System → Logs. It keeps DEBUG and above, whatever the levels
# above are, within both limits.
buffer-capacity: 20000
buffer-max-bytes: 67108864 # 64 MiB

# Tuning for the older scored-import suggestions. Leave it at the defaults.
observed-import:
rules-paths: []
min-visible-score: 45
min-default-selected-score: 70
max-iterations: 3

Database​

Put the database on a disk you back up. See Upgrades and backups.

Keep it on a local disk or Docker volume, not a network share (NFS, SMB): SQLite's WAL mode and the migration lock need local file locking. The files database.db-wal and database.db-shm, and the migration lock database.db.migration.lock, are created next to the database, so the folder must be writable.

Web server​

The server speaks plain HTTP. For HTTPS, put a reverse proxy in front of it. There is no CORS setting: serve the interface and the API from the same address, with frontend-directory or through the proxy. Startup fails when frontend-directory is set but has no index.html.

Authentication​

bootstrap-token enables Create initial admin on the login page while no admin exists; see Create the first admin.

trust-proxy-headers trusts X-Forwarded-* headers from a reverse proxy. It is needed behind an HTTPS proxy so client addresses are logged correctly and cookies are marked Secure, which cookie-samesite: none requires. Only turn it on when MiniPAM can be reached only through your proxy. Otherwise anyone can fake those headers.

Logging​

At least one of console or files must be enabled. An exclusion drops matching records from every destination:

server:
logging:
exclusions:
- name: quiet-health-checks
stream: api
level: INFO
module-prefix: uvicorn
message-match: contains # exact, prefix, or contains
message: "GET /health"

To see every SQL statement in System → Logs, set module-levels: { db.sql: DEBUG }. Where the logs are lists the modules worth raising.

Discovery import scoring​

observed-import tunes the older scored-import suggestions. Leave it at its defaults unless you know you need it. The discovery review queue and its rules are configured in the web interface instead; see Review discovered devices.

Run behind a reverse proxy​

Use a reverse proxy for HTTPS. It must pass WebSocket upgrades for agents (/ws/agent) and must not buffer live events (/sse).

With Caddy, which handles certificates and WebSockets for you:

Caddyfile
minipam.example.com {
reverse_proxy 127.0.0.1:8091
}

With Nginx:

server {
listen 443 ssl;
server_name minipam.example.com;
# ssl_certificate and ssl_certificate_key here

location / {
proxy_pass http://127.0.0.1:8091;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_buffering off;
proxy_read_timeout 1h;
}
}

# In the http block:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}

Then set listen.http: 127.0.0.1:8091 and trust-proxy-headers: true, and connect agents with wss://minipam.example.com/ws/agent.

Command line​

Run from the app-server directory. Every command accepts --config PATH; setting MINIPAM_CONFIG instead works too. The file is found as described in Where the file lives.

  • cli.py run: Start the server. The listen address comes from the configuration.
  • cli.py auth set-root --loginname NAME: Create the root admin, or reset its password. Prompts for the password. Renames the root admin if NAME differs from its current login name; without --loginname, the name is root.
  • cli.py auth init-root --api-key-file PATH: For automation: create the root admin (password from MINIPAM_INITIAL_ADMIN_PASSWORD) and an API key, once. Never changes existing credentials.
  • cli.py db status: Show the database version and whether a migration is pending.
  • cli.py db upgrade: Create or migrate the database now, instead of on next start.
  • cli.py db backup-before-migration: Refresh the migration safety copy.
  • cli.py db restore-migration-backup: Restore the safety copy. Stop the server first.
  • cli.py db usage: Show database size by table. Add --json for machine-readable output.
  • cli.py db vacuum: Compact the database and print its size before and after. Best run with the server stopped. See Compact the database.

With the virtual environment from Install from source: ../.venv/bin/python cli.py db status --config config.local.yml. In Docker: docker exec minipam python cli.py db status. The image's file is config.yml next to cli.py, so Docker commands need no --config.