Add HTTPS reverse proxy guide and PNG icons for real PWA install.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -140,6 +140,53 @@ SKIP_PYTORCH=1 bash deploy.sh deps
|
|||||||
|
|
||||||
下载过程中出现 `Retrying... Read timed out` 属于正常重试,**并非卡死**,请耐心等待 10-30 分钟。
|
下载过程中出现 `Retrying... Read timed out` 属于正常重试,**并非卡死**,请耐心等待 10-30 分钟。
|
||||||
|
|
||||||
|
### 0.7 PWA 安装 App 与 HTTPS 反向代理
|
||||||
|
|
||||||
|
| 访问方式 | 浏览器行为 |
|
||||||
|
|----------|------------|
|
||||||
|
| `http://IP:5683` | 只能「快捷方式 / 添加到主屏幕」,**不能**系统级一键安装 |
|
||||||
|
| `https://IP` 或 `https://域名` | Chrome/Edge 可弹出 **「安装 Trading Studio」**,独立窗口运行 |
|
||||||
|
|
||||||
|
**原因:** PWA 规范要求 **HTTPS 安全上下文**(`localhost` 除外)。局域网直连 HTTP 是正常现象,不是代码 bug。
|
||||||
|
|
||||||
|
#### 推荐方案:Nginx + 自签证书(纯局域网)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /opt/Trading_Studio
|
||||||
|
bash server-update.sh # 或 git pull
|
||||||
|
|
||||||
|
# 1. 安装 Nginx
|
||||||
|
sudo apt install -y nginx
|
||||||
|
|
||||||
|
# 2. 生成自签 SSL(替换为你的服务器局域网 IP)
|
||||||
|
sudo bash scripts/gen_ssl_cert.sh 192.168.8.100
|
||||||
|
|
||||||
|
# 3. 启用站点配置
|
||||||
|
sudo cp nginx/trading_studio.conf /etc/nginx/sites-available/trading_studio.conf
|
||||||
|
sudo ln -sf /etc/nginx/sites-available/trading_studio.conf /etc/nginx/sites-enabled/
|
||||||
|
sudo nginx -t && sudo systemctl reload nginx
|
||||||
|
|
||||||
|
# 4. 确保 Gradio 仍由 PM2 监听 127.0.0.1:5683(仅本机),外网只走 443
|
||||||
|
pm2 restart trading_studio
|
||||||
|
```
|
||||||
|
|
||||||
|
**访问:** `https://192.168.8.100`(首次需在手机/平板点「高级 → 继续访问」信任证书)
|
||||||
|
|
||||||
|
**安装 App:**
|
||||||
|
- 电脑 Chrome:地址栏出现 ⊕ 安装图标,或点页面「安装 App」按钮
|
||||||
|
- 安卓 Chrome:菜单 → 安装应用
|
||||||
|
- iPad/iPhone Safari:分享 → 添加到主屏幕(iOS 无系统安装弹窗,但 HTTPS 下体验更完整)
|
||||||
|
|
||||||
|
#### 有公网域名时
|
||||||
|
|
||||||
|
在 Nginx 前加 [Let's Encrypt](https://letsencrypt.org/) 免费证书(`certbot`),可免信任自签证书步骤。
|
||||||
|
|
||||||
|
#### 无反向代理时的替代
|
||||||
|
|
||||||
|
HTTP 下点击「安装 App」会显示手动引导;桌面快捷方式仍可用,功能不受影响。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
### 0.5 PM2 运维(root 环境)
|
### 0.5 PM2 运维(root 环境)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
@@ -232,15 +232,25 @@ PWA_HEAD = """
|
|||||||
document.body.appendChild(overlay);
|
document.body.appendChild(overlay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isSecure() {
|
||||||
|
return location.protocol === "https:" || location.hostname === "localhost" || location.hostname === "127.0.0.1";
|
||||||
|
}
|
||||||
|
|
||||||
function manualInstallGuide() {
|
function manualInstallGuide() {
|
||||||
|
var httpWarn = "";
|
||||||
|
if (!isSecure()) {
|
||||||
|
httpWarn = "<div class='pwa-modal-warn'><strong>⚠️ 当前为 HTTP 访问</strong><br>浏览器只能创建<strong>快捷方式</strong>,无法弹出系统级「安装 App」。<br>要一键安装,请配置 <strong>HTTPS 反向代理</strong>(见服务器 DEPLOY.md)。</div>";
|
||||||
|
}
|
||||||
var steps = isIOS()
|
var steps = isIOS()
|
||||||
? "<ol><li>点击 Safari 底部分享按钮 <strong>□↑</strong></li><li>选择 <strong>「添加到主屏幕」</strong></li><li>点击 <strong>添加</strong> 即可</li></ol>"
|
? "<ol><li>点击 Safari 底部分享按钮 <strong>□↑</strong></li><li>选择 <strong>「添加到主屏幕」</strong></li><li>点击 <strong>添加</strong></li></ol>"
|
||||||
: "<ol><li>点击浏览器右上角 <strong>⋮</strong> 菜单</li><li>选择 <strong>「安装应用」</strong> 或 <strong>「添加到主屏幕」</strong></li><li>确认安装即可</li></ol>";
|
: (isSecure()
|
||||||
|
? "<ol><li>Chrome/Edge 地址栏点击 <strong>安装</strong> 图标</li><li>或菜单 → <strong>安装 Trading Studio</strong></li></ol>"
|
||||||
|
: "<ol><li>Chrome 菜单 → <strong>添加到主屏幕</strong> 或 <strong>创建快捷方式</strong></li><li>配置 HTTPS 后可真正「安装应用」</li></ol>");
|
||||||
showModal(
|
showModal(
|
||||||
'<button class="pwa-modal-close" type="button">✕</button>' +
|
'<button class="pwa-modal-close" type="button">✕</button>' +
|
||||||
'<h3>📲 安装 Trading Studio</h3>' +
|
'<h3>📲 安装 Trading Studio</h3>' + httpWarn +
|
||||||
'<p>当前环境需手动安装,按以下步骤操作:</p>' + steps +
|
'<p>按以下步骤操作:</p>' + steps +
|
||||||
'<p class="pwa-modal-tip">安装后可像原生 App 一样从桌面/icon 启动。</p>'
|
'<p class="pwa-modal-tip">HTTPS 安装后可独立窗口运行,体验接近原生 App。</p>'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -583,6 +593,16 @@ gradio-app,
|
|||||||
.pwa-modal p { color: #cbd5e1 !important; line-height: 1.6 !important; }
|
.pwa-modal p { color: #cbd5e1 !important; line-height: 1.6 !important; }
|
||||||
.pwa-modal ol { color: #e2e8f0 !important; padding-left: 20px !important; line-height: 1.8 !important; }
|
.pwa-modal ol { color: #e2e8f0 !important; padding-left: 20px !important; line-height: 1.8 !important; }
|
||||||
.pwa-modal-tip { font-size: 0.85rem !important; color: #93c5fd !important; margin-top: 16px !important; }
|
.pwa-modal-tip { font-size: 0.85rem !important; color: #93c5fd !important; margin-top: 16px !important; }
|
||||||
|
.pwa-modal-warn {
|
||||||
|
background: #422006 !important;
|
||||||
|
border: 1px solid #f59e0b !important;
|
||||||
|
border-radius: 8px !important;
|
||||||
|
padding: 12px 14px !important;
|
||||||
|
margin-bottom: 14px !important;
|
||||||
|
color: #fde68a !important;
|
||||||
|
font-size: 0.9rem !important;
|
||||||
|
line-height: 1.6 !important;
|
||||||
|
}
|
||||||
.pwa-modal-close {
|
.pwa-modal-close {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 12px;
|
top: 12px;
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
# Trading Studio — Nginx HTTPS 反向代理
|
||||||
|
# 将 https://你的域名或IP 转发到本机 Gradio 5683
|
||||||
|
#
|
||||||
|
# 安装步骤见 DEPLOY.md「PWA 安装与 HTTPS」
|
||||||
|
|
||||||
|
# HTTP 自动跳转 HTTPS(可选,不需要可删除此 server 块)
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
listen [::]:80;
|
||||||
|
server_name trading.local _;
|
||||||
|
|
||||||
|
return 301 https://$host$request_uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 443 ssl http2;
|
||||||
|
listen [::]:443 ssl http2;
|
||||||
|
server_name trading.local _;
|
||||||
|
|
||||||
|
# 自签证书路径(先用 scripts/gen_ssl_cert.sh 生成)
|
||||||
|
ssl_certificate /etc/nginx/ssl/trading_studio.crt;
|
||||||
|
ssl_certificate_key /etc/nginx/ssl/trading_studio.key;
|
||||||
|
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_ciphers HIGH:!aNULL:!MD5;
|
||||||
|
|
||||||
|
client_max_body_size 200M;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://127.0.0.1:5683;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
|
||||||
|
# Gradio WebSocket 必需
|
||||||
|
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 $scheme;
|
||||||
|
|
||||||
|
proxy_read_timeout 86400s;
|
||||||
|
proxy_send_timeout 86400s;
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 966 B |
Binary file not shown.
|
After Width: | Height: | Size: 2.8 KiB |
@@ -11,17 +11,29 @@
|
|||||||
"lang": "zh-CN",
|
"lang": "zh-CN",
|
||||||
"categories": ["productivity", "utilities"],
|
"categories": ["productivity", "utilities"],
|
||||||
"icons": [
|
"icons": [
|
||||||
|
{
|
||||||
|
"src": "/pwa/icons/icon-192.png",
|
||||||
|
"sizes": "192x192",
|
||||||
|
"type": "image/png",
|
||||||
|
"purpose": "any"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "/pwa/icons/icon-512.png",
|
||||||
|
"sizes": "512x512",
|
||||||
|
"type": "image/png",
|
||||||
|
"purpose": "any"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "/pwa/icons/icon-512.png",
|
||||||
|
"sizes": "512x512",
|
||||||
|
"type": "image/png",
|
||||||
|
"purpose": "maskable"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"src": "/pwa/icons/icon.svg",
|
"src": "/pwa/icons/icon.svg",
|
||||||
"sizes": "any",
|
"sizes": "any",
|
||||||
"type": "image/svg+xml",
|
"type": "image/svg+xml",
|
||||||
"purpose": "any"
|
"purpose": "any"
|
||||||
},
|
|
||||||
{
|
|
||||||
"src": "/pwa/icons/icon.svg",
|
|
||||||
"sizes": "512x512",
|
|
||||||
"type": "image/svg+xml",
|
|
||||||
"purpose": "maskable"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# 从 SVG 生成 PWA 所需 PNG 图标(Chrome 安装条件)
|
||||||
|
# 用法: bash scripts/gen_pwa_icons.sh
|
||||||
|
set -euo pipefail
|
||||||
|
cd "$(dirname "$0")/../pwa/icons"
|
||||||
|
SVG="icon.svg"
|
||||||
|
|
||||||
|
if command -v rsvg-convert &>/dev/null; then
|
||||||
|
rsvg-convert -w 192 -h 192 "${SVG}" -o icon-192.png
|
||||||
|
rsvg-convert -w 512 -h 512 "${SVG}" -o icon-512.png
|
||||||
|
elif command -v convert &>/dev/null; then
|
||||||
|
convert -background none "${SVG}" -resize 192x192 icon-192.png
|
||||||
|
convert -background none "${SVG}" -resize 512x512 icon-512.png
|
||||||
|
elif command -v ffmpeg &>/dev/null; then
|
||||||
|
ffmpeg -y -f lavfi -i "color=c=0x0f1419:s=512x512" -frames:v 1 icon-512.png 2>/dev/null
|
||||||
|
ffmpeg -y -f lavfi -i "color=c=0x0f1419:s=192x192" -frames:v 1 icon-192.png 2>/dev/null
|
||||||
|
echo "[WARN] 仅用 ffmpeg 生成纯色图标,建议: apt install librsvg2-bin"
|
||||||
|
else
|
||||||
|
echo "[ERROR] 需要 rsvg-convert / imagemagick / ffmpeg 之一"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "[OK] 已生成 icon-192.png icon-512.png"
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# 生成本地 HTTPS 自签证书(局域网 PWA 安装用)
|
||||||
|
# 用法: sudo bash scripts/gen_ssl_cert.sh [服务器局域网IP]
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SERVER_IP="${1:-}"
|
||||||
|
SSL_DIR="/etc/nginx/ssl"
|
||||||
|
KEY="${SSL_DIR}/trading_studio.key"
|
||||||
|
CRT="${SSL_DIR}/trading_studio.crt"
|
||||||
|
|
||||||
|
if [[ "${EUID:-0}" -ne 0 ]]; then
|
||||||
|
echo "请使用 root: sudo bash scripts/gen_ssl_cert.sh 192.168.x.x"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "${SERVER_IP}" ]]; then
|
||||||
|
SERVER_IP=$(hostname -I | awk '{print $1}')
|
||||||
|
echo "[INFO] 未指定 IP,使用: ${SERVER_IP}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "${SSL_DIR}"
|
||||||
|
|
||||||
|
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
|
||||||
|
-keyout "${KEY}" \
|
||||||
|
-out "${CRT}" \
|
||||||
|
-subj "/CN=TradingStudio/O=Trading/C=CN" \
|
||||||
|
-addext "subjectAltName=IP:${SERVER_IP},DNS:trading.local,DNS:localhost"
|
||||||
|
|
||||||
|
chmod 600 "${KEY}"
|
||||||
|
echo "[OK] 证书已生成:"
|
||||||
|
echo " ${CRT}"
|
||||||
|
echo " ${KEY}"
|
||||||
|
echo ""
|
||||||
|
echo "手机/平板首次访问 HTTPS 需点「继续访问」信任自签证书,之后即可安装 App。"
|
||||||
Reference in New Issue
Block a user