Deploy
Deploy
The whole server is one container. Two minutes, no orchestration.
Before you start: the
minmaxkeyDocker image isn't published to a registry yet. Until it is, build it from the repo (docker build -t minmaxkey .) or run bare Python — everything below works exactly the same either way.
Docker
MMK_ADMIN_TOKEN=$(openssl rand -base64 32) # management API key
MMK_ADMIN_PASSWORD=$(openssl rand -base64 16) # dashboard login
MMK_SECRET_KEY=$(openssl rand -base64 32) # session cookie signing
docker run -d -p 8080:8080 \
-v ./data:/data \
-e MMK_ADMIN_TOKEN="$MMK_ADMIN_TOKEN" \
-e MMK_ADMIN_PASSWORD="$MMK_ADMIN_PASSWORD" \
-e MMK_SECRET_KEY="$MMK_SECRET_KEY" \
minmaxkey
curl -s localhost:8080/healthz
# {"status": "ok", "service": "minmaxkey"}
That's it. The dashboard is at http://localhost:8080/admin (login with
MMK_ADMIN_PASSWORD), the API explorer at /docs.
Keep the three secrets somewhere safe — you'll need MMK_ADMIN_TOKEN for the
CLI and webhook automation.
Docker Compose
# docker-compose.yml
services:
minmaxkey:
image: minmaxkey
ports: ["8080:8080"]
environment:
MMK_ADMIN_TOKEN: ${MMK_ADMIN_TOKEN:?set in your shell}
MMK_ADMIN_PASSWORD: ${MMK_ADMIN_PASSWORD:-admin}
MMK_SECRET_KEY: ${MMK_SECRET_KEY:?set in your shell}
volumes:
- ./data:/data
restart: unless-stopped
export MMK_ADMIN_TOKEN=$(openssl rand -base64 32)
export MMK_SECRET_KEY=$(openssl rand -base64 32)
docker compose up -d
Bare Python (no Docker)
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
export MMK_ADMIN_TOKEN=$(openssl rand -base64 32)
export MMK_ADMIN_PASSWORD=$(openssl rand -base64 16)
export MMK_SECRET_KEY=$(openssl rand -base64 32)
uvicorn app.main:app --host 0.0.0.0 --port 8080
Environment variables (the only config there is)
| variable | default | notes |
|---|---|---|
MMK_DATABASE_PATH |
data/mmk.db |
SQLite file location |
MMK_DATABASE_URL |
— | set to use Postgres instead |
MMK_ADMIN_TOKEN |
dev-admin-token |
management API auth — change it |
MMK_ADMIN_PASSWORD |
admin |
dashboard login — change it |
MMK_SECRET_KEY |
change-me |
cookie signing — change it, keep stable |
MMK_COOKIE_SECURE |
false |
true when serving over HTTPS |
MMK_ALLOWED_ORIGINS |
* |
comma-separated CORS allowlist |
Generate secrets: python -c "import secrets; print(secrets.token_urlsafe(32))".
Backups
/data holds the whole database. Copy the file, or point Litestream / restic
/ borg at the directory. That's the entire backup story.
Done? Head to the Dashboard to issue your first license — or skip ahead to the CLI. Deeper ops (Postgres, reverse proxy, upgrades): self-hosting.