# 本地导航站 · 部署与使用说明
本文档为 **中文说明** 与 **部署操作** 合一版本,适用于在局域网或 **外网 HTTPS** 场景下自建使用。
**代码仓库:** https://git.bz121.com/dekun/LocalNav.git
---
## 一、项目概述
**本地导航站**是一个基于 **Flask** 的轻量 Web 应用,用于把多台内网机器、多个带端口的本地服务(宝塔、AI 面板、路由管理页、各类后端控制台等)**收纳到同一个入口地址**。
- 浏览器打开一个网址即可进入。
- 左侧为 **自定义分组 + 服务链接列表**。
- 右侧为 **大尺寸 iframe**:点击左侧链接时,在页面内嵌打开对应 `http://内网IP:端口/路径`,**不整页跳转、不新开标签**(体验类似统一后台)。
数据全部落在本机 **SQLite** 文件中,无需安装 MySQL,适合个人或小范围内网使用。
---
## 二、功能特性
| 模块 | 说明 |
|------|------|
| 账号登录 | 用户名 + 密码,会话由 Flask-Login 管理;表单带 CSRF 防护。 |
| 导航首页 | 左右分栏;左侧分组与服务;右侧 iframe 内嵌打开目标页。 |
| 分组管理 | 新增 / 编辑 / 删除分组;支持排序字段(数字越小越靠前)。 |
| 服务管理 | 新增 / 编辑 / 删除服务;字段:名称、内网主机、端口、路径、所属分组、排序。 |
| 系统设置 | 修改登录密码;数据库一键备份与恢复。 |
| 数据库 | SQLite,默认文件名为 `nav_local.db`(与运行当前工作目录有关)。 |
| 网络监听 | 默认绑定 `0.0.0.0`,便于同局域网手机、电脑访问。 |
**说明**:服务访问地址由程序拼接为 `{scheme}://{host}:{port}{path}`,可在「服务管理」中选择 **HTTP** 或 **HTTPS**。嵌入 iframe 时浏览器仍按混合内容等安全策略校验(例如导航站为 HTTPS、内嵌目标为 HTTP 时可能被浏览器拦截)。
---
## 三、技术栈与运行要求
- **Python**:建议 **3.10+**(3.9 一般也可,未在全部小版本上逐一验证)。
- **主要依赖**:Flask、Flask-SQLAlchemy、Flask-Login、Flask-WTF、WTForms、Werkzeug。
- **浏览器**:现代浏览器(Chrome / Edge / Firefox / Safari 等)。
---
## 四、目录结构(参考)
```
本地导航/
├── app.py # 应用入口、路由、启动参数
├── models.py # 数据模型(用户、分组、服务)
├── forms.py # 表单定义
├── requirements.txt # Python 依赖列表
├── .env.example # 环境变量模板(复制为 .env 后修改)
├── .env # 本地配置(自建,勿提交 Git)
├── ecosystem.config.cjs # PM2 守护进程配置
├── scripts/
│ ├── navctl.py # 交互式部署管理(安装 / 卸载 / 更新)
│ ├── nav_common.py # 部署脚本公共工具
│ ├── install.sh # Linux 入口(支持 curl | bash)
│ ├── install.ps1 # Windows 入口
│ ├── install.py # 兼容:等价 navctl install
│ ├── deploy.py # 项目内安装逻辑(由 navctl 调用)
│ ├── deploy.sh # 项目内更新封装
│ ├── deploy.ps1 # 项目内更新封装
│ └── cleanup_gate_scout.py # 可选:清理旧「Gate 扫单」分组
├── nav_local.db # SQLite 数据库(首次成功运行后生成,勿手误提交到公开仓库)
├── static/
│ └── style.css # 样式
└── templates/ # Jinja2 模板(登录、首页、后台页)
├── base.html
├── login.html
├── index.html
├── admin_groups.html
├── admin_group_form.html
├── admin_services.html
└── admin_service_form.html
└── admin_settings.html
```
---
## 五、一键部署(推荐,无需预先克隆)
运行安装脚本后进入**交互式部署菜单**,无需预先 `git clone`。
### 5.1 启动菜单
```bash
# Linux / macOS(一条命令)
curl -fsSL https://git.bz121.com/dekun/LocalNav/raw/main/scripts/install.sh | bash
# 或
bash scripts/install.sh
python3 scripts/navctl.py
```
**Windows:** `.\scripts\install.ps1`
**菜单:**
| 按键 | 功能 |
|------|------|
| **1** | 一键部署安装:输入仓库地址 → 克隆 → 安装依赖 → 生成 `.env` → 自动 pm2 启动 |
| **2** | 一键卸载:停止 pm2/systemd;可选删除安装目录(含数据库,需二次确认) |
| **3** | 更新:`git pull` + 重新部署 + 自动重启 |
| **0** | 退出 |
安装信息会保存到 `~/.config/localnav/install.json`,下次打开菜单自动识别安装目录与服务状态。
### 5.2 非交互命令
```bash
python3 scripts/navctl.py install -y
python3 scripts/navctl.py install --repo https://git.bz121.com/dekun/LocalNav.git --dir /opt/LocalNav
python3 scripts/navctl.py update --dir /opt/LocalNav
python3 scripts/navctl.py uninstall --dir /opt/LocalNav
```
### 5.3 自动完成的步骤(安装 / 更新)
| 步骤 | 说明 |
|------|------|
| 环境检测 | Python 3.10+、git(必填)、pip |
| 克隆代码 | `git clone` 到指定目录;若目录已是本项目则 `git pull` |
| 虚拟环境 | 创建 `.venv` 并 `pip install -r requirements.txt` |
| 生成 `.env` | 从 `.env.example` 复制(若不存在) |
| `NAV_SECRET_KEY` | 若为空则自动生成 64 位 hex |
| 默认账号 | `NAV_ADMIN_USERNAME=admin`、`NAV_ADMIN_PASSWORD=admin123` |
| 中控自动登录 | 默认 `NAV_HUB_AUTO_LOGIN=1` |
| 内网 Cookie | 默认 `NAV_COOKIES_INSECURE_HTTP=1`(便于 `http://IP:端口` 访问) |
| **自动启动** | 优先 **pm2**;其次 **systemd**;都没有则用 **后台进程**(`logs/nav-site.pid` + `logs/nav-site.log`) |
**注意:** 脚本不会覆盖 `.env` 中已有的 `NAV_SECRET_KEY` 等配置。生产环境部署后请尽快登录并在「系统设置」中修改密码。仅安装不启动可在 `deploy.py` 加 `--no-start`。
### 5.4 已安装后的更新
也可在菜单选 **3**,或:
```bash
cd /opt/LocalNav
python3 scripts/navctl.py update
```
部署完成后启动:
```bash
.venv/bin/python app.py # Linux
# 或
pm2 start ecosystem.config.cjs # 需已安装 PM2
```
---
## 六、环境变量与 `.env` 文件
程序启动时会从 **与 `app.py` 同目录** 的 `.env` 文件加载变量(依赖 `python-dotenv`)。**若 `.env` 不存在则跳过,不影响启动。**
**优先级**:操作系统或进程里 **已经设置** 的环境变量 **优先**;`.env` 中的键 **不会覆盖** 已有变量(与 `python-dotenv` 默认行为一致)。便于在 systemd 里写死 `NAV_SECRET_KEY`,本地开发仍用 `.env` 填其他项。
**初次使用:**
```bash
cp .env.example .env
# 编辑 .env,至少设置 NAV_SECRET_KEY(长期运行强烈建议)
```
`.env` 含敏感信息,已列入 `.gitignore`,请勿提交到公开仓库;仓库内仅保留 **`.env.example`** 作模板。
### 5.1 变量一览
| 变量名 | 含义 | 默认值 |
|--------|------|--------|
| `NAV_SECRET_KEY` | Flask 会话、CSRF 等加密签名密钥。**生产或长期运行务必设置固定值**,否则重启后会话失效且安全性下降。 | 未设置时每次进程启动随机生成 |
| `NAV_DATABASE_URL` | SQLAlchemy 数据库连接串 | `sqlite:///nav_local.db` |
| `NAV_HOST` | `python app.py` 时监听地址 | `0.0.0.0` |
| `NAV_PORT` | `python app.py` 时监听端口 | `5070` |
| `NAV_DEBUG` | 是否开启调试模式(**勿**在内网多人共用服务器上长期开启) | 未设置或不为 `1` 则为关闭;设为 `1` 开启 |
**生成密钥示例(Linux / macOS):**
```bash
export NAV_SECRET_KEY="$(openssl rand -hex 32)"
```
**Windows PowerShell 示例:**
```powershell
$env:NAV_SECRET_KEY = -join ((48..57) + (65..90) + (97..122) | Get-Random -Count 48 | ForEach-Object {[char]$_})
```
---
## 七、安装与运行(通用)
### 6.1 获取代码
**Git 克隆(推荐):**
```bash
git clone https://git.bz121.com/dekun/LocalNav.git
cd LocalNav
```
也可将项目目录放到目标机器上(拷贝、压缩包解压等)。下文以项目根目录为当前工作目录。
### 6.2 创建虚拟环境并安装依赖
**Linux / macOS:**
```bash
cd /path/to/本地导航
python3 -m venv .venv
source .venv/bin/activate
pip install -U pip
pip install -r requirements.txt
```
**Windows(PowerShell):**
```powershell
cd C:\path\to\本地导航
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -U pip
pip install -r requirements.txt
```
**若 `pip install` 报错 “No matching distribution” 或版本列表为空**:多为镜像源未同步或网络策略问题,可显式指定官方索引:
```bash
pip install -r requirements.txt -i https://pypi.org/simple
```
### 6.3 直接启动(开发 / 小范围内网)
若已用 `.env` 配置 `NAV_SECRET_KEY` 等,可直接:
```bash
python app.py
```
否则可临时用环境变量(与 `.env` 二选一或混用,见上文优先级):
```bash
export NAV_SECRET_KEY="$(openssl rand -hex 32)" # Linux;长期部署也可写进 systemd 的 EnvironmentFile
python app.py
```
默认监听 **`http://0.0.0.0:5070`**。在同一局域网内的其他设备浏览器访问:
```text
http://<本机局域网IP>:5070
```
例如:`http://192.168.1.100:5070`。
**注意**:内置的 `app.run()` 为 Flask 开发用服务器,**并发能力与健壮性有限**,适合个人使用或低并发内网场景。需要长期开机、略高并发时,建议使用下文 **Gunicorn** 方式。
---
## 八、首次登录与默认账号
1. 第一次成功启动且数据库中 **没有任何用户** 时,程序会自动创建:
- 用户:**`admin`**
- 密码:**`admin123`**
- 一个名为 **「默认分组」** 的空分组。
2. 控制台会打印一行提示(内容大意:默认账号仅内网使用,请尽快修改)。
3. 一键安装脚本 `scripts/install.py` 会写入相同的默认账号;若 `.env` 中已有 `NAV_ADMIN_USERNAME` / `NAV_ADMIN_PASSWORD` 则以其为准。
**安全建议(强烈)**:
- 首次登录后,请进入顶部 **「系统设置」** 修改密码。
- **不要将**带默认口令的数据库文件提交到公开 Git 仓库。
- 本应用设计为 **内网聚合入口**;若需外网访问,请按 **10.8** 配置 HTTPS 与反向代理,勿将 `5070` 端口裸奔到公网。
---
## 九、使用说明(操作层面)
### 9.1 登录
访问站点根路径,未登录会跳转至 **`/login`**,输入用户名与密码即可。
### 9.2 导航首页(`/`)
- **左侧**:按分组展示服务名称;点击后在 **右侧 iframe** 打开对应地址。
- **顶部**:可进入「分组管理」「服务管理」「系统设置」或退出登录。
- **内嵌页工具栏**:「Gate 登录」「实例免密」「刷新」「强制刷新」「新标签页」。中控嵌入须配置 `NAV_HUB_AUTO_LOGIN=1` 自动代登录(无手动「中控登录」按钮)。
### 9.3 分组管理(`/admin/groups`)
- **新建 / 编辑**:填写分组名称、排序。
- **删除**:会 **同时删除** 该分组下的 **所有服务**(级联删除),请谨慎操作。
- 列表中可从某分组快捷 **「在此分组添加服务」**。
### 9.4 服务管理(`/admin/services`)
- 字段含义简要说明:
- **服务名称**:左侧显示名称。
- **协议**:**HTTP** 或 **HTTPS**;HTTPS 站点选 HTTPS,端口一般填 `443`(或其它 TLS 端口)。
- **主机或域名**:如 `192.168.1.10`、`api.example.com` 等。
- **端口**:1–65535。
- **路径**:可选,须以 `/` 开头;留空则按 `/` 处理。
- **分组**:必选。
- **排序**:同分组内数字越小越靠前。
**HTTPS 服务示例:**
| 字段 | 示例值 |
|------|--------|
| 协议 | HTTPS |
| 主机或域名 | `panel.example.com` |
| 端口 | `443` |
| 路径 | `/` |
生成地址:`https://panel.example.com:443/`
### 9.5 系统设置(`/admin/settings`)
- **修改密码**:输入当前密码与新密码(至少 6 位),保存后立即生效。
- **一键备份**:下载当前 `nav_local.db` 文件(文件名带时间戳)。
- **一键恢复**:上传 `.db` 备份文件覆盖当前库;恢复前会自动在同目录生成 `nav_local.db.bak.时间戳`。**恢复后请重启 LocalNav 服务。**
### 9.6 关于 iframe 打不开的说明
部分网站(尤其银行、部分管理面板)通过 **`X-Frame-Options`** 或 **`Content-Security-Policy`** 禁止被嵌入 iframe,此时右侧区域可能为空白或浏览器控制台报错。这属于 **目标站点安全策略**,与本导航站实现无关。若必须统一入口,只能由目标服务侧放开嵌入策略,或改为新窗口打开(需改代码,非当前默认行为)。
### 9.7 云端「复盘中控」iframe 嵌入(LocalNav + manual_trading_hub)
本地导航(如 `http://192.168.x.x:5070`)嵌入 **云端中控**(`https://你的域名:5100`)时,浏览器会把中控 Cookie 视为**跨站第三方**,直接在 iframe 里登录常会「成功但进不去」。
**本地导航侧(本仓库)**
1. 「服务管理」→ 编辑中控条目 → **嵌入类型** 选 **「复盘中控」**,协议 HTTPS,路径填 `/monitor`。
2. `.env` 配置(与云端中控账号一致):
```env
NAV_HUB_USERNAME=admin
NAV_HUB_PASSWORD=你的中控密码
NAV_HUB_AUTO_LOGIN=1
```
3. 重启 LocalNav。打开中控时会由**本地服务端**自动代登录(`NAV_HUB_AUTO_LOGIN=1`),iframe 再打开 `/embed-auth?token=...` 写入会话。
**云端中控侧(`crypto_monitor/manual_trading_hub`)**
部署最新代码并重启 hub,`.env` 增加:
```env
HUB_ALLOW_PUBLIC=true
HUB_ALLOW_EMBED=true
HUB_EMBED_ORIGINS=http://192.168.8.6:5070
```
将 `192.168.8.6:5070` 换成你本机访问 LocalNav 的完整 Origin(含协议与端口)。多台电脑可逗号分隔。
**四实例(币安/Gate/OKX)**:从中控点「实例 / 策略交易 / 复盘」时,**最新版**会由中控 `postMessage` 通知本地导航,在**同一层 iframe** 打开实例 SSO 链接。工具栏会出现 **「← 中控」** 返回监控区与 **「实例免密」** 按钮;刷新会由本地导航服务端代签新的 SSO 链接(须已配置 `NAV_HUB_USERNAME` / `NAV_HUB_PASSWORD`)。
四实例 `.env` 建议:
```env
APP_COOKIE_SECURE=true
APP_ALLOW_HUB_EMBED=true
HUB_EMBED_PARENT_ORIGINS=https://你的中控域名,http://192.168.x.x:5070
```
(`5070` 换成本地导航实际地址;与中控相同的 `HUB_BRIDGE_TOKEN` 必填。)
### 9.8 Gate 服务 iframe 代登录(手动配置)
本版本**不再自动创建**「Gate 扫单」分组。若需内嵌 Gate 扫描端或执行器,请在 **服务管理** 中手动添加服务,**嵌入类型** 选「Gate 扫描端」或「Gate 执行器」。
`.env` 配置示例:
```env
NAV_GATE_SCOUT_USERNAME=admin
NAV_GATE_SCOUT_PASSWORD=你的 Gate 密码
NAV_GATE_SCOUT_AUTO_LOGIN=1
```
打开对应服务时由本地服务端代登录;未开启自动登录时,可点工具栏 **「Gate 登录」** 手动触发。
**清理旧数据(可选)**:若升级前已有自动种子创建的「Gate 扫单」分组,可执行:
```bash
python scripts/cleanup_gate_scout.py
```
---
## 十、部署指南(以 Ubuntu 为例)
以下假设:系统为 **Ubuntu 20.04/22.04/24.04** 等,项目路径为 **`/opt/LocalNav`**,监听端口 **5070**,进程以 **root** 用户运行;可根据实际域名与端口修改。
### 10.1 系统准备
```bash
sudo apt update
sudo apt install -y python3 python3-venv python3-pip git
```
(若已安装 Python 3、venv 与 git,可跳过。)
### 10.2 一键安装(推荐)
```bash
sudo apt install -y python3 python3-venv python3-pip git # 若 10.1 已装可跳过
curl -fsSL https://git.bz121.com/dekun/LocalNav/raw/main/scripts/install.sh | bash
# 按提示输入仓库地址(直接回车用默认)与安装目录(建议 /opt/LocalNav)
```
或手动执行:
```bash
curl -fsO https://git.bz121.com/dekun/LocalNav/raw/main/scripts/install.py
sudo python3 install.py --repo https://git.bz121.com/dekun/LocalNav.git --dir /opt/LocalNav
```
后续更新代码:
```bash
cd /opt/LocalNav
git pull
python3 scripts/deploy.py
pm2 restart nav-site # 或 systemctl restart nav-site
```
手动克隆安装(旧方式,不推荐)
```bash
sudo mkdir -p /opt
cd /opt
sudo git clone https://git.bz121.com/dekun/LocalNav.git
cd /opt/LocalNav
python3 scripts/deploy.py
```
### 10.3 配置密钥(必做)
```bash
sudo mkdir -p /etc/nav-site
sudo bash -c 'openssl rand -hex 32 > /etc/nav-site/secret_key'
sudo chmod 600 /etc/nav-site/secret_key
```
后续由 systemd 读取该文件并注入 `NAV_SECRET_KEY`(见下节)。
**替代做法**:也可在项目根目录放置 `.env`(建议 `chmod 600 .env`),`WorkingDirectory` 指向项目根时程序会自动加载。若 systemd 的 `Environment` / `EnvironmentFile` 里已设置同名变量,**以 systemd 为准**(`.env` 不会覆盖已有环境变量)。
### 10.4 使用 systemd 常驻运行(推荐)
创建服务文件(仍使用内置 `python app.py` 时示例;若改用 Gunicorn,将 `ExecStart` 改为 gunicorn 命令即可):
```bash
sudo nano /etc/systemd/system/nav-site.service
```
示例内容(**root 运行**):
```ini
[Unit]
Description=Local Nav Flask Site
After=network.target
[Service]
Type=simple
User=root
Group=root
WorkingDirectory=/opt/LocalNav
EnvironmentFile=-/etc/nav-site/env
ExecStart=/opt/LocalNav/.venv/bin/python /opt/LocalNav/app.py
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
```
创建环境文件 `/etc/nav-site/env`(**不要**把密钥写进 Git):
```bash
sudo nano /etc/nav-site/env
```
示例:
```ini
NAV_SECRET_KEY=粘贴openssl_rand_hex32的输出
NAV_HOST=0.0.0.0
NAV_PORT=5070
```
启用并启动:
```bash
sudo systemctl daemon-reload
sudo systemctl enable nav-site
sudo systemctl start nav-site
sudo systemctl status nav-site
```
查看日志:
```bash
journalctl -u nav-site -f
```
### 10.5 防火墙(若启用了 ufw)
```bash
sudo ufw allow 5070/tcp
sudo ufw reload
```
仅内网使用时,也可限制来源网段(示例,请按实际修改):
```bash
sudo ufw allow from 192.168.0.0/16 to any port 5070 proto tcp
```
### 10.6 可选:使用 Gunicorn 提高稳定性
安装:
```bash
source /opt/LocalNav/.venv/bin/activate
pip install gunicorn
```
`WorkingDirectory` 仍为项目根目录,**保证 `nav_local.db` 路径与工作目录一致**。示例 `ExecStart`:
```ini
ExecStart=/opt/LocalNav/.venv/bin/gunicorn -w 2 -b 0.0.0.0:5070 app:app
```
说明:`-w 2` 为 worker 数量,可按机器 CPU 调整;`app:app` 表示 `app.py` 中的全局变量 `app`。
### 10.7 使用 PM2 守护进程(可选)
适合已安装 [PM2](https://pm2.keymetrics.io/) 的环境(常见于用 Node 的服务器上顺带托管 Python 进程)。项目根目录提供 **`ecosystem.config.cjs`**,用虚拟环境里的 Python 直接运行 **`app.py`**(与手动 `python app.py` 一致),**实例数固定为 1**(Flask 内置开发服务器不宜多进程监听同一端口)。
**1. 安装 PM2(若尚未安装,需本机已有 Node.js / npm)**
```bash
sudo npm install -g pm2
```
**2. 准备虚拟环境与依赖(项目根目录)**
```bash
cd /opt/LocalNav # 项目路径
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt -i https://pypi.org/simple
cp -n .env.example .env && nano .env # 至少配置 NAV_SECRET_KEY、NAV_PORT=5070
```
**3. 启动 / 查看 / 维护**
```bash
cd /opt/LocalNav
pm2 start ecosystem.config.cjs
pm2 status
pm2 logs nav-site
```
日志文件默认写入项目下 **`logs/`** 目录(PM2 会自动创建;该目录已加入 `.gitignore`)。
**4. 开机自启(在目标机器上执行一次)**
```bash
pm2 save
pm2 startup
# 按终端里打印的 sudo 命令整行复制执行,再执行一次 pm2 save
```
**5. 常用命令**
| 命令 | 作用 |
|------|------|
| `pm2 restart nav-site` | 热重启(改代码或 .env 后) |
| `pm2 stop nav-site` | 停止 |
| `pm2 delete nav-site` | 从 PM2 列表移除 |
| `pm2 monit` | 简易监控 |
**说明**:若 `interpreter` 指向的 `.venv/bin/python` 不存在,PM2 会启动失败;请确认虚拟环境路径与 `ecosystem.config.cjs` 中一致。Windows 下脚本会自动使用 `.venv\Scripts\python.exe`。
### 10.8 外网 HTTPS 访问(Nginx 反向代理)
若需从 **公网或外网** 通过 **HTTPS** 访问本导航站(浏览器地址栏为 `https://`),建议在 Ubuntu 上用 **Nginx** 终止 TLS,反代到本机 `127.0.0.1:5070`。Flask 仍监听内网端口,不直接暴露 5070 到公网。
**1. 安装 Nginx 与 Certbot(Let's Encrypt 免费证书,需已解析到本机的域名)**
```bash
sudo apt install -y nginx certbot python3-certbot-nginx
```
**2. 调整应用环境变量**
编辑 `/etc/nav-site/env`(或项目根目录 `.env`),增加:
```ini
NAV_TRUST_PROXY=1
NAV_SESSION_COOKIE_SECURE=1
NAV_CSRF_TRUSTED_ORIGINS=https://你的域名
```
保存后重启:`sudo systemctl restart nav-site`
**3. Nginx 站点配置**
将 `nav.example.com` 替换为你的域名:
```bash
sudo nano /etc/nginx/sites-available/localnav
```
```nginx
server {
listen 80;
server_name nav.example.com;
location / {
proxy_pass http://127.0.0.1:5070;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_read_timeout 300s;
}
}
```
启用并重载:
```bash
sudo ln -sf /etc/nginx/sites-available/localnav /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
```
**4. 申请 HTTPS 证书**
```bash
sudo certbot --nginx -d nav.example.com
```
按提示完成验证后,Certbot 会自动配置 `listen 443 ssl` 与证书路径。证书续期一般已由系统定时任务处理,可手动验证:
```bash
sudo certbot renew --dry-run
```
**5. 防火墙**
```bash
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
# 若仅通过 Nginx 对外,可不放行 5070 到公网
sudo ufw reload
```
**6. 访问**
外网浏览器打开:`https://nav.example.com`
**说明:**
- 内嵌 iframe 中的目标服务仍为你在「服务管理」里填写的 `http://内网IP:端口`;外网用户能否打开取决于目标服务是否可从其网络访问,与本导航站 HTTPS 无关。
- 若无公网域名,仅有公网 IP,可改用 **自签证书** 或 **Caddy**(`caddy reverse-proxy --from :443 --to 127.0.0.1:5070`),但浏览器会提示证书不受信任,需自行导入信任。
- 公网暴露登录入口存在安全风险,请务必使用强密码,并考虑 IP 白名单、VPN 或 Nginx `allow/deny` 等额外访问控制。
---
## 十一、数据与备份
- 默认数据库文件:**`nav_local.db`**,位于 **启动进程时的当前工作目录**(与 `WorkingDirectory` 一致)。
- **推荐**:登录后进入 **「系统设置」** → **一键备份** 下载数据库文件。
- **恢复**:在「系统设置」上传 `.db` 文件一键恢复(恢复前会自动生成 `.bak` 备份);**恢复后请重启服务**。
- 也可手动复制 `nav_local.db` 做备份;恢复时替换同名文件后重启服务。
---
## 十二、路由一览(便于排障与二次开发)
| 路径 | 说明 |
|------|------|
| `/` | 导航首页(需登录) |
| `/login` | 登录页 |
| `/logout` | 退出登录 |
| `/admin/groups` | 分组列表 |
| `/admin/groups/new` | 新建分组 |
| `/admin/groups//edit` | 编辑分组 |
| `/admin/groups//delete` | 删除分组(POST) |
| `/admin/services` | 服务列表(支持 `?group_id=` 筛选) |
| `/admin/services/new` | 新建服务 |
| `/admin/services//edit` | 编辑服务 |
| `/admin/services//delete` | 删除服务(POST) |
| `/admin/settings` | 系统设置(改密、备份恢复) |
| `/admin/settings/backup` | 下载数据库备份 |
| `/api/embed/hub-login` | 中控代登录(自动登录用) |
| `/api/embed/gate-scout-login` | Gate 服务代登录 |
| `/api/embed/hub-instance-url` | 实例 SSO 免密签发 |
---
## 十三、常见问题(FAQ)
**Q:手机能打开吗?**
能。只要手机与服务器在同一局域网,且防火墙放行端口,浏览器访问 `http://服务器IP:端口` 即可。
**Q:为什么右侧 iframe 是白的?**
常见原因:目标站禁止被嵌入;目标服务宕机或地址/端口填错;浏览器混合内容策略(本应用为 HTTP 打开链接,若目标强制 HTTPS 且策略严格,可能异常)。可在新标签直接打开同一 URL 对比排查。
**Q:端口想改成其他值?**
设置环境变量 `NAV_PORT=8080`(示例)后重启进程;防火墙与 Nginx `proxy_pass` 端口需一并修改。默认端口为 **5070**。
**Q:忘记密码怎么办?**
登录后进入 **「系统设置」** 修改密码(须记得当前密码)。若完全无法登录,可用 SQLite 工具修改 `users` 表,或删除用户行后重启让程序按 `.env` 重新创建管理员。
**Q:能否从外网访问?**
可以。推荐在 Ubuntu 上用 **Nginx + HTTPS** 反代到 `127.0.0.1:5070`,并配置 `NAV_TRUST_PROXY=1` 等变量,详见 **10.8 外网 HTTPS 访问**。请务必使用强密码并做好访问控制。
---
## 十四、版本与维护
- 依赖版本见 `requirements.txt`;升级依赖前建议在测试环境验证。
- 修改模板或静态文件后,重启进程即可生效;修改 Python 代码同样需要重启(`NAV_DEBUG=1` 时开发服务器可自动重载,但不建议在生产长期开启)。
---
**文档结束。**
**仓库地址:** https://git.bz121.com/dekun/LocalNav.git