GitHub ↗

Self-Hosting Momo

All guides for running Momo on your own infrastructure.


Quick reference

Minimum setup

git clone https://github.com/jp1337/momo.git && cd momo
cp .env.example .env.local
# Set DATABASE_URL, AUTH_SECRET, and at least one OAuth provider
docker compose up -d

Required environment variables

Variable Description
DATABASE_URL PostgreSQL connection string
AUTH_SECRET Random secret — openssl rand -base64 32
At least one OAuth provider GITHUB_CLIENT_ID + GITHUB_CLIENT_SECRET, or Discord/Google/OIDC

Behind a reverse proxy? Also set AUTH_TRUST_HOST=true.

Full reference → Environment Variables

Enforcing two-factor authentication

If you want to require every user on your instance to set up a second factor (TOTP or Passkey) before they can use Momo:

  1. Generate an encryption key for the TOTP secrets:

    openssl rand -hex 32
    
  2. Add both lines to your .env.local:

    TOTP_ENCRYPTION_KEY=<the 64-character hex string from above>
    REQUIRE_2FA=true
    
  3. Restart Momo (docker compose up -d).

From the next sign-in onwards, every account is sent to a forced setup page (/setup/2fa) until they enroll an authenticator app. Existing users get the same prompt — no migration is needed. The “disable 2FA” button in the user settings is hidden while REQUIRE_2FA=true is set, and removing the last remaining second factor (TOTP secret or last passkey) is blocked server-side.

Heads-up: the forced setup screen currently only walks new users through the TOTP wizard. Once they finish that, they can register passkeys from the regular settings page if they prefer. Method-agnostic enforcement is in place — userHasSecondFactor() accepts either TOTP or any registered passkey — but the forced wizard is TOTP-only by design (to avoid getting stuck if the user’s browser doesn’t support WebAuthn). See Passkeys for the user-facing flow.

⚠️ Plan for recovery first. Once a user has 2FA on, losing both their authenticator app and all their backup codes means they cannot self-recover. You as the operator can clear their 2FA columns directly in the database. The exact SQL is in the technical guide. Make sure your users know to keep backup codes safe before you flip the switch.

⚠️ Treat TOTP_ENCRYPTION_KEY as critical. Rotating it invalidates every existing TOTP secret — every user would need to re-enroll. Back it up alongside your database password.

Full end-user guide → Two-Factor Authentication

Container images

Available on three registries — pick whichever you prefer:

ghcr.io/jp1337/momo:latest
docker.io/kermit1337/momo:latest
quay.io/jp1337/momo:latest