feat(mobile,deploy): 接入安卓极光与华为通道并准备公网部署配置

客户端默认指向 jxd.jinniu.ink 的 HTTPS/WSS;登录后把 OpenIM userID 设为极光 alias。
华为 agconnect-services.json 不伪造、不入库。Master Secret 只从服务器文件注入。

Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
编码工程师
2026-08-30 21:32:58 +08:00
co-authored by multica-agent
parent f35e1f03d5
commit f1fe4a3928
35 changed files with 687 additions and 64 deletions
+16
View File
@@ -0,0 +1,16 @@
# 复制到仓库根目录的 .env 后按机填写。禁止把 Master Secret 写进本文件或 Git。
# 公网测试域名已解析到测试机;客户端只认域名,不认 IP。
# 本机公网 IP(LiveKit 媒体候选用)。在服务器上用 `curl -4 -s ifconfig.me` 查看,不要写进客户端。
SERVER_IP=
MINIO_EXTERNAL_ADDRESS="https://jxd.jinniu.ink/files"
OPENIM_PUSH_ENABLE=jpush
JPUSH_APPKEY=95fc2352648a7d4568ac8d72
JPUSH_PUSH_URL=https://api.jpush.cn/v3/push
JPUSH_PUSH_INTENT=intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;component=cn.solsum.jinxunda/cn.solsum.jinxunda.MainActivity;end
# Master Secret 由 scripts/load-jpush-secret.sh 从
# /root/.config/jinxunda/jpush_master_secret 注入为环境变量 JPUSH_MASTER_SECRET。
# JPUSH_MASTER_SECRET_FILE=/root/.config/jinxunda/jpush_master_secret
+66
View File
@@ -0,0 +1,66 @@
# 公网测试部署说明(jxd.jinniu.ink
施工员本卡**不执行**本节命令、不 SSH 改测试机。由总工审核通过后再部署。
目标机:已解析到 `jxd.jinniu.ink` 的香港测试服务器。数据目录仍是仓库下的 `components/``data/`,回滚不删数据。
## 对外暴露与对内绑定
| 入口 | 协议 | 后端 | 说明 |
| --- | --- | --- | --- |
| `https://jxd.jinniu.ink/` | HTTPS | OpenIM API `:10002` | 客户端 `apiAddr` |
| `wss://jxd.jinniu.ink/msg_gateway` | WSS | OpenIM 网关 `:10001` | 客户端 `wsAddr` |
| `https://jxd.jinniu.ink/account/` | HTTPS | 账号服务 `:10010` | 客户端 `authApiBase` |
| `https://jxd.jinniu.ink/files/` | HTTPS | MinIO `:10005` | `MINIO_EXTERNAL_ADDRESS` |
| `wss://jxd.jinniu.ink/livekit/` | WSS | LiveKit 信令 `:17880` | 客户端 `livekitUrl` |
| `:17881/tcp` `:17882/udp` | 媒体 | LiveKit RTC | 必须对公网开放,不能只走 443 |
内部端口(10001/10002/10005/10010/17880/etcd)在 overlay 里绑 `127.0.0.1`。防火墙建议只放行 80/tcp、443/tcp、17881/tcp、17882/udp。
## 证书
1. 先把 `deploy/public/nginx.bootstrap.conf` 挂到 edge(只听 80)。
2. `certbot certonly --webroot -w deploy/public/acme -d jxd.jinniu.ink`
3. 确认 `/etc/letsencrypt/live/jxd.jinniu.ink/``fullchain.pem``privkey.pem`
4. 改回 `nginx.conf` 后重载 edge。
私钥不得复制进 Git。
## 极光 Master Secret
文件在测试机 `/root/.config/jinxunda/jpush_master_secret`(权限 600)。部署前:
```bash
source ./scripts/load-jpush-secret.sh # 只导出环境变量,不打印内容
```
不要 `cat` 该文件,不要写进 `.env` 或 compose 明文。
## 启动(总工)
```bash
cd /path/to/tongxunruanjian
cp .env.example .env # 若还没有
# 按 deploy/public/.env.public.example 写入 SERVER_IP、MINIO_EXTERNAL_ADDRESS、JPUSH_*(不含 Master Secret
source ./scripts/load-jpush-secret.sh
./scripts/deploy-public.sh
```
`SERVER_IP` 填本机公网 IP(LiveKit 媒体候选),不要写进手机/电脑客户端代码。
## 回滚
```bash
./scripts/rollback-public.sh
```
效果:停掉 nginx edge,按原来的 `docker-compose.yaml` 拉起;`components/``data/account` 不动。
## 客户端地址(已写进代码默认值)
- 手机:`mobile/lib/config.dart`,默认 `jxd.jinniu.ink` + TLS。内网回切:`--dart-define=SERVER_HOST=192.168.200.11 --dart-define=USE_TLS=false`
- 电脑:改 `pc-client/.env``VITE_*``https://` / `wss://` 路径,见该目录 `.env.example`
## 华为通道缺口
`mobile/android/app/README-agconnect.md`。缺 `agconnect-services.json` 时华为真机厂商通道不通,其余施工已完成。
View File
+56
View File
@@ -0,0 +1,56 @@
# 公网测试 overlay。用法(在仓库根目录,由总工执行,本卡不跑):
# set -a && . ./.env && ./scripts/load-jpush-secret.sh && set +a
# docker compose -f docker-compose.yaml -f deploy/public/docker-compose.public.yaml up -d
#
# 原则:内部端口只绑 127.0.0.1;对外只开 80/443 + LiveKit 媒体 17881/tcp、17882/udp。
# 回滚:去掉本 overlay,改回 docker compose -f docker-compose.yaml up -d,数据目录 components/ 与 data/ 不动。
services:
openim-server:
ports:
- "127.0.0.1:${OPENIM_MSG_GATEWAY_PORT}:10001"
- "127.0.0.1:${OPENIM_API_PORT}:10002"
environment:
- IMENV_OPENIM_PUSH_ENABLE=${OPENIM_PUSH_ENABLE:-jpush}
- IMENV_OPENIM_PUSH_JPUSH_APPKEY=${JPUSH_APPKEY}
- IMENV_OPENIM_PUSH_JPUSH_MASTERSECRET=${JPUSH_MASTER_SECRET}
- IMENV_OPENIM_PUSH_JPUSH_PUSHURL=${JPUSH_PUSH_URL:-https://api.jpush.cn/v3/push}
- IMENV_OPENIM_PUSH_JPUSH_PUSHINTENT=${JPUSH_PUSH_INTENT}
minio:
ports:
- "127.0.0.1:${MINIO_PORT}:9000"
- "127.0.0.1:${MINIO_CONSOLE_PORT}:9090"
etcd:
ports:
- "127.0.0.1:12379:2379"
- "127.0.0.1:12380:2380"
livekit:
command: --config /etc/livekit.yaml --node-ip ${SERVER_IP}
ports:
- "127.0.0.1:${LIVEKIT_PORT:-17880}:17880"
- "${LIVEKIT_RTC_TCP_PORT:-17881}:17881"
- "${LIVEKIT_RTC_UDP_PORT:-17882}:17882/udp"
volumes:
- ./config/livekit.public.yaml:/etc/livekit.yaml
account-server:
ports:
- "127.0.0.1:${ACCOUNT_PORT:-10010}:10010"
edge:
image: nginx:1.27-alpine
container_name: jxd-edge
restart: always
network_mode: host
volumes:
- ./deploy/public/nginx.conf:/etc/nginx/nginx.conf:ro
- ./deploy/public/acme:/var/www/acme:ro
- /etc/letsencrypt:/etc/letsencrypt:ro
depends_on:
- openim-server
- account-server
- minio
- livekit
+30
View File
@@ -0,0 +1,30 @@
# 仅 80 端口:申请 Let's Encrypt 证书用。证书拿到后换成 nginx.conf。
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
sendfile on;
server_tokens off;
server {
listen 80;
listen [::]:80;
server_name jxd.jinniu.ink;
location /.well-known/acme-challenge/ {
root /var/www/acme;
}
location / {
return 200 'jxd.jinniu.ink bootstrap\n';
add_header Content-Type text/plain;
}
}
}
+120
View File
@@ -0,0 +1,120 @@
# 公网测试:jxd.jinniu.ink 终止 TLS,反代到本机回环上的 OpenIM / 账号 / 对象存储 / LiveKit。
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 4096;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
sendfile on;
server_tokens off;
client_max_body_size 100m;
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream openim_api {
server 127.0.0.1:10002;
}
upstream openim_ws {
server 127.0.0.1:10001;
}
upstream account_api {
server 127.0.0.1:10010;
}
upstream minio_s3 {
server 127.0.0.1:10005;
}
upstream livekit_signal {
server 127.0.0.1:17880;
}
server {
listen 80;
listen [::]:80;
server_name jxd.jinniu.ink;
location /.well-known/acme-challenge/ {
root /var/www/acme;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name jxd.jinniu.ink;
ssl_certificate /etc/letsencrypt/live/jxd.jinniu.ink/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/jxd.jinniu.ink/privkey.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
# OpenIM 消息长连接
location /msg_gateway {
proxy_pass http://openim_ws/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $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 3600s;
proxy_send_timeout 3600s;
}
# 公司账号服务(登录、管理页、rtc_token)
location /account/ {
proxy_pass http://account_api/;
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;
}
# MinIO 对象(MINIO_EXTERNAL_ADDRESS=https://jxd.jinniu.ink/files
location /files/ {
proxy_pass http://minio_s3/;
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_request_buffering off;
}
# LiveKit 信令(客户端 wss://jxd.jinniu.ink/livekit → 容器 /rtc 等)
location /livekit/ {
proxy_pass http://livekit_signal/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $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 3600s;
proxy_send_timeout 3600s;
}
# OpenIM REST APIcatch-all,须放最后)
location / {
proxy_pass http://openim_api;
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;
}
}
}