- A+
所属分类:国外VPS
背景
NGINX Proxy Manager(NPM)是个挺方便的反向代理管理工具,跑在 Docker 里。但有个坑——它用 bcrypt 单向哈希存密码,忘了就是忘了,没法找回,只能进数据库硬改。
本教程针对针对 Docker 部署环境
先搞清楚两件事
- 密码不可逆:bcrypt 加密后没法反推,只能重置成新密码
- 密码存在哪:不在 user 表,在 auth 表的 secret 字段里
我的环境
- Ubuntu / Debian
- Docker 部署
- 数据目录:/home/docker/npm/data/
- 数据库文件:/home/docker/npm/data/database.sqlite
你的路径可能不一样,自己调整。
操作步骤
1. 确认数据库位置
ls /home/docker/npm/data/
正常应该能看到这些:
access custom_ssl database.sqlite keys.json letsencrypt-acme-challenge logs nginx
2. 装 sqlite3
宿主机上操作:
apt-get install -y sqlite3
如果宿主机装不了,也可以进容器里弄:
# 找容器名 docker ps | grep nginx-proxy-manager # 进去 docker exec -it <容器名> sh # 容器里直接操作数据库 sqlite3 /data/database.sqlite
3. 看看表结构(可选)
想确认一下的话:
sqlite3 /home/docker/npm/data/database.sqlite
然后执行:
class="language-sql">PRAGMA table_info(auth);
输出大概长这样:
0|id|INTEGER 3|user_id|INTEGER 4|type|varchar(30) 5|secret|varchar(255) <-- 密码 hash 在这里
按 .quit 退出。
4. 装 Python bcrypt 模块
重置密码需要生成新的 bcrypt hash:
apt-get install -y python3-bcrypt
5. 重置密码
下面这行命令直接把密码改成 Abc12345:
python3 -c "
import sqlite3, bcrypt
conn = sqlite3.connect('/home/docker/npm/data/database.sqlite')
h = bcrypt.hashpw(b'Abc12345', bcrypt.gensalt(rounds=10)).decode()
conn.execute(\"UPDATE auth SET secret=? WHERE user_id=1\", (h,))
conn.commit()
conn.close()
print('完成,新密码: Abc12345')
"
解释一下:
user_id=1是默认管理员账号- 改的是 auth 表的 secret 字段
- 用的是宿主机上的数据库文件
6. 重启容器
docker restart <容器名>
7. 登录验证
用新密码登进去,然后立刻去界面里改个更强的密码。
踩坑记录
| 问题 | 原因 | 解决 |
|---|---|---|
| sqlite3: command not found | 没装 sqlite3 | apt-get install -y sqlite3或进容器操作 |
| no such column: password | 字段名不对 | 字段叫 secret,在 auth 表里 |
| No module named 'bcrypt' | 没装 bcrypt | apt-get install -y python3-bcrypt |
| pip3: command not found | 没 pip3 | 直接用 apt 装 python3-bcrypt |
| 改了密码还是登不上 | 容器缓存没刷 | docker restart <容器名> |
安全提醒
- 重置完马上改强密码,至少 8 位,大小写+数字
- 定期备份 database.sqlite
- NPM 管理界面别暴露到公网,内网访问或者加白名单
总结
核心思路很简单:用 Python 的 bcrypt 库生成新密码的 hash,写进 SQLite 的 auth 表,重启容器。全程不用进容器,也不会影响已有的代理配置。




