minmaxkey

Deploy

Deploy

The whole server is one container. Two minutes, no orchestration.

Before you start: the minmaxkey Docker 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.