# DAO DE JING 部署文档

本文档说明如何在 **Ubuntu 本地** 部署站点，并通过 **NPS TCP 内网穿透** + **云服务器反向代理** 对外提供访问。

---

## 1. 架构说明

```
用户浏览器
    ↓
云服务器（Nginx / 宝塔反代，HTTPS）
    ↓
NPS 服务端（TCP 转发）
    ↓
NPS 客户端（内网 Ubuntu）
    ↓
Express 登录服务（0.0.0.0:12100）
    ↓
VitePress 静态站点（.vitepress/dist）
```

| 组件 | 作用 |
|------|------|
| **VitePress** | 将 Markdown 文档构建为静态 HTML |
| **Express** | 提供登录校验，保护全部页面 |
| **NPS TCP** | 将内网 `12100` 端口映射到公网 |
| **云服务器反代** | 绑定域名、HTTPS（由你自行配置） |

> 登录鉴权在 **本地 Express 层** 完成，不依赖宝塔或 Nginx 的访问限制。

---

## 2. 环境要求

| 项目 | 要求 |
|------|------|
| 操作系统 | Ubuntu 20.04+（或其他 Linux） |
| Node.js | **18.x 或 20.x**（推荐 LTS） |
| npm | 9+ |
| Git LFS | 可选，用于拉取图片资源 |
| 端口 | **12100**（Express 服务端口） |

### 2.1 安装 Node.js（Ubuntu 示例）

```bash
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt-get install -y nodejs
node -v
npm -v
```

### 2.2 安装 Git LFS（可选，建议）

仓库中部分图片使用 Git LFS 存储，部署前建议执行：

```bash
sudo apt-get install -y git-lfs
git lfs install
git lfs pull
```

---

## 3. 获取代码

```bash
git clone https://git.bz121.com/dekun/DAO_DE_JING.git
cd DAO_DE_JING
git lfs pull   # 可选
```

---

## 4. 安装与构建

```bash
npm install
npm run build
```

构建完成后，静态文件输出到 `.vitepress/dist/`。

### 常用命令

| 命令 | 说明 |
|------|------|
| `npm run build` | 仅构建静态站点 |
| `npm run start` | 启动服务（需先 build） |
| `npm run serve` | **构建 + 启动**（推荐一键部署） |
| `npm run docs:dev` | 开发模式，端口 5173，**无登录** |

---

## 5. 登录配置

首次启动时，若不存在 `server/auth.config.json`，会自动从示例文件复制生成。

```bash
cp server/auth.config.example.json server/auth.config.json
```

编辑 `server/auth.config.json`：

```json
{
  "username": "你的用户名",
  "password": "你的强密码",
  "sessionSecret": "随机长字符串，至少32位"
}
```

| 字段 | 说明 |
|------|------|
| `username` | 登录用户名 |
| `password` | 登录密码（明文存储，仅用于本地校验） |
| `sessionSecret` | Session 签名密钥，务必修改为随机字符串 |

> 该文件已加入 `.gitignore`，**不会提交到 Git**。请勿修改 `.env.production`。

修改配置后需重启服务：

```bash
npm run start
```

---

## 6. 启动本地服务

```bash
npm run serve
```

启动成功后输出：

```
DAO DE JING 站点已启动: http://0.0.0.0:12100
登录页: /login
```

### 本地验证

```bash
curl -I http://127.0.0.1:12100/
# 应返回 302，跳转到 /login

curl -I http://127.0.0.1:12100/login
# 应返回 200
```

浏览器访问 `http://<内网IP>:12100/login`，使用配置的账号密码登录。

---

## 7. NPS TCP 内网穿透

在内网 Ubuntu 上运行 NPS 客户端，将本地 **12100** 以 **TCP 模式** 映射到 NPS 服务端。

### 客户端配置示例（nps.conf）

```ini
[common]
server_addr=<NPS服务端IP>
server_port=<NPS服务端端口>
vkey=<你的密钥>

[tcp-12100]
mode=tcp
target_addr=127.0.0.1:12100
server_port=<公网映射端口>
```

映射完成后，云服务器可通过 `127.0.0.1:<公网映射端口>` 访问内网站点。

### 注意事项

- 使用 **TCP 模式**，不要用 HTTP 模式（Express 自行处理 HTTP 与 Session）
- 确保 Ubuntu 防火墙放行出站连接
- 确保 `12100` 端口未被其他程序占用：

```bash
ss -tlnp | grep 12100
```

---

## 8. 云服务器反向代理（参考）

