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 with | Your file | How the server finds it |
|---|---|---|
| Docker | minipam-config.yml | Mounted over /app/app-server/config.yml in the container. |
| Source | app-server/config.local.yml | Passed with --config config.local.yml. |
The server looks for the file in this order:
--config PATHon the command line;- the
MINIPAM_CONFIGenvironment variable; config.ymlnext tocli.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.
# 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:
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 ifNAMEdiffers from its current login name; without--loginname, the name isroot.cli.py auth init-root --api-key-file PATH: For automation: create the root admin (password fromMINIPAM_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--jsonfor 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.