## 架构概览
```
域名 example.xyz
→ Apache (服务器 :80)
→ frps (服务器 :8080, vhost_http_port)
→ frpc 隧道 (端口 7000)
→ 本地服务 (多端口)
```
## 涉及的文件
| 位置 | 文件 | 作用 |
|------|------|------|
| 本地 | `/opt/frp_0.69.1_linux_amd64/frpc.toml` | frp 客户端,注册代理 |
| 本地 | `/home/user/.config/systemd/user/frpc.service` | frpc 的 systemd 服务 |
| 服务器 | `/opt/frp/frps.toml` | frp 服务端,含 `vhost_http_port = 8080` |
| 服务器 | `/etc/apache2/sites-enabled/000-default.conf` | Apache 转发请求到 frps |
| 本地项目 | `/opt/electrical/next.config.ts` | Next.js 的 `basePath` 配置 |
## 当前代理配置 (frpc.toml)
```toml
[common]
server_addr = xxx.xxx.xxx.xxx
server_port = 7000
auth.token = secure-token-example
tls.enable = true
[opengrok-web]
type = http
local_port = 8090
custom_domains = example.xyz
locations = /opengrok
[elec-web]
type = http
local_port = 3000
custom_domains = example.xyz
locations = /elec
```
## 当前 Apache 配置 (服务器)
```apache
ProxyPass /opengrok http://127.0.0.1:8080/opengrok
ProxyPassReverse /opengrok http://127.0.0.1:8080/opengrok
ProxyPass /elec http://127.0.0.1:8080/elec
ProxyPassReverse /elec http://127.0.0.1:8080/elec
```
## 添加新子地址的步骤
假设新增 `/foo` 指向本地端口 `5000`:
### 1. 本地 frpc.toml 添加代理
```toml
[foo-web]
type = http
local_port = 5000
custom_domains = example.xyz
locations = /foo
```
### 2. 服务器 Apache 添加转发
```apache
ProxyPass /foo http://127.0.0.1:8080/foo
ProxyPassReverse /foo http://127.0.0.1:8080/foo
```
### 3. 重启服务
```bash
# 本地
systemctl --user restart frpc
# 服务器
systemctl reload apache2
```
### 4. 如果是 Next.js 项目,需设 basePath
```ts
// next.config.ts
const nextConfig: NextConfig = {
basePath: "/foo",
// ...
};
```
然后重新构建:`npx next build && npx next start -p 5000`
## 关键注意事项
- **同一域名必须用 `locations` 区分**:两个 HTTP 代理不能在相同 `custom_domains` 下都没有 `locations`,会报 `router config conflict`
- **不用引号**:frp 0.69.1 解析 TOML 有兼容问题,值不加引号更稳定
- **不要用 `[[proxies]]` 数组格式**:本版本不支持,代理名会被错误解析
- **Next.js 必须 `basePath`**:否则 CSS/JS 路径 `/_next/...` 无法通过 frp 路由正确加载