obsidian/wiki/concepts/npm-sqlite-admin-reset.md
2026-05-09 17:44:30 +01:00

3.8 KiB

title aliases tags sources created updated
Nginx Proxy Manager — Admin Password Reset via SQLite bcrypt Injection
npm-admin-reset
npm-password-reset
npm-sqlite-reset
nginx-proxy-manager
npm
sqlite
homelab
docker
admin
daily/2026-04-29.md
2026-04-29 2026-04-29

Nginx Proxy Manager — Admin Password Reset via SQLite bcrypt Injection

When locked out of Nginx Proxy Manager (NPM), the admin password can be reset by directly modifying the SQLite database. NPM stores user credentials in a database.sqlite file. The process requires stopping NPM first to prevent data corruption, generating a bcrypt hash of the new password, and writing it into the auth table.

Key Points

  • NPM must be stopped before editing the DB — modifying a live SQLite file risks corruption
  • Always back up the database firstcp database.sqlite database.sqlite.bak.YYYY-MM-DD
  • Password is stored as a bcrypt hash in the auth table
  • Restart NPM after the edit — NPM reads credentials from the DB at runtime
  • Default admin email is typically admin@example.com; in this homelab it is admin@ai-impress.com

Details

Step-by-Step Reset Process

# 1. Stop NPM to prevent corruption
docker compose stop npm

# 2. Navigate to the NPM data directory
cd /opt/npm/data

# 3. Back up the database
cp database.sqlite database.sqlite.bak.$(date +%Y-%m-%d)

# 4. Generate a bcrypt hash for the new password
#    Option A: Python
python3 -c "import bcrypt; print(bcrypt.hashpw(b'admin', bcrypt.gensalt(rounds=10)).decode())"

#    Option B: Node.js (if available)
node -e "const bcrypt = require('bcrypt'); bcrypt.hash('admin', 10).then(h => console.log(h))"

#    Option C: use htpasswd
htpasswd -bnBC 10 "" admin | tr -d ':\n'

# 5. Open the database
sqlite3 database.sqlite

# 6. Find the admin user row
SELECT id, name, email FROM user;
-- or, depending on NPM version:
SELECT id, name, email FROM auth;

# 7. Update the password hash
UPDATE auth SET secret = '$2b$10$YOUR_BCRYPT_HASH_HERE' WHERE identity = 'admin@ai-impress.com';
-- or if the table is named 'user':
UPDATE user SET password = '$2b$10$YOUR_BCRYPT_HASH_HERE' WHERE email = 'admin@ai-impress.com';

# 8. Verify
SELECT identity, secret FROM auth;

# 9. Exit and restart NPM
.quit
docker compose start npm

Table Structure Notes

NPM's SQLite schema varies slightly between versions. In most installations:

  • Table auth contains columns: id, identity (email), secret (bcrypt hash), type
  • Table user contains: id, name, email, password

Run .tables and PRAGMA table_info(auth); inside sqlite3 to confirm the structure for your version before updating.

Why NPM Must Be Stopped

SQLite uses file-level locking. NPM holds a write lock on database.sqlite while running. Editing the file while NPM is active can corrupt the WAL (write-ahead log) or leave the DB in an inconsistent state. Always stop the container, edit, then restart.

Homelab Context

This procedure was used when the NPM admin account at admin@ai-impress.com became inaccessible. Password was reset to admin (minimum viable for internal homelab use). NPM fronts all internal services via reverse proxy and SSL termination at /opt/npm/.

Sources