Add initial setup for local HTTPS debugging and Nginx configuration
- Introduce `setup-certs.sh` script for generating trusted local TLS certificates using mkcert. - Add Nginx configuration files for local and Docker environments to handle HTTPS requests and proxy to backend services. - Update `docker-compose.yaml` to include Nginx service for unified TLS entry and adjust frontend service ports for local development. - Create `AGENTS.md` and `README.md` files to document the local HTTPS setup process and usage instructions. - Modify backend startup commands in `README.md` for consistency with new requirements. - Add `.gitignore` to exclude generated certificates from version control.
This commit is contained in:
1
deploy/.gitignore
vendored
Normal file
1
deploy/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
certs/
|
||||
66
deploy/README.md
Normal file
66
deploy/README.md
Normal file
@@ -0,0 +1,66 @@
|
||||
# 本地 / 局域网 HTTPS 调试
|
||||
|
||||
语音预览要求麦克风可用,浏览器只在 **安全上下文**(localhost 或 https)下放行
|
||||
`getUserMedia`。本机用 localhost 就够;**要在局域网用 IP 给别的设备测,就得上 https**。
|
||||
这里用 mkcert 签本地受信任证书 + nginx 反代统一 TLS。
|
||||
|
||||
## 结构
|
||||
|
||||
```
|
||||
浏览器 ──https/wss──> nginx :443 (唯一 TLS 入口, mkcert 证书)
|
||||
├── /ws/ → 后端 :8000 (/ws/voice 信令、/ws/stream 裸流)
|
||||
├── /api/ → 后端 :8000 (assistants/credentials/...)
|
||||
├── /health → 后端 :8000
|
||||
└── / → 前端 :3000 (Next dev + HMR)
|
||||
```
|
||||
|
||||
前端页面和信令 ws 同源(同 host 同端口),没有混合内容 / 跨源问题。
|
||||
|
||||
## 步骤
|
||||
|
||||
```bash
|
||||
# 1) 装 mkcert(只需一次)
|
||||
brew install mkcert nss
|
||||
|
||||
# 2) 生成证书(本机 CA + localhost/LAN IP/ai-video.local 的证书)
|
||||
./deploy/setup-certs.sh
|
||||
|
||||
# 3) 起前后端(任选其一)
|
||||
docker compose up -d # api:8000 + ui:3030 都发布到 localhost
|
||||
# 或本地分别 npm run dev / uvicorn app:app --port 8000
|
||||
|
||||
# 4) 起 nginx(装一下:brew install nginx)
|
||||
nginx -c "$(pwd)/deploy/nginx/ai-video.dev.conf" -g 'daemon off;'
|
||||
|
||||
# 5) 访问
|
||||
# 本机: https://localhost 或 https://ai-video.local
|
||||
# 局域网:https://<本机IP> (脚本结尾会打印)
|
||||
```
|
||||
|
||||
## 前端怎么连后端
|
||||
|
||||
前端读环境变量 `NEXT_PUBLIC_API_BASE_URL`(compose 里已设)。走 nginx 后,
|
||||
让它指向**同源**即可,ws 地址由它推导:
|
||||
|
||||
```
|
||||
NEXT_PUBLIC_API_BASE_URL = https://<访问用的host> # 同源,不再写 :8000
|
||||
wsUrl = NEXT_PUBLIC_API_BASE_URL.replace(/^http/, 'ws') + '/ws/voice'
|
||||
```
|
||||
|
||||
> 没有反代、直连后端时则是 `https://<host>:8000`,但那样要给后端单独配证书、
|
||||
> 还有跨源,不推荐。统一走 nginx 最干净。
|
||||
|
||||
## 给别的设备(手机等)免警告
|
||||
|
||||
证书是 mkcert 本地 CA 签的,只有装了该 CA 的设备才信任:
|
||||
|
||||
```bash
|
||||
mkcert -CAROOT # 打印 CA 目录,里面的 rootCA.pem 拷到设备并信任
|
||||
```
|
||||
|
||||
LAN IP 不在证书 SAN 里会报名称不匹配——`setup-certs.sh` 已自动把探测到的
|
||||
en0/en1 IP 加进 SAN;换网络换了 IP,重跑脚本即可。
|
||||
|
||||
## 证书不入库
|
||||
|
||||
`deploy/.gitignore` 已忽略 `certs/`。私钥不要提交。
|
||||
94
deploy/nginx/ai-video.dev.conf
Normal file
94
deploy/nginx/ai-video.dev.conf
Normal file
@@ -0,0 +1,94 @@
|
||||
# AI Video Assistant —— 本地/局域网开发用 nginx 反代(统一 TLS 入口)
|
||||
#
|
||||
# 作用:浏览器只跟 nginx(:443)打交道,一张 mkcert 证书统管;
|
||||
# 前端(:3000)和后端(:8000)在后面照常跑明文,不用各自配证书。
|
||||
# 前端页面与信令 ws 同源(同 host 同端口),没有混合内容/跨源问题。
|
||||
#
|
||||
# 用法:
|
||||
# 1. ./deploy/setup-certs.sh # mkcert 生成证书到 deploy/certs/
|
||||
# 2. 启动前后端(docker compose → ui:3030;本地裸跑 → ui:3000;后端均 :8000)
|
||||
# 3. nginx -c $(pwd)/deploy/nginx/ai-video.dev.conf -g 'daemon off;'
|
||||
# 4. 浏览器访问 https://<本机IP 或 ai-video.local>
|
||||
#
|
||||
# 注意:证书路径下面写的是绝对路径,换机器/换目录时改 __CERT_DIR__ 两行即可。
|
||||
|
||||
worker_processes 1;
|
||||
events { worker_connections 256; }
|
||||
|
||||
http {
|
||||
# mac/homebrew 的 nginx 默认 mime.types 路径;Linux 一般是 /etc/nginx/mime.types
|
||||
include mime.types;
|
||||
default_type application/octet-stream;
|
||||
sendfile on;
|
||||
|
||||
# 前端上游:优先本地裸跑的 :3000,连不上自动落到 docker ui 发布的 :3030
|
||||
upstream ui_upstream {
|
||||
server 127.0.0.1:3000;
|
||||
server 127.0.0.1:3030 backup;
|
||||
}
|
||||
|
||||
# 80 → 全部跳 443
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name _; # catch-all:任何 host/IP 都匹配,LAN 调试省心
|
||||
|
||||
# __CERT_DIR__ —— mkcert 生成的证书(setup-certs.sh 会放到这里)
|
||||
ssl_certificate /Users/wangx/Code/AI-VideoAssistant-Project/ai-video/deploy/certs/ai-video.pem;
|
||||
ssl_certificate_key /Users/wangx/Code/AI-VideoAssistant-Project/ai-video/deploy/certs/ai-video-key.pem;
|
||||
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_prefer_server_ciphers on;
|
||||
|
||||
# ---- 语音信令 / 裸音频流 ws:/ws/voice、/ws/stream ----
|
||||
# 关键:Upgrade/Connection 头让 ws 握手成功;长超时防止长连接被掐;关缓冲实时透传。
|
||||
location /ws/ {
|
||||
proxy_pass http://127.0.0.1:8000;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
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 https;
|
||||
|
||||
proxy_read_timeout 3600s; # 语音是长连接,默认 60s 会断
|
||||
proxy_send_timeout 3600s;
|
||||
proxy_buffering off; # 流式音频不能攒着
|
||||
}
|
||||
|
||||
# ---- 后端 HTTP 接口:/api/*(assistants/credentials/knowledge-bases)+ /health ----
|
||||
location /api/ {
|
||||
proxy_pass http://127.0.0.1:8000;
|
||||
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 https;
|
||||
client_max_body_size 50M; # 知识库文件上传留余量
|
||||
}
|
||||
|
||||
location /health {
|
||||
proxy_pass http://127.0.0.1:8000;
|
||||
proxy_set_header Host $host;
|
||||
}
|
||||
|
||||
# ---- 前端 Next dev(其余全部)----
|
||||
# Upgrade 头是给 Next 热更新(HMR)的 ws 用的。
|
||||
location / {
|
||||
proxy_pass http://ui_upstream;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
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 https;
|
||||
}
|
||||
}
|
||||
}
|
||||
75
deploy/nginx/ai-video.docker.conf
Normal file
75
deploy/nginx/ai-video.docker.conf
Normal file
@@ -0,0 +1,75 @@
|
||||
# AI Video Assistant —— docker compose 用 nginx 反代(统一 TLS 入口)
|
||||
#
|
||||
# 与 ai-video.dev.conf 的唯一区别:proxy_pass 用 compose 的服务名(api/ui),
|
||||
# 不是 127.0.0.1——容器之间靠 app-network 上的服务名互通。
|
||||
# 证书挂载到容器内 /etc/nginx/certs(见 docker-compose 的 nginx 服务)。
|
||||
#
|
||||
# 这份文件被 nginx:alpine 容器当作 /etc/nginx/nginx.conf 整体加载。
|
||||
|
||||
worker_processes 1;
|
||||
events { worker_connections 256; }
|
||||
|
||||
http {
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
sendfile on;
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name _;
|
||||
|
||||
ssl_certificate /etc/nginx/certs/ai-video.pem;
|
||||
ssl_certificate_key /etc/nginx/certs/ai-video-key.pem;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_prefer_server_ciphers on;
|
||||
|
||||
# 语音信令 / 裸音频流
|
||||
location /ws/ {
|
||||
proxy_pass http://api:8000;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
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 https;
|
||||
proxy_read_timeout 3600s;
|
||||
proxy_send_timeout 3600s;
|
||||
proxy_buffering off;
|
||||
}
|
||||
|
||||
# 后端 HTTP 接口
|
||||
location /api/ {
|
||||
proxy_pass http://api:8000;
|
||||
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 https;
|
||||
client_max_body_size 50M;
|
||||
}
|
||||
|
||||
location /health {
|
||||
proxy_pass http://api:8000;
|
||||
proxy_set_header Host $host;
|
||||
}
|
||||
|
||||
# 前端 Next dev(含 HMR 的 ws)
|
||||
location / {
|
||||
proxy_pass http://ui:3000;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
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 https;
|
||||
}
|
||||
}
|
||||
}
|
||||
53
deploy/setup-certs.sh
Executable file
53
deploy/setup-certs.sh
Executable file
@@ -0,0 +1,53 @@
|
||||
#!/usr/bin/env bash
|
||||
# 用 mkcert 生成本地受信任 TLS 证书,供 deploy/nginx/ai-video.dev.conf 使用。
|
||||
#
|
||||
# mkcert 会建一个"本地 CA"并装进系统/浏览器信任库,之后它签的证书在本机零警告。
|
||||
# 局域网里其它设备(手机/别的电脑)要免警告,需把这个 CA 根证书也装到那台设备上
|
||||
# (见末尾提示)。
|
||||
#
|
||||
# 用法: ./deploy/setup-certs.sh
|
||||
set -euo pipefail
|
||||
|
||||
CERT_DIR="$(cd "$(dirname "$0")" && pwd)/certs"
|
||||
mkdir -p "$CERT_DIR"
|
||||
|
||||
# 1) 确认 mkcert 已安装
|
||||
if ! command -v mkcert >/dev/null 2>&1; then
|
||||
echo "✗ 未找到 mkcert。先安装:"
|
||||
echo " brew install mkcert nss # nss 是给 Firefox 用的"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 2) 安装本地 CA(幂等,已装过会跳过)
|
||||
echo "▶ 安装/确认本地 CA(mkcert -install)…"
|
||||
mkcert -install
|
||||
|
||||
# 3) 探测本机局域网 IP(其它设备靠这个 IP 访问)
|
||||
LAN_IP="$(ipconfig getifaddr en0 2>/dev/null || ipconfig getifaddr en1 2>/dev/null || true)"
|
||||
if [ -z "$LAN_IP" ]; then
|
||||
echo "⚠ 没探测到局域网 IP(en0/en1),证书将只覆盖 localhost。"
|
||||
echo " 如需 LAN 访问,手动重跑:mkcert ... <你的IP>"
|
||||
fi
|
||||
|
||||
# 4) 签证书:覆盖 localhost / 回环 / 局域网 IP / 一个好记的本地域名
|
||||
HOSTS=(localhost 127.0.0.1 ::1 ai-video.local)
|
||||
[ -n "$LAN_IP" ] && HOSTS+=("$LAN_IP")
|
||||
|
||||
echo "▶ 为以下名字签发证书:${HOSTS[*]}"
|
||||
mkcert -cert-file "$CERT_DIR/ai-video.pem" \
|
||||
-key-file "$CERT_DIR/ai-video-key.pem" \
|
||||
"${HOSTS[@]}"
|
||||
|
||||
echo
|
||||
echo "✓ 证书已生成:"
|
||||
echo " $CERT_DIR/ai-video.pem"
|
||||
echo " $CERT_DIR/ai-video-key.pem"
|
||||
echo
|
||||
echo "下一步:"
|
||||
echo " • 本机访问: https://localhost 或 https://ai-video.local"
|
||||
[ -n "$LAN_IP" ] && echo " • 局域网访问:https://$LAN_IP"
|
||||
echo " • 别的设备要免警告,把本地 CA 根证书装到那台设备:"
|
||||
echo " 根证书位置:\$(mkcert -CAROOT)/rootCA.pem → 拷到设备并信任"
|
||||
echo
|
||||
echo " ai-video.local 解析:在 /etc/hosts 加一行(可选)"
|
||||
[ -n "$LAN_IP" ] && echo " $LAN_IP ai-video.local"
|
||||
Reference in New Issue
Block a user