在云服务器（宝塔 / Nginx）上，将域名反代到 NPS 映射端口。**无需在宝塔配置额外登录**。

### Nginx 反代示例

```nginx
server {
    listen 443 ssl http2;
    server_name your-domain.com;

    # ssl_certificate ...;
    # ssl_certificate_key ...;

    location / {
        proxy_pass http://127.0.0.1:<NPS映射端口>;
        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;
    }
}
```

Express 已启用 `trust proxy`，HTTPS 反代后 Session Cookie 可正常工作。

---

## 9. 后台常驻运行（systemd）

创建 systemd 服务，实现开机自启与崩溃重启。

```bash
sudo nano /etc/systemd/system/dao-de-jing.service
```

```ini
[Unit]
Description=DAO DE JING Site
After=network.target

[Service]
Type=simple
User=你的用户名
WorkingDirectory=/path/to/DAO_DE_JING
ExecStart=/usr/bin/npm run start
Restart=on-failure
RestartSec=5
Environment=NODE_ENV=production

[Install]
WantedBy=multi-user.target
```

```bash
# 首次需手动构建
cd /path/to/DAO_DE_JING
npm run build

sudo systemctl daemon-reload
sudo systemctl enable dao-de-jing
sudo systemctl start dao-de-jing
sudo systemctl status dao-de-jing
```

查看日志：

```bash
journalctl -u dao-de-jing -f
```

> `ExecStart` 使用 `npm run start`（仅启动，不重新构建）。更新内容后需手动 `npm run build` 再 `systemctl restart dao-de-jing`。

---

## 10. 更新部署

文档内容有变更时：

```bash
cd DAO_DE_JING
git pull
git lfs pull          # 如有图片更新
npm install           # 依赖有变更时
npm run build
sudo systemctl restart dao-de-jing   # 若使用 systemd
```

或一键：

```bash
npm run serve
```

---

## 11. 目录结构（部署相关）

```
DAO_DE_JING/
├── .vitepress/
│   ├── config.mts          # VitePress 配置
│   ├── dist/               # 构建产物（npm run build 生成）
│   └── public/             # 构建时自动同步 assets/images
├── server/
│   ├── index.js            # Express 服务（端口 12100）
│   ├── auth.config.json    # 登录配置（本地，不提交 Git）
│   ├── auth.config.example.json
│   └── public/login.html   # 登录页
├── scripts/prepare-public.mjs
├── index.md                # 站点首页
├── package.json
└── DEPLOY.md               # 本文档
```

---

## 12. 常见问题

### Q1：启动报错「未找到构建产物 .vitepress/dist」

先执行构建：

```bash
npm run build
```

### Q2：登录后刷新又跳回登录页

- 检查 `sessionSecret` 是否已修改且重启后保持一致
- 反代是否传递了 `X-Forwarded-Proto`（HTTPS 场景）
- 浏览器是否禁用了 Cookie

### Q3：图片不显示

执行 Git LFS 拉取：

```bash
git lfs pull
npm run build
```

部分章节引用的图片若仓库中不存在，页面可正常访问，仅图片为空。

### Q4：端口被占用

```bash
ss -tlnp | grep 12100
# 结束占用进程或修改 server/index.js 中的 PORT 常量
```

### Q5：内网穿透后外网无法访问

1. 确认 Ubuntu 上 `npm run start` 正常运行
2. 确认 NPS 客户端在线，TCP 隧道状态正常
3. 确认云服务器反代指向正确的 NPS 映射端口
4. 确认云服务器安全组 / 防火墙已放行相应端口

---

## 13. 安全建议

1. **立即修改** `server/auth.config.json` 中的默认密码和 `sessionSecret`
2. 不要将 `server/auth.config.json` 提交到 Git 或分享给他人
3. 通过 HTTPS 对外提供服务（在云服务器反代层配置 SSL）
4. 定期更新依赖：`npm update`
5. 限制 NPS 映射端口的访问来源（如云服务器安全组仅允许必要 IP）

---

## 14. 快速部署清单

```bash
# 1. 环境
node -v && npm -v

# 2. 代码
git clone <repo> && cd DAO_DE_JING
git lfs pull

# 3. 依赖与构建
npm install
npm run build

# 4. 登录配置
cp server/auth.config.example.json server/auth.config.json
nano server/auth.config.json

# 5. 启动
npm run start

# 6. 配置 NPS TCP → 12100
# 7. 配置云服务器反代 → NPS 映射端口
# 8. 浏览器访问域名，登录后使用
```
