mirror of
https://github.com/619dev/Paperphone-plus.git
synced 2026-09-03 07:18:05 +08:00
更新部署文档
This commit is contained in:
423
DEPLOY_CN.md
Normal file
423
DEPLOY_CN.md
Normal file
@@ -0,0 +1,423 @@
|
||||
# 📦 部署指南
|
||||
|
||||
本文档详细介绍 PaperPhonePlus 的两种推荐部署方式,以及各平台客户端的服务器地址配置方法。
|
||||
|
||||
> **核心思路**:后端(server)、数据库(MySQL)、缓存(Redis)部署在服务器端;前端(client)可独立部署到 Vercel 等 CDN 平台以获得更好的全球访问速度。客户端(iOS / Android / Web / Windows / macOS)通过填写 **server 的地址** 来连接后端服务。
|
||||
|
||||
---
|
||||
|
||||
## 目录
|
||||
|
||||
- [方式一:Zeabur 模版 + Vercel 前端(推荐)](#方式一zeabur-模版--vercel-前端推荐)
|
||||
- [方式二:Docker Compose + Nginx 本地部署](#方式二docker-compose--nginx-本地部署)
|
||||
- [客户端服务器地址配置](#客户端服务器地址配置)
|
||||
|
||||
---
|
||||
|
||||
## 方式一:Zeabur 模版 + Vercel 前端(推荐)
|
||||
|
||||
此方案将 server、MySQL、Redis 部署在 Zeabur 云平台,前端部署到 Vercel CDN,实现全球加速访问。
|
||||
|
||||
### 第一步:使用 Zeabur 模版部署
|
||||
|
||||
1. 点击一键部署按钮:
|
||||
|
||||
[](https://zeabur.com/templates/SK6T93?referralCode=619dev)
|
||||
|
||||
2. 登录 Zeabur 账号(支持 GitHub 登录)
|
||||
3. 选择部署区域(建议选择离目标用户最近的区域)
|
||||
4. 按提示填写环境变量(`JWT_SECRET`、`R2_*` 等),详见 [README](README.md) 中的环境变量说明
|
||||
5. 等待所有服务启动完成
|
||||
|
||||
### 第二步:删除 Zeabur 上的 client 服务
|
||||
|
||||
部署完成后,Zeabur 会自动创建 `client`(前端)、`server`(后端)、`MySQL`、`Redis` 四个服务。由于我们要将前端单独部署到 Vercel,需要删除 Zeabur 上的 client 服务:
|
||||
|
||||
1. 进入 [Zeabur Dashboard](https://dash.zeabur.com)
|
||||
2. 找到刚部署的项目
|
||||
3. 点击 **client** 服务
|
||||
4. 进入服务设置 → 底部找到 **Delete Service**(删除服务)
|
||||
5. 确认删除
|
||||
|
||||
> ⚠️ 仅删除 `client` 服务,**不要** 删除 `server`、`MySQL`、`Redis` 服务。
|
||||
|
||||
### 第三步:记录 server 服务的域名
|
||||
|
||||
1. 在 Zeabur Dashboard 中点击 **server** 服务
|
||||
2. 进入 **Networking** 选项卡
|
||||
3. 记录 server 服务的公网域名,例如:`https://your-server-xxx.zeabur.app`
|
||||
4. 如需自定义域名,可在此处绑定自己的域名
|
||||
|
||||
### 第四步:在 Vercel 部署前端
|
||||
|
||||
1. **Fork 本仓库** 到你的 GitHub 账号
|
||||
|
||||
2. 登录 [Vercel](https://vercel.com),点击 **Add New Project**
|
||||
|
||||
3. 从 GitHub 导入你 fork 的仓库
|
||||
|
||||
4. 配置项目设置:
|
||||
|
||||
| 配置项 | 值 |
|
||||
|--------|-----|
|
||||
| **Root Directory** | `client/` |
|
||||
| **Framework Preset** | Vite |
|
||||
| **Build Command** | `npm run build` |
|
||||
| **Output Directory** | `dist/` |
|
||||
|
||||
5. **无需设置任何环境变量** — 用户在前端登录页面填写后端服务器地址即可
|
||||
|
||||
6. 点击 **Deploy** 开始部署
|
||||
|
||||
7. 部署完成后,Vercel 会分配一个域名(如 `your-app.vercel.app`),也可以绑定自定义域名
|
||||
|
||||
### 第五步:验证部署
|
||||
|
||||
1. 打开 Vercel 部署的前端页面
|
||||
2. 在登录页面的服务器地址输入框中,填写 Zeabur 上 **server** 服务的域名(如 `https://your-server-xxx.zeabur.app`)
|
||||
3. 注册账号并登录
|
||||
4. 测试消息发送、文件上传等功能
|
||||
|
||||
---
|
||||
|
||||
## 方式二:Docker Compose + Nginx 本地部署
|
||||
|
||||
此方案适合有自己服务器的用户,将所有服务(除前端外)通过 Docker Compose 部署,使用 Nginx 作为反向代理提供 HTTPS 访问。
|
||||
|
||||
### 第一步:准备服务器环境
|
||||
|
||||
**系统要求**:
|
||||
- Linux 服务器(推荐 Ubuntu 22.04+ / Debian 12+)
|
||||
- 已安装 Docker 和 Docker Compose
|
||||
- 一个域名(已解析到服务器 IP)
|
||||
- 建议至少 2GB 内存
|
||||
|
||||
**安装 Docker**(如未安装):
|
||||
```bash
|
||||
# 安装 Docker
|
||||
curl -fsSL https://get.docker.com | sh
|
||||
|
||||
# 启动 Docker 服务
|
||||
sudo systemctl enable docker
|
||||
sudo systemctl start docker
|
||||
|
||||
# 将当前用户加入 docker 组(免 sudo)
|
||||
sudo usermod -aG docker $USER
|
||||
# 重新登录使组变更生效
|
||||
```
|
||||
|
||||
### 第二步:克隆项目并配置
|
||||
|
||||
```bash
|
||||
# 克隆仓库
|
||||
git clone <repo-url> && cd paperphone-plus
|
||||
|
||||
# 复制并编辑环境变量
|
||||
cp server/.env.example server/.env
|
||||
```
|
||||
|
||||
编辑 `server/.env` 文件,配置必要的环境变量:
|
||||
|
||||
```bash
|
||||
# 必须修改的配置
|
||||
JWT_SECRET=你的随机密钥字符串 # 生产环境必须更改
|
||||
DB_PASS=你的数据库密码 # 与 docker-compose.yml 中保持一致
|
||||
ADMIN_PASSWORD=你的管理后台密码 # 生产环境必须更改
|
||||
|
||||
# 可选配置(按需填写)
|
||||
R2_ACCOUNT_ID=... # Cloudflare R2 文件存储
|
||||
R2_ACCESS_KEY_ID=...
|
||||
R2_SECRET_ACCESS_KEY=...
|
||||
R2_BUCKET=...
|
||||
CF_CALLS_APP_ID=... # Cloudflare TURN(视频通话)
|
||||
CF_CALLS_APP_SECRET=...
|
||||
VAPID_PUBLIC_KEY=... # Web Push 推送通知
|
||||
VAPID_PRIVATE_KEY=...
|
||||
```
|
||||
|
||||
### 第三步:修改 docker-compose.yml,删除 client 部分
|
||||
|
||||
由于前端将通过 Nginx 直接提供服务(或部署到 Vercel),需要从 `docker-compose.yml` 中删除 `client` 服务。
|
||||
|
||||
编辑 `docker-compose.yml`,**删除以下内容**:
|
||||
|
||||
```yaml
|
||||
# ── Frontend (Nginx + React SPA) ────────────────────────────
|
||||
client:
|
||||
container_name: paperphone-plus-client
|
||||
image: facilisvelox/paperphone-plus-client:latest
|
||||
ports:
|
||||
- "80:80"
|
||||
depends_on:
|
||||
server:
|
||||
condition: service_healthy
|
||||
restart: unless-stopped
|
||||
```
|
||||
|
||||
删除后,`docker-compose.yml` 中应只保留 `server`、`mysql`、`redis` 三个服务。
|
||||
|
||||
### 第四步:启动 Docker 服务
|
||||
|
||||
```bash
|
||||
# 启动所有服务(后端 + MySQL + Redis)
|
||||
docker compose up -d
|
||||
|
||||
# 查看服务状态
|
||||
docker compose ps
|
||||
|
||||
# 查看日志
|
||||
docker compose logs -f server
|
||||
```
|
||||
|
||||
确认所有服务状态为 `running` 且 `healthy`。server 首次启动会自动创建数据库表,无需手动导入 SQL。
|
||||
|
||||
### 第五步:构建前端静态文件
|
||||
|
||||
有两种方式获取前端静态文件:
|
||||
|
||||
**方式 A:本地构建(推荐)**
|
||||
|
||||
```bash
|
||||
cd client
|
||||
npm install
|
||||
npm run build
|
||||
# 构建产物在 client/dist/ 目录
|
||||
```
|
||||
|
||||
**方式 B:从 Docker 镜像提取**
|
||||
|
||||
```bash
|
||||
# 创建临时容器并复制文件
|
||||
docker create --name temp-client facilisvelox/paperphone-plus-client:latest
|
||||
docker cp temp-client:/usr/share/nginx/html ./client/dist
|
||||
docker rm temp-client
|
||||
```
|
||||
|
||||
### 第六步:安装并配置 Nginx
|
||||
|
||||
**安装 Nginx**:
|
||||
|
||||
```bash
|
||||
# Ubuntu / Debian
|
||||
sudo apt update
|
||||
sudo apt install -y nginx
|
||||
|
||||
# CentOS / RHEL
|
||||
sudo yum install -y nginx
|
||||
|
||||
# 启动 Nginx
|
||||
sudo systemctl enable nginx
|
||||
sudo systemctl start nginx
|
||||
```
|
||||
|
||||
**安装 SSL 证书**(使用 Let's Encrypt 免费证书):
|
||||
|
||||
```bash
|
||||
# 安装 Certbot
|
||||
sudo apt install -y certbot python3-certbot-nginx
|
||||
|
||||
# 申请证书(将 your.domain.com 替换为你的域名)
|
||||
sudo certbot --nginx -d your.domain.com
|
||||
|
||||
# 证书会自动配置到 Nginx,并设置自动续期
|
||||
```
|
||||
|
||||
**配置 Nginx**:
|
||||
|
||||
创建 Nginx 站点配置文件:
|
||||
|
||||
```bash
|
||||
sudo nano /etc/nginx/sites-available/paperphoneplus
|
||||
```
|
||||
|
||||
写入以下内容(将 `your.domain.com` 替换为你的域名):
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name your.domain.com;
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
server_name your.domain.com;
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/your.domain.com/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/your.domain.com/privkey.pem;
|
||||
|
||||
# SSL 安全优化
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers HIGH:!aNULL:!MD5;
|
||||
ssl_prefer_server_ciphers on;
|
||||
ssl_session_cache shared:SSL:10m;
|
||||
|
||||
# 文件上传大小限制(与 500MB 文件上传对应)
|
||||
client_max_body_size 512M;
|
||||
|
||||
# 前端静态文件
|
||||
location / {
|
||||
root /path/to/paperphone-plus/client/dist;
|
||||
try_files $uri /index.html;
|
||||
|
||||
# 缓存优化
|
||||
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
|
||||
expires 30d;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
}
|
||||
|
||||
# API 反向代理
|
||||
location /api/ {
|
||||
proxy_pass http://localhost:3000;
|
||||
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;
|
||||
}
|
||||
|
||||
# WebSocket 信令(实时通讯)
|
||||
location /ws {
|
||||
proxy_pass http://localhost: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_read_timeout 3600s;
|
||||
proxy_send_timeout 3600s;
|
||||
}
|
||||
|
||||
# 管理后台(可选,路径与 ADMIN_PATH 环境变量一致)
|
||||
location /admin {
|
||||
proxy_pass http://localhost:3000;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
}
|
||||
|
||||
# 健康检查
|
||||
location /health {
|
||||
proxy_pass http://localhost:3000;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**启用站点并重启 Nginx**:
|
||||
|
||||
```bash
|
||||
# 创建符号链接启用站点
|
||||
sudo ln -s /etc/nginx/sites-available/paperphoneplus /etc/nginx/sites-enabled/
|
||||
|
||||
# 删除默认站点(可选)
|
||||
sudo rm -f /etc/nginx/sites-enabled/default
|
||||
|
||||
# 测试配置文件语法
|
||||
sudo nginx -t
|
||||
|
||||
# 重启 Nginx
|
||||
sudo systemctl reload nginx
|
||||
```
|
||||
|
||||
### 第七步:验证部署
|
||||
|
||||
1. 浏览器访问 `https://your.domain.com`,应能看到前端登录页面
|
||||
2. 注册账号并测试各项功能
|
||||
3. 检查 WebSocket 连接是否正常(聊天消息实时送达)
|
||||
4. 测试文件上传功能
|
||||
|
||||
### 故障排查
|
||||
|
||||
```bash
|
||||
# 检查 Docker 容器状态
|
||||
docker compose ps
|
||||
|
||||
# 查看后端日志
|
||||
docker compose logs -f server
|
||||
|
||||
# 查看 Nginx 错误日志
|
||||
sudo tail -f /var/log/nginx/error.log
|
||||
|
||||
# 检查端口占用
|
||||
sudo ss -tlnp | grep -E '80|443|3000|3306|6379'
|
||||
|
||||
# 重启所有服务
|
||||
docker compose restart
|
||||
sudo systemctl restart nginx
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 客户端服务器地址配置
|
||||
|
||||
所有客户端(iOS、Android、Web、Windows、macOS)连接的服务器地址,应该填写 **server 后端服务** 的地址,而非前端地址。
|
||||
|
||||
> ⚠️ **重要**:客户端中填写的服务器地址是 **后端 server 的地址**,不是前端网页的地址。
|
||||
|
||||
### 各部署方式对应的服务器地址
|
||||
|
||||
| 部署方式 | 服务器地址 | 示例 |
|
||||
|----------|-----------|------|
|
||||
| **Zeabur** | Zeabur 上 server 服务的域名 | `https://your-server-xxx.zeabur.app` |
|
||||
| **Docker Compose + Nginx** | 你的域名(Nginx 会代理到后端) | `https://your.domain.com` |
|
||||
| **本地开发** | 本地后端地址 | `http://localhost:3000` |
|
||||
|
||||
### 各客户端配置方式
|
||||
|
||||
#### 📱 iOS App(App Store 版 / PWA)
|
||||
1. 打开 App → 进入登录页面
|
||||
2. 在 **服务器地址** 输入框中填写 server 地址
|
||||
3. 例如:`https://your-server-xxx.zeabur.app`
|
||||
|
||||
#### 🤖 Android App(Google Play 版)
|
||||
1. 打开 App → 进入登录页面
|
||||
2. 在 **服务器地址** 输入框中填写 server 地址
|
||||
3. 例如:`https://your-server-xxx.zeabur.app`
|
||||
|
||||
#### 🌐 Web 端(浏览器)
|
||||
1. 打开 Vercel 或 Nginx 部署的前端页面
|
||||
2. 在登录页面的 **服务器地址** 输入框中填写 server 地址
|
||||
3. 例如:`https://your-server-xxx.zeabur.app`
|
||||
|
||||
#### 🖥️ Windows 客户端
|
||||
1. 下载并安装 [Windows 客户端](https://github.com/619dev/ppp-win/releases)
|
||||
2. 打开应用 → 进入登录页面
|
||||
3. 在 **服务器地址** 输入框中填写 server 地址
|
||||
4. 例如:`https://your-server-xxx.zeabur.app`
|
||||
|
||||
#### 🍎 macOS 客户端
|
||||
1. 下载并安装 [Mac 客户端](https://github.com/619dev/ppp-mac/releases)
|
||||
2. 打开应用 → 进入登录页面
|
||||
3. 在 **服务器地址** 输入框中填写 server 地址
|
||||
4. 例如:`https://your-server-xxx.zeabur.app`
|
||||
|
||||
### Docker Compose + Nginx 部署时的特殊说明
|
||||
|
||||
当使用 Docker Compose + Nginx 部署时,前端和后端共用同一个域名(通过 Nginx 反向代理)。此时客户端中填写的服务器地址就是你的域名本身:
|
||||
|
||||
```
|
||||
服务器地址:https://your.domain.com
|
||||
```
|
||||
|
||||
Nginx 会根据请求路径自动将 API 请求(`/api/*`)和 WebSocket 连接(`/ws`)转发到后端 server 容器。
|
||||
|
||||
---
|
||||
|
||||
## 常见问题
|
||||
|
||||
### Q: 前端和后端可以部署在不同域名吗?
|
||||
**A:** 可以。前端支持在登录页面手动输入后端服务器地址,前端与后端不需要同一域名。
|
||||
|
||||
### Q: Vercel 部署前端需要设置环境变量吗?
|
||||
**A:** 不需要。前端的服务器地址由用户在登录页面手动输入,无需预设。
|
||||
|
||||
### Q: 为什么推荐删除 Zeabur/Docker 中的 client 服务?
|
||||
**A:** 将前端部署到 Vercel 可以利用其全球 CDN 加速,用户访问速度更快。同时减轻服务器负担,让服务器专注于后端处理。
|
||||
|
||||
### Q: iOS PWA 用户需要 HTTPS 吗?
|
||||
**A:** 是的。WebRTC 和 Web Crypto API 必须在 HTTPS(安全上下文)环境中运行。iOS PWA 的「添加到主屏幕」功能也需要 HTTPS。
|
||||
|
||||
### Q: 如何更新部署?
|
||||
**A:**
|
||||
- **Zeabur**:在 Dashboard 中重新部署 server 服务即可
|
||||
- **Docker Compose**:执行 `docker compose pull && docker compose up -d`
|
||||
- **Vercel 前端**:推送到 GitHub,Vercel 自动触发重新部署
|
||||
423
DEPLOY_EN.md
Normal file
423
DEPLOY_EN.md
Normal file
@@ -0,0 +1,423 @@
|
||||
# 📦 Deployment Guide
|
||||
|
||||
This document provides detailed instructions for two recommended deployment methods for PaperPhonePlus, along with client-side server address configuration for all platforms.
|
||||
|
||||
> **Key Concept**: The backend (server), database (MySQL), and cache (Redis) are deployed on a server; the frontend (client) can be independently deployed to CDN platforms like Vercel for better global performance. All clients (iOS / Android / Web / Windows / macOS) connect to the backend by entering the **server's address**.
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Method 1: Zeabur Template + Vercel Frontend (Recommended)](#method-1-zeabur-template--vercel-frontend-recommended)
|
||||
- [Method 2: Docker Compose + Nginx Local Deployment](#method-2-docker-compose--nginx-local-deployment)
|
||||
- [Client Server Address Configuration](#client-server-address-configuration)
|
||||
|
||||
---
|
||||
|
||||
## Method 1: Zeabur Template + Vercel Frontend (Recommended)
|
||||
|
||||
This approach deploys server, MySQL, and Redis on the Zeabur cloud platform, while the frontend is deployed to Vercel CDN for globally accelerated access.
|
||||
|
||||
### Step 1: Deploy Using the Zeabur Template
|
||||
|
||||
1. Click the one-click deploy button:
|
||||
|
||||
[](https://zeabur.com/templates/SK6T93?referralCode=619dev)
|
||||
|
||||
2. Log in to your Zeabur account (GitHub login supported)
|
||||
3. Select a deployment region (choose the region closest to your target users)
|
||||
4. Fill in the environment variables as prompted (`JWT_SECRET`, `R2_*`, etc.) — see the [README](README_EN.md) for environment variable details
|
||||
5. Wait for all services to finish starting
|
||||
|
||||
### Step 2: Delete the client Service on Zeabur
|
||||
|
||||
After deployment, Zeabur will automatically create four services: `client` (frontend), `server` (backend), `MySQL`, and `Redis`. Since we want to deploy the frontend separately on Vercel, we need to delete the client service on Zeabur:
|
||||
|
||||
1. Go to the [Zeabur Dashboard](https://dash.zeabur.com)
|
||||
2. Find the project you just deployed
|
||||
3. Click on the **client** service
|
||||
4. Go to Service Settings → scroll to the bottom and find **Delete Service**
|
||||
5. Confirm the deletion
|
||||
|
||||
> ⚠️ Only delete the `client` service. **Do NOT** delete the `server`, `MySQL`, or `Redis` services.
|
||||
|
||||
### Step 3: Note the server Service Domain
|
||||
|
||||
1. In the Zeabur Dashboard, click on the **server** service
|
||||
2. Go to the **Networking** tab
|
||||
3. Note the server service's public domain, e.g., `https://your-server-xxx.zeabur.app`
|
||||
4. You can bind a custom domain here if needed
|
||||
|
||||
### Step 4: Deploy the Frontend on Vercel
|
||||
|
||||
1. **Fork this repository** to your GitHub account
|
||||
|
||||
2. Log in to [Vercel](https://vercel.com) and click **Add New Project**
|
||||
|
||||
3. Import your forked repository from GitHub
|
||||
|
||||
4. Configure the project settings:
|
||||
|
||||
| Setting | Value |
|
||||
|---------|-------|
|
||||
| **Root Directory** | `client/` |
|
||||
| **Framework Preset** | Vite |
|
||||
| **Build Command** | `npm run build` |
|
||||
| **Output Directory** | `dist/` |
|
||||
|
||||
5. **No environment variables are needed** — users enter the backend server address on the frontend login page
|
||||
|
||||
6. Click **Deploy** to start the deployment
|
||||
|
||||
7. After deployment, Vercel will assign a domain (e.g., `your-app.vercel.app`). You can also bind a custom domain
|
||||
|
||||
### Step 5: Verify the Deployment
|
||||
|
||||
1. Open the Vercel-deployed frontend page
|
||||
2. On the login page, enter the **server** service domain from Zeabur in the server address field (e.g., `https://your-server-xxx.zeabur.app`)
|
||||
3. Register an account and log in
|
||||
4. Test messaging, file upload, and other features
|
||||
|
||||
---
|
||||
|
||||
## Method 2: Docker Compose + Nginx Local Deployment
|
||||
|
||||
This approach is suitable for users with their own servers. All services (except the frontend) are deployed via Docker Compose, with Nginx serving as a reverse proxy providing HTTPS access.
|
||||
|
||||
### Step 1: Prepare the Server Environment
|
||||
|
||||
**System Requirements**:
|
||||
- Linux server (Ubuntu 22.04+ / Debian 12+ recommended)
|
||||
- Docker and Docker Compose installed
|
||||
- A domain name (DNS already pointing to your server IP)
|
||||
- At least 2GB of RAM recommended
|
||||
|
||||
**Install Docker** (if not already installed):
|
||||
```bash
|
||||
# Install Docker
|
||||
curl -fsSL https://get.docker.com | sh
|
||||
|
||||
# Start Docker service
|
||||
sudo systemctl enable docker
|
||||
sudo systemctl start docker
|
||||
|
||||
# Add current user to docker group (no sudo needed)
|
||||
sudo usermod -aG docker $USER
|
||||
# Log out and back in for the group change to take effect
|
||||
```
|
||||
|
||||
### Step 2: Clone the Project and Configure
|
||||
|
||||
```bash
|
||||
# Clone the repository
|
||||
git clone <repo-url> && cd paperphone-plus
|
||||
|
||||
# Copy and edit environment variables
|
||||
cp server/.env.example server/.env
|
||||
```
|
||||
|
||||
Edit the `server/.env` file and configure the necessary environment variables:
|
||||
|
||||
```bash
|
||||
# Required configuration — must change
|
||||
JWT_SECRET=your_random_secret_string # Must change for production
|
||||
DB_PASS=your_database_password # Keep consistent with docker-compose.yml
|
||||
ADMIN_PASSWORD=your_admin_panel_password # Must change for production
|
||||
|
||||
# Optional configuration (fill in as needed)
|
||||
R2_ACCOUNT_ID=... # Cloudflare R2 file storage
|
||||
R2_ACCESS_KEY_ID=...
|
||||
R2_SECRET_ACCESS_KEY=...
|
||||
R2_BUCKET=...
|
||||
CF_CALLS_APP_ID=... # Cloudflare TURN (video calls)
|
||||
CF_CALLS_APP_SECRET=...
|
||||
VAPID_PUBLIC_KEY=... # Web Push notifications
|
||||
VAPID_PRIVATE_KEY=...
|
||||
```
|
||||
|
||||
### Step 3: Modify docker-compose.yml — Remove the client Section
|
||||
|
||||
Since the frontend will be served directly through Nginx (or deployed to Vercel), you need to remove the `client` service from `docker-compose.yml`.
|
||||
|
||||
Edit `docker-compose.yml` and **delete the following block**:
|
||||
|
||||
```yaml
|
||||
# ── Frontend (Nginx + React SPA) ────────────────────────────
|
||||
client:
|
||||
container_name: paperphone-plus-client
|
||||
image: facilisvelox/paperphone-plus-client:latest
|
||||
ports:
|
||||
- "80:80"
|
||||
depends_on:
|
||||
server:
|
||||
condition: service_healthy
|
||||
restart: unless-stopped
|
||||
```
|
||||
|
||||
After deletion, `docker-compose.yml` should only contain the `server`, `mysql`, and `redis` services.
|
||||
|
||||
### Step 4: Start Docker Services
|
||||
|
||||
```bash
|
||||
# Start all services (backend + MySQL + Redis)
|
||||
docker compose up -d
|
||||
|
||||
# Check service status
|
||||
docker compose ps
|
||||
|
||||
# View logs
|
||||
docker compose logs -f server
|
||||
```
|
||||
|
||||
Confirm all services show `running` and `healthy` status. The server will automatically create database tables on first startup — no manual SQL import is needed.
|
||||
|
||||
### Step 5: Build Frontend Static Files
|
||||
|
||||
There are two ways to obtain the frontend static files:
|
||||
|
||||
**Option A: Build Locally (Recommended)**
|
||||
|
||||
```bash
|
||||
cd client
|
||||
npm install
|
||||
npm run build
|
||||
# Build output will be in client/dist/
|
||||
```
|
||||
|
||||
**Option B: Extract from Docker Image**
|
||||
|
||||
```bash
|
||||
# Create a temporary container and copy files
|
||||
docker create --name temp-client facilisvelox/paperphone-plus-client:latest
|
||||
docker cp temp-client:/usr/share/nginx/html ./client/dist
|
||||
docker rm temp-client
|
||||
```
|
||||
|
||||
### Step 6: Install and Configure Nginx
|
||||
|
||||
**Install Nginx**:
|
||||
|
||||
```bash
|
||||
# Ubuntu / Debian
|
||||
sudo apt update
|
||||
sudo apt install -y nginx
|
||||
|
||||
# CentOS / RHEL
|
||||
sudo yum install -y nginx
|
||||
|
||||
# Start Nginx
|
||||
sudo systemctl enable nginx
|
||||
sudo systemctl start nginx
|
||||
```
|
||||
|
||||
**Install SSL Certificate** (using Let's Encrypt free certificate):
|
||||
|
||||
```bash
|
||||
# Install Certbot
|
||||
sudo apt install -y certbot python3-certbot-nginx
|
||||
|
||||
# Request certificate (replace your.domain.com with your domain)
|
||||
sudo certbot --nginx -d your.domain.com
|
||||
|
||||
# The certificate will be automatically configured in Nginx with auto-renewal
|
||||
```
|
||||
|
||||
**Configure Nginx**:
|
||||
|
||||
Create an Nginx site configuration file:
|
||||
|
||||
```bash
|
||||
sudo nano /etc/nginx/sites-available/paperphoneplus
|
||||
```
|
||||
|
||||
Enter the following content (replace `your.domain.com` with your domain):
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name your.domain.com;
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
server_name your.domain.com;
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/your.domain.com/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/your.domain.com/privkey.pem;
|
||||
|
||||
# SSL security optimizations
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers HIGH:!aNULL:!MD5;
|
||||
ssl_prefer_server_ciphers on;
|
||||
ssl_session_cache shared:SSL:10m;
|
||||
|
||||
# File upload size limit (to support 500MB uploads)
|
||||
client_max_body_size 512M;
|
||||
|
||||
# Frontend static files
|
||||
location / {
|
||||
root /path/to/paperphone-plus/client/dist;
|
||||
try_files $uri /index.html;
|
||||
|
||||
# Cache optimization
|
||||
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
|
||||
expires 30d;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
}
|
||||
|
||||
# API reverse proxy
|
||||
location /api/ {
|
||||
proxy_pass http://localhost:3000;
|
||||
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;
|
||||
}
|
||||
|
||||
# WebSocket signaling (real-time communication)
|
||||
location /ws {
|
||||
proxy_pass http://localhost: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_read_timeout 3600s;
|
||||
proxy_send_timeout 3600s;
|
||||
}
|
||||
|
||||
# Admin panel (optional, path should match ADMIN_PATH env var)
|
||||
location /admin {
|
||||
proxy_pass http://localhost:3000;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
}
|
||||
|
||||
# Health check
|
||||
location /health {
|
||||
proxy_pass http://localhost:3000;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Enable the site and restart Nginx**:
|
||||
|
||||
```bash
|
||||
# Create symbolic link to enable the site
|
||||
sudo ln -s /etc/nginx/sites-available/paperphoneplus /etc/nginx/sites-enabled/
|
||||
|
||||
# Remove default site (optional)
|
||||
sudo rm -f /etc/nginx/sites-enabled/default
|
||||
|
||||
# Test configuration syntax
|
||||
sudo nginx -t
|
||||
|
||||
# Reload Nginx
|
||||
sudo systemctl reload nginx
|
||||
```
|
||||
|
||||
### Step 7: Verify the Deployment
|
||||
|
||||
1. Visit `https://your.domain.com` in a browser — you should see the frontend login page
|
||||
2. Register an account and test all features
|
||||
3. Verify that WebSocket connections work correctly (chat messages delivered in real-time)
|
||||
4. Test file upload functionality
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
```bash
|
||||
# Check Docker container status
|
||||
docker compose ps
|
||||
|
||||
# View backend logs
|
||||
docker compose logs -f server
|
||||
|
||||
# View Nginx error logs
|
||||
sudo tail -f /var/log/nginx/error.log
|
||||
|
||||
# Check port usage
|
||||
sudo ss -tlnp | grep -E '80|443|3000|3306|6379'
|
||||
|
||||
# Restart all services
|
||||
docker compose restart
|
||||
sudo systemctl restart nginx
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Client Server Address Configuration
|
||||
|
||||
All clients (iOS, Android, Web, Windows, macOS) should enter the address of the **backend server service**, not the frontend address.
|
||||
|
||||
> ⚠️ **Important**: The server address entered in clients is the **backend server's address**, not the frontend web page's address.
|
||||
|
||||
### Server Address by Deployment Method
|
||||
|
||||
| Deployment Method | Server Address | Example |
|
||||
|-------------------|---------------|---------|
|
||||
| **Zeabur** | Domain of the server service on Zeabur | `https://your-server-xxx.zeabur.app` |
|
||||
| **Docker Compose + Nginx** | Your domain (Nginx proxies to backend) | `https://your.domain.com` |
|
||||
| **Local Development** | Local backend address | `http://localhost:3000` |
|
||||
|
||||
### Configuration for Each Client
|
||||
|
||||
#### 📱 iOS App (App Store / PWA)
|
||||
1. Open the App → go to the login page
|
||||
2. Enter the server address in the **Server Address** field
|
||||
3. Example: `https://your-server-xxx.zeabur.app`
|
||||
|
||||
#### 🤖 Android App (Google Play)
|
||||
1. Open the App → go to the login page
|
||||
2. Enter the server address in the **Server Address** field
|
||||
3. Example: `https://your-server-xxx.zeabur.app`
|
||||
|
||||
#### 🌐 Web (Browser)
|
||||
1. Open the frontend page deployed on Vercel or Nginx
|
||||
2. Enter the server address in the **Server Address** field on the login page
|
||||
3. Example: `https://your-server-xxx.zeabur.app`
|
||||
|
||||
#### 🖥️ Windows Client
|
||||
1. Download and install the [Windows Client](https://github.com/619dev/ppp-win/releases)
|
||||
2. Open the app → go to the login page
|
||||
3. Enter the server address in the **Server Address** field
|
||||
4. Example: `https://your-server-xxx.zeabur.app`
|
||||
|
||||
#### 🍎 macOS Client
|
||||
1. Download and install the [Mac Client](https://github.com/619dev/ppp-mac/releases)
|
||||
2. Open the app → go to the login page
|
||||
3. Enter the server address in the **Server Address** field
|
||||
4. Example: `https://your-server-xxx.zeabur.app`
|
||||
|
||||
### Special Note for Docker Compose + Nginx Deployment
|
||||
|
||||
When using Docker Compose + Nginx deployment, the frontend and backend share the same domain (via Nginx reverse proxy). In this case, the server address to enter in clients is simply your domain:
|
||||
|
||||
```
|
||||
Server Address: https://your.domain.com
|
||||
```
|
||||
|
||||
Nginx automatically routes API requests (`/api/*`) and WebSocket connections (`/ws`) to the backend server container based on the request path.
|
||||
|
||||
---
|
||||
|
||||
## FAQ
|
||||
|
||||
### Q: Can the frontend and backend be deployed on different domains?
|
||||
**A:** Yes. The frontend supports manually entering the backend server address on the login page, so the frontend and backend do not need to share the same domain.
|
||||
|
||||
### Q: Does the Vercel-deployed frontend need environment variables?
|
||||
**A:** No. The server address is entered by users on the login page — no pre-configuration is needed.
|
||||
|
||||
### Q: Why is it recommended to remove the client service from Zeabur/Docker?
|
||||
**A:** Deploying the frontend to Vercel leverages its global CDN for faster user access worldwide. It also reduces server load, allowing the server to focus on backend processing.
|
||||
|
||||
### Q: Does iOS PWA require HTTPS?
|
||||
**A:** Yes. WebRTC and Web Crypto APIs must run in an HTTPS (secure context) environment. The iOS PWA "Add to Home Screen" feature also requires HTTPS.
|
||||
|
||||
### Q: How do I update the deployment?
|
||||
**A:**
|
||||
- **Zeabur**: Redeploy the server service in the Dashboard
|
||||
- **Docker Compose**: Run `docker compose pull && docker compose up -d`
|
||||
- **Vercel Frontend**: Push to GitHub and Vercel will automatically trigger redeployment
|
||||
@@ -96,6 +96,8 @@
|
||||
|
||||
---
|
||||
|
||||
> 📖 **[详细部署文档 / Deployment Guide](DEPLOY_CN.md)** — 包含 Zeabur + Vercel 混合部署、Docker Compose + Nginx 本地部署的完整步骤,以及各客户端服务器地址配置说明。
|
||||
|
||||
### 方式零:Zeabur 一键云部署
|
||||
[](https://zeabur.com/templates/SK6T93?referralCode=619dev)
|
||||
|
||||
|
||||
@@ -96,6 +96,8 @@ Kryptographische Schicht
|
||||
|
||||
---
|
||||
|
||||
> 📖 **[Detaillierte Bereitstellungsanleitung (中文)](DEPLOY_CN.md)** | **[Deployment Guide (English)](DEPLOY_EN.md)** — Vollständige Schritt-für-Schritt-Anleitung für Zeabur + Vercel Hybrid-Bereitstellung, Docker Compose + Nginx lokale Bereitstellung und Client-Server-Adresskonfiguration.
|
||||
|
||||
### Option 0: Zeabur One-Click Cloud-Bereitstellung
|
||||
[](https://zeabur.com/templates/SK6T93?referralCode=619dev)
|
||||
|
||||
|
||||
@@ -96,6 +96,8 @@ Cryptographic Layer
|
||||
|
||||
---
|
||||
|
||||
> 📖 **[Detailed Deployment Guide](DEPLOY_EN.md)** — Complete step-by-step instructions for Zeabur + Vercel hybrid deployment, Docker Compose + Nginx local deployment, and client server address configuration.
|
||||
|
||||
### Option 0: Zeabur One-Click Cloud Deploy
|
||||
[](https://zeabur.com/templates/SK6T93?referralCode=619dev)
|
||||
|
||||
|
||||
@@ -96,6 +96,8 @@ Capa criptográfica
|
||||
|
||||
---
|
||||
|
||||
> 📖 **[Guía de despliegue detallada (中文)](DEPLOY_CN.md)** | **[Deployment Guide (English)](DEPLOY_EN.md)** — Instrucciones paso a paso completas para el despliegue híbrido Zeabur + Vercel, despliegue local con Docker Compose + Nginx, y configuración de la dirección del servidor del cliente.
|
||||
|
||||
### Opción 0: Despliegue en la nube con Zeabur en un clic
|
||||
[](https://zeabur.com/templates/SK6T93?referralCode=619dev)
|
||||
|
||||
|
||||
@@ -96,6 +96,8 @@ Couche cryptographique
|
||||
|
||||
---
|
||||
|
||||
> 📖 **[Guide de déploiement détaillé (中文)](DEPLOY_CN.md)** | **[Deployment Guide (English)](DEPLOY_EN.md)** — Instructions étape par étape complètes pour le déploiement hybride Zeabur + Vercel, le déploiement local avec Docker Compose + Nginx, et la configuration de l'adresse du serveur client.
|
||||
|
||||
### Option 0 : Déploiement cloud Zeabur en un clic
|
||||
[](https://zeabur.com/templates/SK6T93?referralCode=619dev)
|
||||
|
||||
|
||||
@@ -96,6 +96,8 @@ WeChat スタイルのエンドツーエンド暗号化メッセンジャー。
|
||||
|
||||
---
|
||||
|
||||
> 📖 **[詳細デプロイガイド (中文)](DEPLOY_CN.md)** | **[Deployment Guide (English)](DEPLOY_EN.md)** — Zeabur + Vercel ハイブリッドデプロイ、Docker Compose + Nginx ローカルデプロイ、およびクライアントサーバーアドレス設定の完全なステップバイステップガイド。
|
||||
|
||||
### オプション 0: Zeabur ワンクリッククラウドデプロイ
|
||||
[](https://zeabur.com/templates/SK6T93?referralCode=619dev)
|
||||
|
||||
|
||||
@@ -96,6 +96,8 @@ WeChat 스타일의 종단간 암호화 메신저. 무상태 ECDH + XSalsa20-Pol
|
||||
|
||||
---
|
||||
|
||||
> 📖 **[상세 배포 가이드 (中文)](DEPLOY_CN.md)** | **[Deployment Guide (English)](DEPLOY_EN.md)** — Zeabur + Vercel 하이브리드 배포, Docker Compose + Nginx 로컬 배포 및 클라이언트 서버 주소 구성에 대한 단계별 전체 가이드.
|
||||
|
||||
### 옵션 0: Zeabur 원클릭 클라우드 배포
|
||||
[](https://zeabur.com/templates/SK6T93?referralCode=619dev)
|
||||
|
||||
|
||||
@@ -96,6 +96,8 @@
|
||||
|
||||
---
|
||||
|
||||
> 📖 **[Подробное руководство по развёртыванию (中文)](DEPLOY_CN.md)** | **[Deployment Guide (English)](DEPLOY_EN.md)** — Полные пошаговые инструкции по гибридному развёртыванию Zeabur + Vercel, локальному развёртыванию Docker Compose + Nginx, а также настройке адреса сервера в клиентских приложениях.
|
||||
|
||||
### Вариант 0: Zeabur — облачное развёртывание в один клик
|
||||
[](https://zeabur.com/templates/SK6T93?referralCode=619dev)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user