增加readme和部署说明,内容还需要校验和调整
This commit is contained in:
@@ -0,0 +1,222 @@
|
||||
# Privydrop - Backend
|
||||
|
||||
This is the backend server for Privydrop, a WebRTC based file sharing application. It handles signaling for WebRTC connections, room management, API requests from the frontend, and other related backend logic.
|
||||
|
||||
## Features
|
||||
|
||||
- **WebRTC Signaling:** Facilitates peer-to-peer connections using Socket.IO for exchanging SDP offers, answers, and ICE candidates.
|
||||
- **Room Management:** Allows users to create and join unique rooms for file sharing sessions. Room state and participant information are managed using Redis.
|
||||
- **API Endpoints:** Provides HTTP APIs for the frontend to interact with (e.g., creating/joining rooms, checking room availability).
|
||||
- **Real-time Communication:** Uses Socket.IO for instant messaging between clients and server.
|
||||
- **Rate Limiting:** Basic IP-based rate limiting for certain operations to prevent abuse.
|
||||
- **Ephemeral Data Storage:** Leverages Redis for storing temporary data like room information and session details, with automatic expiry.
|
||||
- **Referrer Tracking:** Basic daily tracking of traffic sources (referrers).
|
||||
|
||||
## Tech Stack
|
||||
|
||||
- **Node.js:** JavaScript runtime environment.
|
||||
- **Express.js:** Web application framework for Node.js.
|
||||
- **TypeScript:** Superset of JavaScript for static typing.
|
||||
- **Socket.IO:** Library for real-time, bidirectional event-based communication.
|
||||
- **Redis:** In-memory data structure store, used for caching, session management, and message brokering.
|
||||
- **ioredis:** A robust Redis client for Node.js.
|
||||
- **CORS:** Middleware for enabling Cross-Origin Resource Sharing.
|
||||
- **dotenv:** Module to load environment variables from a `.env` file.
|
||||
- **PM2 (Ecosystem file provided):** Production process manager for Node.js applications.
|
||||
- **Docker:** Containerization platform.
|
||||
|
||||
## Project Structure
|
||||
|
||||
The backend source code is primarily located in the `src/` directory:
|
||||
.
|
||||
├── DEPLOYMENT.md
|
||||
├── docker # Docker related files (Dockerfile, Nginx/TURN configs if used).
|
||||
│ ├── Dockerfile
|
||||
│ ├── env_install.log
|
||||
│ ├── Nginx
|
||||
│ │ ├── configure.sh
|
||||
│ │ ├── default
|
||||
│ │ ├── nginx.conf
|
||||
│ │ ├── renew_ssl.sh
|
||||
│ │ └── stop_clean-log.sh
|
||||
│ └── TURN
|
||||
│ ├── configure.sh
|
||||
│ ├── turnserver_development.conf
|
||||
│ └── turnserver_production.conf
|
||||
├── docs
|
||||
│ ├── host_preparation.md
|
||||
│ └── turn_nginx_notes.md
|
||||
├── ecosystem.config.js
|
||||
├── package.json
|
||||
├── package-lock.json
|
||||
├── readme.md
|
||||
├── README.md
|
||||
├── scripts
|
||||
│ ├── del_logs.js
|
||||
│ ├── export-tracking-data.js
|
||||
│ └── redis-monitor.js
|
||||
├── src
|
||||
│ ├── config # Environment variables and server configurations (CORS).
|
||||
│ │ ├── env.ts
|
||||
│ │ └── server.ts
|
||||
│ ├── routes # API route definitions (Express routers).
|
||||
│ │ └── api.ts
|
||||
│ ├── server.ts # Main application entry point: Express server and Socket.IO setup.
|
||||
│ ├── services # Core business logic (room management, Redis interactions, rate limiting).
|
||||
│ │ ├── rateLimit.ts
|
||||
│ │ ├── redis.ts
|
||||
│ │ └── room.ts
|
||||
│ ├── socket # Socket.IO event handlers and signaling logic.
|
||||
│ │ └── handlers.ts
|
||||
│ └── types # TypeScript type definitions and interfaces.
|
||||
│ ├── room.ts
|
||||
│ └── socket.ts
|
||||
└── tsconfig.json
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Node.js (v18.x or later recommended)
|
||||
- npm or yarn
|
||||
- A running Redis instance
|
||||
|
||||
## Environment Variables
|
||||
|
||||
Create a `.env.development.local` file in the `backend/` directory for local development (or `.env.production.local` for production-like environments). Populate it with the following variables:
|
||||
|
||||
```ini
|
||||
# Server Configuration
|
||||
PORT=3001
|
||||
NODE_ENV=development # or production
|
||||
CORS_ORIGIN=http://localhost:3000 # URL of your frontend application
|
||||
|
||||
# Redis Configuration
|
||||
REDIS_HOST=127.0.0.1 # Or your Redis server host
|
||||
REDIS_PORT=6379 # Or your Redis server port
|
||||
# REDIS_PASSWORD=your_redis_password # Optional: if your Redis is password protected (code needs adjustment to use this)
|
||||
```
|
||||
|
||||
**Note:** The application will exit on startup if `REDIS_HOST` or `REDIS_PORT` are not defined.
|
||||
|
||||
## Getting Started (Local Development)
|
||||
|
||||
1. **Clone the repository.**
|
||||
2. **Navigate to the `backend/` directory:**
|
||||
```bash
|
||||
cd path/to/your/project/privydrop/backend
|
||||
```
|
||||
3. **Install dependencies:**
|
||||
```bash
|
||||
npm install
|
||||
# or
|
||||
yarn install
|
||||
```
|
||||
4. **Ensure Redis is running** and accessible with the credentials provided in your `.env` file.
|
||||
5. **Create and configure your `.env.development.local` file** as described above.
|
||||
6. **Run the development server:**
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
The server should start on the port specified in your `PORT` environment variable (defaults to 3001).
|
||||
|
||||
## Docker Deployment
|
||||
|
||||
1. **Navigate to the `backend/` directory.** (This assumes your `Dockerfile` is in `backend/docker/Dockerfile` but the build context is `backend/`)
|
||||
2. **Build the Docker image:**
|
||||
```bash
|
||||
docker build -t privydrop-backend -f docker/Dockerfile .
|
||||
```
|
||||
3. **Run the Docker container:**
|
||||
```bash
|
||||
docker run -d \
|
||||
-p 3001:3001 \
|
||||
--name privydrop-backend-container \
|
||||
-e PORT=3001 \
|
||||
-e NODE_ENV=production \
|
||||
-e CORS_ORIGIN="http://your-frontend-domain.com" \
|
||||
-e REDIS_HOST="your-redis-host" \
|
||||
-e REDIS_PORT="your-redis-port" \
|
||||
privydrop-backend
|
||||
```
|
||||
- Adjust `-p` if your internal `PORT` differs or you want to map to a different host port.
|
||||
- Replace placeholder values for environment variables (`-e`).
|
||||
- For a production setup, you'll likely use Docker Compose and might run Nginx as a reverse proxy and a TURN server. Refer to configurations in the `backend/docker/nginx/` and `backend/docker/turn/` directories (if you structure them as suggested) and potentially a `docker-compose.yml` file.
|
||||
|
||||
## API Endpoints
|
||||
|
||||
All API endpoints are prefixed with `/api`.
|
||||
|
||||
- **`POST /api/create_room`**
|
||||
- Creates a new room if the provided `roomId` is unique.
|
||||
- Request Body: `{ "roomId": "string" }`
|
||||
- Response: `{ "success": boolean, "message": "string" }`
|
||||
- **`GET /api/get_room`**
|
||||
- Generates a unique, available room ID and creates the room.
|
||||
- Response: `{ "roomId": "string" }`
|
||||
- **`POST /api/check_room`**
|
||||
- Checks if a given `roomId` is available (i.e., does not exist).
|
||||
- Request Body: `{ "roomId": "string" }`
|
||||
- Response: `{ "available": boolean }`
|
||||
- **`POST /api/set_track`**
|
||||
- Tracks a referrer event. Stores daily statistics in Redis with a 30-day TTL.
|
||||
- Request Body: `{ "ref": "string", "timestamp": number, "path": "string" }`
|
||||
- Response: `{ "success": boolean }`
|
||||
- **`POST /api/logs_debug`** (For frontend debugging)
|
||||
- Receives log messages from the frontend and prints them to the server console.
|
||||
- Request Body: `{ "message": "string", "timestamp": number }`
|
||||
- Response: `{ "success": boolean }`
|
||||
|
||||
## Socket.IO Events
|
||||
|
||||
The server listens for and emits the following Socket.IO events for WebRTC signaling and room communication:
|
||||
|
||||
**Client-to-Server Events:**
|
||||
|
||||
- **`join`**: Client requests to join a room.
|
||||
- Data: `{ roomId: string }`
|
||||
- **`offer`**: Client sends an SDP offer to a peer.
|
||||
- Data: `{ peerId: string, offer: RTCSessionDescriptionInit, from?: string }`
|
||||
- **`answer`**: Client sends an SDP answer to a peer.
|
||||
- Data: `{ peerId: string, answer: RTCSessionDescriptionInit, from?: string }`
|
||||
- **`ice-candidate`**: Client sends an ICE candidate to a peer.
|
||||
- Data: `{ peerId: string, candidate: RTCIceCandidateInit, from?: string }`
|
||||
- **`initiator-online`**: (Custom) Initiator signals it's online/ready in a room.
|
||||
- Data: `{ roomId: string }`
|
||||
- **`recipient-ready`**: (Custom) Recipient signals it's ready in a room.
|
||||
- Data: `{ roomId: string, peerId: string }`
|
||||
|
||||
**Server-to-Client Events:**
|
||||
|
||||
- **`joinResponse`**: Response to a `join` request.
|
||||
- Data: `{ success: boolean, message: string, roomId: string }`
|
||||
- **`ready`**: Notifies clients in a room that a new peer has joined and is ready.
|
||||
- Data: `{ peerId: string }` (ID of the new peer)
|
||||
- **`offer`**: Forwards an SDP offer from one peer to another.
|
||||
- Data: `{ offer: RTCSessionDescriptionInit, peerId: string }` (ID of the sender)
|
||||
- **`answer`**: Forwards an SDP answer from one peer to another.
|
||||
- Data: `{ answer: RTCSessionDescriptionInit, peerId: string }` (ID of the sender)
|
||||
- **`ice-candidate`**: Forwards an ICE candidate from one peer to another.
|
||||
- Data: `{ candidate: RTCIceCandidateInit, peerId: string }` (ID of the sender)
|
||||
- **`initiator-online`**: (Custom) Broadcasts that an initiator is online in the room.
|
||||
- Data: `{ roomId: string }`
|
||||
- **`recipient-ready`**: (Custom) Broadcasts that a recipient is ready.
|
||||
- Data: `{ peerId: string }` (ID of the ready recipient)
|
||||
- **`peer-disconnected`**: Notifies clients in a room that a peer has disconnected.
|
||||
- Data: `{ peerId: string }`
|
||||
|
||||
## Redis Data Usage Summary
|
||||
|
||||
Redis is used for:
|
||||
|
||||
- **Room Information (`room:<roomId>` - Hash):** Stores room creation time. TTL managed.
|
||||
- **Sockets in Room (`room:<roomId>:sockets` - Set):** Stores `socketId`s of clients in a room. TTL tied to room TTL.
|
||||
- **Socket to Room Mapping (`socket:<socketId>` - String):** Maps a `socketId` to its `roomId`. TTL managed.
|
||||
- **Rate Limiting (`ratelimit:join:<ipAddress>` - Sorted Set):** Tracks request timestamps for IP-based rate limiting on join operations. TTL managed.
|
||||
- **Referrer Tracking (`referrers:daily:<YYYY-MM-DD>` - Hash):** Stores daily counts of referrers. TTL of 30 days.
|
||||
|
||||
## Contributing
|
||||
|
||||
(Placeholder for contribution guidelines - e.g., fork, branch, PR, coding standards)
|
||||
|
||||
## License
|
||||
|
||||
(Placeholder for license - e.g., MIT, Apache 2.0)
|
||||
@@ -0,0 +1,222 @@
|
||||
# Privydrop - 后端
|
||||
|
||||
这是 Privydrop 的后端服务器,一个基于 WebRTC 的文件共享应用程序。它处理 WebRTC 连接的信令、房间管理、来自前端的 API 请求以及其他相关的后端逻辑。
|
||||
|
||||
## 功能特性
|
||||
|
||||
- **WebRTC 信令:** 使用 Socket.IO 交换 SDP offers、answers 和 ICE candidates,以促进点对点连接。
|
||||
- **房间管理:** 允许用户创建和加入独特的房间进行文件共享会话。房间状态和参与者信息使用 Redis 进行管理。
|
||||
- **API 端点:** 提供 HTTP API 供前端交互(例如,创建/加入房间、检查房间可用性)。
|
||||
- **实时通信:** 使用 Socket.IO 实现客户端和服务器之间的即时消息传递。
|
||||
- **速率限制:** 对某些操作进行基本的基于 IP 的速率限制,以防止滥用。
|
||||
- **临时数据存储:** 利用 Redis 存储临时数据,如房间信息和会话详情,并具有自动过期功能。
|
||||
- **来源跟踪:** 每日基础的流量来源(referrers)跟踪。
|
||||
|
||||
## 技术栈
|
||||
|
||||
- **Node.js:** JavaScript 运行时环境。
|
||||
- **Express.js:** Node.js 的 Web 应用程序框架。
|
||||
- **TypeScript:** JavaScript 的超集,用于静态类型检查。
|
||||
- **Socket.IO:** 用于实时、双向、基于事件的通信库。
|
||||
- **Redis:** 内存数据结构存储,用作缓存、会话管理和消息代理。
|
||||
- **ioredis:** Node.js 的一个健壮的 Redis 客户端。
|
||||
- **CORS:** 用于启用跨域资源共享的中间件。
|
||||
- **dotenv:** 用于从 `.env` 文件加载环境变量的模块。
|
||||
- **PM2 (已提供 Ecosystem 文件):** Node.js 应用程序的生产流程管理器。
|
||||
- **Docker:** 容器化平台。
|
||||
|
||||
## 项目结构
|
||||
|
||||
后端源代码主要位于 `src/` 目录中:
|
||||
.
|
||||
├── DEPLOYMENT.md
|
||||
├── docker # Docker 相关文件 (Dockerfile, Nginx/TURN 配置等)。
|
||||
│ ├── Dockerfile
|
||||
│ ├── env_install.log
|
||||
│ ├── Nginx
|
||||
│ │ ├── configure.sh
|
||||
│ │ ├── default
|
||||
│ │ ├── nginx.conf
|
||||
│ │ ├── renew_ssl.sh
|
||||
│ │ └── stop_clean-log.sh
|
||||
│ └── TURN
|
||||
│ ├── configure.sh
|
||||
│ ├── turnserver_development.conf
|
||||
│ └── turnserver_production.conf
|
||||
├── docs
|
||||
│ ├── host_preparation.md
|
||||
│ └── turn_nginx_notes.md
|
||||
├── ecosystem.config.js
|
||||
├── package.json
|
||||
├── package-lock.json
|
||||
├── readme.md
|
||||
├── README.md
|
||||
├── scripts
|
||||
│ ├── del_logs.js
|
||||
│ ├── export-tracking-data.js
|
||||
│ └── redis-monitor.js
|
||||
├── src
|
||||
│ ├── config # 环境变量和服务器配置 (CORS)。
|
||||
│ │ ├── env.ts
|
||||
│ │ └── server.ts
|
||||
│ ├── routes # API 路由定义 (Express 路由)。
|
||||
│ │ └── api.ts
|
||||
│ ├── server.ts # 主应用程序入口点:Express 服务器和 Socket.IO 设置。
|
||||
│ ├── services # 核心业务逻辑 (房间管理, Redis 交互, 速率限制)。
|
||||
│ │ ├── rateLimit.ts
|
||||
│ │ ├── redis.ts
|
||||
│ │ └── room.ts
|
||||
│ ├── socket # Socket.IO 事件处理程序和信令逻辑。
|
||||
│ │ └── handlers.ts
|
||||
│ └── types # TypeScript 类型定义和接口。
|
||||
│ ├── room.ts
|
||||
│ └── socket.ts
|
||||
└── tsconfig.json
|
||||
|
||||
## 先决条件
|
||||
|
||||
- Node.js (推荐 v18.x 或更高版本)
|
||||
- npm 或 yarn
|
||||
- 一个正在运行的 Redis 实例
|
||||
|
||||
## 环境变量
|
||||
|
||||
在 `backend/` 目录中创建一个 `.env.development.local` 文件用于本地开发(或为类生产环境创建 `.env.production.local` 文件)。用以下变量填充它:
|
||||
|
||||
```ini
|
||||
# 服务器配置
|
||||
PORT=3001
|
||||
NODE_ENV=development # 或 production
|
||||
CORS_ORIGIN=http://localhost:3000 # 你的前端应用程序 URL
|
||||
|
||||
# Redis 配置
|
||||
REDIS_HOST=127.0.0.1 # 或者你的 Redis 服务器主机
|
||||
REDIS_PORT=6379 # 或者你的 Redis 服务器端口
|
||||
# REDIS_PASSWORD=your_redis_password # 可选:如果你的 Redis 受密码保护(代码需要调整才能使用)
|
||||
```
|
||||
|
||||
**注意:** 如果未定义 `REDIS_HOST` 或 `REDIS_PORT`,应用程序将在启动时退出。
|
||||
|
||||
## 入门 (本地开发)
|
||||
|
||||
1. **克隆仓库。**
|
||||
2. **导航到 `backend/` 目录:**
|
||||
```bash
|
||||
cd path/to/your/project/privydrop/backend
|
||||
```
|
||||
3. **安装依赖:**
|
||||
```bash
|
||||
npm install
|
||||
# 或
|
||||
yarn install
|
||||
```
|
||||
4. **确保 Redis 正在运行**,并且可以使用您在 `.env` 文件中提供的凭据进行访问。
|
||||
5. 如上所述,**创建并配置您的 `.env.development.local` 文件**。
|
||||
6. **运行开发服务器:**
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
服务器应在您 `PORT` 环境变量指定的端口上启动(默认为 3001)。
|
||||
|
||||
## Docker 部署
|
||||
|
||||
1. **导航到 `backend/` 目录。** (这假设您的 `Dockerfile` 位于 `backend/docker/Dockerfile`,但构建上下文是 `backend/`)
|
||||
2. **构建 Docker 镜像:**
|
||||
```bash
|
||||
docker build -t privydrop-backend -f docker/Dockerfile .
|
||||
```
|
||||
3. **运行 Docker 容器:**
|
||||
```bash
|
||||
docker run -d \
|
||||
-p 3001:3001 \
|
||||
--name privydrop-backend-container \
|
||||
-e PORT=3001 \
|
||||
-e NODE_ENV=production \
|
||||
-e CORS_ORIGIN="http://your-frontend-domain.com" \
|
||||
-e REDIS_HOST="your-redis-host" \
|
||||
-e REDIS_PORT="your-redis-port" \
|
||||
privydrop-backend
|
||||
```
|
||||
- 如果您的内部 `PORT` 不同或您想映射到不同的主机端口,请调整 `-p`。
|
||||
- 替换环境变量 (`-e`) 的占位符值。
|
||||
- 对于生产设置,您可能需要使用 Docker Compose,并可能将 Nginx 作为反向代理和 TURN 服务器运行。请参考 `backend/docker/nginx/` 和 `backend/docker/turn/` 目录中的配置(如果您按建议构建它们)以及可能的 `docker-compose.yml` 文件。
|
||||
|
||||
## API 端点
|
||||
|
||||
所有 API 端点都以 `/api` 为前缀。
|
||||
|
||||
- **`POST /api/create_room`**
|
||||
- 如果提供的 `roomId` 是唯一的,则创建一个新房间。
|
||||
- 请求体: `{ "roomId": "string" }`
|
||||
- 响应: `{ "success": boolean, "message": "string" }`
|
||||
- **`GET /api/get_room`**
|
||||
- 生成一个唯一的、可用的房间 ID 并创建房间。
|
||||
- 响应: `{ "roomId": "string" }`
|
||||
- **`POST /api/check_room`**
|
||||
- 检查给定的 `roomId` 是否可用(即不存在)。
|
||||
- 请求体: `{ "roomId": "string" }`
|
||||
- 响应: `{ "available": boolean }`
|
||||
- **`POST /api/set_track`**
|
||||
- 跟踪一个来源事件。在 Redis 中存储每日统计信息,TTL 为 30 天。
|
||||
- 请求体: `{ "ref": "string", "timestamp": number, "path": "string" }`
|
||||
- 响应: `{ "success": boolean }`
|
||||
- **`POST /api/logs_debug`** (用于前端调试)
|
||||
- 从前端接收日志消息并将其打印到服务器控制台。
|
||||
- 请求体: `{ "message": "string", "timestamp": number }`
|
||||
- 响应: `{ "success": boolean }`
|
||||
|
||||
## Socket.IO 事件
|
||||
|
||||
服务器侦听并发出以下 Socket.IO 事件,用于 WebRTC 信令和房间通信:
|
||||
|
||||
**客户端到服务器事件:**
|
||||
|
||||
- **`join`**: 客户端请求加入房间。
|
||||
- 数据: `{ roomId: string }`
|
||||
- **`offer`**: 客户端向对等方发送 SDP offer。
|
||||
- 数据: `{ peerId: string, offer: RTCSessionDescriptionInit, from?: string }`
|
||||
- **`answer`**: 客户端向对等方发送 SDP answer。
|
||||
- 数据: `{ peerId: string, answer: RTCSessionDescriptionInit, from?: string }`
|
||||
- **`ice-candidate`**: 客户端向对等方发送 ICE candidate。
|
||||
- 数据: `{ peerId: string, candidate: RTCIceCandidateInit, from?: string }`
|
||||
- **`initiator-online`**: (自定义) 发起者在房间内发出在线/就绪信号。
|
||||
- 数据: `{ roomId: string }`
|
||||
- **`recipient-ready`**: (自定义) 接收者在房间内发出就绪信号。
|
||||
- 数据: `{ roomId: string, peerId: string }`
|
||||
|
||||
**服务器到客户端事件:**
|
||||
|
||||
- **`joinResponse`**: 对 `join` 请求的响应。
|
||||
- 数据: `{ success: boolean, message: string, roomId: string }`
|
||||
- **`ready`**: 通知房间内的客户端有新的对等方加入并准备就绪。
|
||||
- 数据: `{ peerId: string }` (新对等方的 ID)
|
||||
- **`offer`**: 将一个对等方的 SDP offer 转发给另一个对等方。
|
||||
- 数据: `{ offer: RTCSessionDescriptionInit, peerId: string }` (发送方的 ID)
|
||||
- **`answer`**: 将一个对等方的 SDP answer 转发给另一个对等方。
|
||||
- 数据: `{ answer: RTCSessionDescriptionInit, peerId: string }` (发送方的 ID)
|
||||
- **`ice-candidate`**: 将一个对等方的 ICE candidate 转发给另一个对等方。
|
||||
- 数据: `{ candidate: RTCIceCandidateInit, peerId: string }` (发送方的 ID)
|
||||
- **`initiator-online`**: (自定义) 广播房间内发起者在线。
|
||||
- 数据: `{ roomId: string }`
|
||||
- **`recipient-ready`**: (自定义) 广播接收者已准备就绪。
|
||||
- 数据: `{ peerId: string }` (准备就绪的接收者的 ID)
|
||||
- **`peer-disconnected`**: 通知房间内的客户端有对等方断开连接。
|
||||
- 数据: `{ peerId: string }`
|
||||
|
||||
## Redis 数据使用摘要
|
||||
|
||||
Redis 用于:
|
||||
|
||||
- **房间信息 (`room:<roomId>` - Hash):** 存储房间创建时间。TTL 受管理。
|
||||
- **房间内的套接字 (`room:<roomId>:sockets` - Set):** 存储房间内客户端的 `socketId`。TTL 与房间 TTL 绑定。
|
||||
- **套接字到房间映射 (`socket:<socketId>` - String):** 将 `socketId` 映射到其 `roomId`。TTL 受管理。
|
||||
- **速率限制 (`ratelimit:join:<ipAddress>` - Sorted Set):** 跟踪加入操作的基于 IP 的请求时间戳以进行速率限制。TTL 受管理。
|
||||
- **来源跟踪 (`referrers:daily:<YYYY-MM-DD>` - Hash):** 存储每日来源计数。TTL 为 30 天。
|
||||
|
||||
## 贡献
|
||||
|
||||
(贡献指南占位符 - 例如:fork、branch、PR、编码标准)
|
||||
|
||||
## 许可证
|
||||
|
||||
(许可证占位符 - 例如:MIT、Apache 2.0)
|
||||
@@ -0,0 +1,483 @@
|
||||
# Privydrop Backend Deployment Guide
|
||||
|
||||
This guide provides comprehensive instructions for deploying the Privydrop backend application, including setting up necessary services like Redis, TURN, and Nginx (for production).
|
||||
|
||||
## 1. Introduction
|
||||
|
||||
This document will walk you through the steps to prepare your server environment, configure dependencies, and deploy the Privydrop backend. Whether you are setting up a development/testing environment or a full production instance, this guide aims to cover the essential aspects.
|
||||
|
||||
## 2. Prerequisites
|
||||
|
||||
Before you begin, ensure your server environment meets the following requirements:
|
||||
|
||||
* **Operating System:** A Linux distribution (e.g., Ubuntu 20.04 LTS or later is recommended).
|
||||
* **Node.js:** v18.x or later.
|
||||
* **npm (or yarn):** Package manager for Node.js.
|
||||
* **Git:** For cloning the repository.
|
||||
* **Curl, GnuPG, etc.:** For installing Nginx or other dependencies.
|
||||
* **Root or Sudo Access:** Required for installing packages and configuring services.
|
||||
|
||||
## 3. Dependent Services Installation and Configuration
|
||||
|
||||
The Privydrop backend relies on several external services.
|
||||
|
||||
### 3.1. Redis Server
|
||||
|
||||
Redis is used for room management, session information, and caching.
|
||||
|
||||
**Installation (Ubuntu Example):**
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt install redis-server
|
||||
```
|
||||
|
||||
**Configuration:**
|
||||
- By default, Redis listens on `127.0.0.1:6379` and requires no password.
|
||||
- If your Redis instance is on a different host, port, or requires a password, you will need to update the backend application's environment variables accordingly (see section 4.3).
|
||||
- Ensure Redis is running:
|
||||
```bash
|
||||
sudo systemctl status redis-server
|
||||
# Or for older systems
|
||||
# /etc/init.d/redis-server status
|
||||
```
|
||||
- To start Redis if it's not running:
|
||||
```bash
|
||||
sudo systemctl start redis-server
|
||||
# Or
|
||||
# sudo /etc/init.d/redis-server start
|
||||
```
|
||||
|
||||
### 3.2. TURN/STUN Server (Coturn)
|
||||
|
||||
A TURN server is crucial for WebRTC to traverse NATs and firewalls, ensuring reliable peer-to-peer connections. Coturn is a popular open-source TURN server implementation.
|
||||
|
||||
**Installation (Ubuntu Example):**
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt install coturn
|
||||
```
|
||||
|
||||
**Configuration:**
|
||||
|
||||
1. **Enable Coturn Service:**
|
||||
Edit `/etc/default/coturn` and uncomment the line:
|
||||
```
|
||||
TURNSERVER_ENABLED=1
|
||||
```
|
||||
|
||||
2. **Coturn Configuration File (`/etc/turnserver.conf`):**
|
||||
This is the main configuration file. Below is a comprehensive example. Adapt it to your needs.
|
||||
|
||||
* **For Testing/Development (using IP, no TLS):**
|
||||
```conf
|
||||
# Listening IP address(es) for STUN/TURN. Use your server's private/local IP if behind NAT,
|
||||
# and ensure your TURN_EXTERNAL_IP environment variable for the backend uses the public IP.
|
||||
# If your server has a public IP directly, you can use that.
|
||||
listening-ip=YOUR_SERVER_PRIVATE_OR_PUBLIC_IP
|
||||
|
||||
# External IP address of the server.
|
||||
# This is the IP that clients will use to connect to the TURN server from the internet.
|
||||
# It MUST be set if the server is behind NAT.
|
||||
external-ip=YOUR_SERVER_PUBLIC_IP
|
||||
|
||||
# Realm for the TURN server
|
||||
realm=YOUR_SERVER_PUBLIC_IP # Or your domain for production
|
||||
|
||||
# User for TURN authentication
|
||||
user=YourTurnUsername:YourTurnPassword
|
||||
|
||||
# Listening port for STUN/TURN (UDP and TCP)
|
||||
listening-port=3478
|
||||
|
||||
# Further listening ports for STUN/TURN (UDP and TCP)
|
||||
# alt-listening-port=3479 # Optional
|
||||
|
||||
# Log file
|
||||
log-file=/var/log/turnserver.log
|
||||
verbose
|
||||
|
||||
# Deny TLS/DTLS for non-secure connections if you don't have SSL certs for testing
|
||||
no-tls
|
||||
no-dtls
|
||||
|
||||
# Other recommended settings
|
||||
lt-cred-mech # Use long-term credential mechanism
|
||||
fingerprint # Use fingerprint for STUN messages
|
||||
```
|
||||
|
||||
* **For Production (using Domain, with TLS for TURNS):**
|
||||
```conf
|
||||
# Listening IP address(es)
|
||||
listening-ip=YOUR_SERVER_PRIVATE_OR_PUBLIC_IP
|
||||
|
||||
# External IP address of the server if behind NAT
|
||||
external-ip=YOUR_SERVER_PUBLIC_IP # Must be the public IP
|
||||
|
||||
# Realm for the TURN server - MUST match your domain used for SSL cert
|
||||
realm=turn.yourdomain.com
|
||||
|
||||
# User for TURN authentication
|
||||
user=YourTurnUsername:YourTurnPassword
|
||||
|
||||
# Listening port for STUN/TURN (UDP and TCP) - standard non-TLS
|
||||
listening-port=3478
|
||||
|
||||
# Listening port for TURNS (TLS-TCP)
|
||||
tls-listening-port=5349
|
||||
|
||||
# SSL Certificate and Key for TURNS
|
||||
cert=/etc/letsencrypt/live/turn.yourdomain.com/fullchain.pem
|
||||
pkey=/etc/letsencrypt/live/turn.yourdomain.com/privkey.pem
|
||||
|
||||
# Log file
|
||||
log-file=/var/log/turnserver.log
|
||||
verbose
|
||||
|
||||
# Other recommended settings
|
||||
lt-cred-mech
|
||||
fingerprint
|
||||
# Specify a cipher list if needed, e.g., for older clients, but modern defaults are usually fine.
|
||||
# cipher-list="DEFAULT"
|
||||
```
|
||||
|
||||
3. **Firewall Configuration:**
|
||||
Open the necessary ports on your server's firewall (e.g., using `ufw`):
|
||||
* **TCP & UDP `3478`**: For STUN and TURN.
|
||||
* **TCP & UDP `5349`**: For TURNS (TURN over TLS/DTLS) - *Production*.
|
||||
* **UDP `49152-65533`**: Default relay port range for Coturn (configurable with `min-port` and `max-port` in `turnserver.conf`).
|
||||
```bash
|
||||
sudo ufw allow 3478
|
||||
sudo ufw allow 5349 # For production
|
||||
sudo ufw allow 49152:65535/udp
|
||||
sudo ufw enable
|
||||
sudo ufw status
|
||||
```
|
||||
|
||||
4. **SSL Certificate for Production (TURNS):**
|
||||
If deploying for production and using `TURNS` (TURN over TLS), you need an SSL certificate for your TURN domain (e.g., `turn.yourdomain.com`).
|
||||
* Ensure you have a DNS 'A' record pointing `turn.yourdomain.com` to your server's public IP.
|
||||
* Use Certbot to obtain a certificate:
|
||||
```bash
|
||||
sudo apt install certbot
|
||||
sudo certbot certonly --standalone -d turn.yourdomain.com
|
||||
```
|
||||
The certificate and private key will typically be stored in `/etc/letsencrypt/live/turn.yourdomain.com/`.
|
||||
|
||||
5. **Permissions for SSL Certificates (Production):**
|
||||
The Coturn process (usually runs as user `turnserver`) needs permission to read the SSL certificate and key.
|
||||
* Check current permissions:
|
||||
```bash
|
||||
sudo ls -lh /etc/letsencrypt/live/turn.yourdomain.com/fullchain.pem
|
||||
sudo ls -ld /etc/letsencrypt/archive/
|
||||
```
|
||||
* If Coturn logs show permission errors:
|
||||
Create a group (e.g., `ssl-cert`), add `turnserver` to it, and adjust permissions:
|
||||
```bash
|
||||
sudo groupadd -f ssl-cert
|
||||
# Find the user coturn runs as, usually 'turnserver' or 'coturn'
|
||||
# ps aux | grep turnserver
|
||||
sudo usermod -a -G ssl-cert turnserver # Replace 'turnserver' if it's different
|
||||
sudo chown -R root:ssl-cert /etc/letsencrypt/
|
||||
sudo chmod -R 750 /etc/letsencrypt/
|
||||
```
|
||||
Verify the new permissions on `/etc/letsencrypt/archive/` and `/etc/letsencrypt/live/`.
|
||||
|
||||
6. **Start/Restart and Test Coturn:**
|
||||
```bash
|
||||
sudo systemctl restart coturn
|
||||
sudo systemctl status coturn
|
||||
```
|
||||
Check `/var/log/turnserver.log` for any errors.
|
||||
|
||||
**Testing your TURN server:**
|
||||
Use an online tool like Metered TURN Server Tester (https://www.metered.ca/turn-server-testing):
|
||||
* **For testing (non-TLS):**
|
||||
* TURN URL: `turn:YOUR_SERVER_PUBLIC_IP:3478`
|
||||
* Username: `YourTurnUsername`
|
||||
* Password: `YourTurnPassword`
|
||||
* **For production (TURNS):**
|
||||
* TURNS URL: `turns:turn.yourdomain.com:5349`
|
||||
* Username: `YourTurnUsername`
|
||||
* Password: `YourTurnPassword`
|
||||
Look for "Success" or "Reachable" messages.
|
||||
|
||||
### 3.3. Nginx (Reverse Proxy - Production Environment)
|
||||
|
||||
Nginx is recommended for production environments to act as a reverse proxy, handle SSL termination, serve static files (if applicable), and enable HTTP/3.
|
||||
|
||||
**Installation (with HTTP/3 support, Ubuntu Example):**
|
||||
Ref: https://nginx.org/en/linux_packages.html#Ubuntu
|
||||
|
||||
1. **Install prerequisites:**
|
||||
```bash
|
||||
sudo apt install curl gnupg2 ca-certificates lsb-release ubuntu-keyring
|
||||
```
|
||||
2. **Import Nginx signing key:**
|
||||
```bash
|
||||
curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
|
||||
| sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
|
||||
```
|
||||
3. **Verify the key:**
|
||||
```bash
|
||||
gpg --dry-run --quiet --no-keyring --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg
|
||||
# Expected fingerprint: 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62
|
||||
```
|
||||
4. **Set up apt repository for stable Nginx packages:**
|
||||
```bash
|
||||
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
|
||||
http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" \
|
||||
| sudo tee /etc/apt/sources.list.d/nginx.list
|
||||
```
|
||||
5. **Set up repository pinning:**
|
||||
```bash
|
||||
echo -e "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n" \
|
||||
| sudo tee /etc/apt/preferences.d/99nginx
|
||||
```
|
||||
6. **Install Nginx:**
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt install nginx
|
||||
```
|
||||
|
||||
**Configuration:**
|
||||
|
||||
1. **Firewall Configuration:**
|
||||
* TCP `80` (for HTTP, redirects to HTTPS)
|
||||
* TCP `443` (for HTTPS)
|
||||
* UDP `443` (for HTTP/3 QUIC)
|
||||
```bash
|
||||
sudo ufw allow 'Nginx Full' # Allows HTTP and HTTPS
|
||||
sudo ufw allow 443/udp # For HTTP/3
|
||||
sudo ufw status
|
||||
```
|
||||
|
||||
2. **SSL Certificate for Your Main Domain:**
|
||||
Obtain an SSL certificate for your main application domain (e.g., `yourdomain.com` and `www.yourdomain.com`).
|
||||
```bash
|
||||
# Ensure certbot is installed and configured to work with Nginx
|
||||
sudo apt install python3-certbot-nginx
|
||||
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
|
||||
```
|
||||
Follow the prompts. This will also attempt to configure Nginx for SSL.
|
||||
|
||||
3. **Nginx Configuration (`/etc/nginx/nginx.conf` and server blocks in `/etc/nginx/conf.d/`):**
|
||||
You'll need to configure Nginx to:
|
||||
* Listen on port 80 and redirect to HTTPS.
|
||||
* Listen on port 443 (TCP and UDP for HTTP/3).
|
||||
* Use your SSL certificates.
|
||||
* Proxy pass requests to your backend Node.js application (running on e.g., `localhost:3001`).
|
||||
* Handle WebSocket connections for Socket.IO.
|
||||
* (Optionally) Serve your frontend static files if they are on the same server.
|
||||
|
||||
A basic example server block for your application (`/etc/nginx/conf.d/privydrop.conf`):
|
||||
```nginx
|
||||
map $http_upgrade $connection_upgrade {
|
||||
default upgrade;
|
||||
'' close;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name yourdomain.com www.yourdomain.com;
|
||||
# Redirect all HTTP requests to HTTPS
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
listen [::]:443 ssl http2;
|
||||
# For HTTP/3 (QUIC)
|
||||
listen 443 quic reuseport;
|
||||
listen [::]:443 quic reuseport;
|
||||
|
||||
server_name yourdomain.com www.yourdomain.com;
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
|
||||
include /etc/letsencrypt/options-ssl-nginx.conf; # Recommended SSL settings from Certbot
|
||||
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # Recommended SSL settings from Certbot
|
||||
|
||||
# HTTP/3 specific headers
|
||||
# Tell the browser that HTTP/3 is available
|
||||
add_header Alt-Svc 'h3=":443"; ma=86400';
|
||||
# For 0-RTT
|
||||
# add_header Alt-Svc 'h3=":443"; ma=86400, h3-29=":443"; ma=86400'; # If supporting older h3 drafts
|
||||
# ssl_early_data on; # Nginx 1.15.4+
|
||||
|
||||
# (Optional) If serving frontend from Nginx
|
||||
# root /path/to/your/frontend/build;
|
||||
# index index.html index.htm;
|
||||
|
||||
location / {
|
||||
# If serving frontend:
|
||||
# try_files $uri $uri/ /index.html;
|
||||
|
||||
# If only backend, or for API calls when frontend is separate:
|
||||
proxy_pass http://localhost:3001; # Assuming backend runs on port 3001
|
||||
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_set_header X-Forwarded-Host $host;
|
||||
proxy_set_header X-Forwarded-Port $server_port;
|
||||
proxy_read_timeout 86400s; # For potentially long file transfers
|
||||
proxy_send_timeout 86400s;
|
||||
}
|
||||
|
||||
# Socket.IO specific location (ensure path matches your Socket.IO path)
|
||||
location /socket.io/ {
|
||||
proxy_pass http://localhost:3001; # Assuming backend runs on port 3001
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection $connection_upgrade;
|
||||
proxy_set_header Host $host;
|
||||
}
|
||||
|
||||
# Add other security headers, logging, etc. as needed
|
||||
}
|
||||
```
|
||||
* **Important:** The `nginx.conf` main file should have an `http` block that enables QUIC:
|
||||
```nginx
|
||||
# In /etc/nginx/nginx.conf, inside the http {} block:
|
||||
http {
|
||||
# ... other settings ...
|
||||
quic_retry on; # Nginx 1.25.0+
|
||||
# ... other settings ...
|
||||
}
|
||||
```
|
||||
Ensure your Nginx version supports QUIC and `quic_retry`. The official Nginx packages usually do.
|
||||
|
||||
4. **Test Nginx Configuration and Restart:**
|
||||
```bash
|
||||
sudo nginx -t
|
||||
sudo systemctl restart nginx
|
||||
```
|
||||
|
||||
## 4. Backend Application Deployment
|
||||
|
||||
### 4.1. Get the Code
|
||||
Clone your repository to your server:
|
||||
```bash
|
||||
git clone <your-repository-url> privydrop
|
||||
cd privydrop/backend
|
||||
```
|
||||
|
||||
### 4.2. Install Dependencies
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
### 4.3. Environment Variables
|
||||
|
||||
Create a `.env.production.local` file in the `backend/` directory. This file contains sensitive information and configurations.
|
||||
|
||||
```ini
|
||||
# Server Configuration
|
||||
PORT=3001 # The port your Node.js app will listen on (Nginx will proxy to this)
|
||||
NODE_ENV=production
|
||||
CORS_ORIGIN=https://yourdomain.com # URL of your frontend application
|
||||
|
||||
# Redis Configuration
|
||||
REDIS_HOST=127.0.0.1
|
||||
REDIS_PORT=6379
|
||||
# REDIS_PASSWORD=your_redis_password # If applicable
|
||||
|
||||
# TURN Server Configuration
|
||||
# These are used by the backend to inform clients about the TURN server.
|
||||
# For Testing (if using non-TLS TURN)
|
||||
# TURN_EXTERNAL_IP=YOUR_SERVER_PUBLIC_IP
|
||||
# TURN_REALM=YOUR_SERVER_PUBLIC_IP
|
||||
# TURN_USERNAME=YourTurnUsername
|
||||
# TURN_PASSWORD=YourTurnPassword
|
||||
|
||||
# For Production (if using TURNS)
|
||||
TURN_EXTERNAL_IP=YOUR_SERVER_PUBLIC_IP # The public IP of your TURN server
|
||||
TURN_REALM=turn.yourdomain.com # The realm, usually your TURN domain
|
||||
TURN_USERNAME=YourTurnUsername
|
||||
TURN_PASSWORD=YourTurnPassword
|
||||
TURN_CERT_PATH=/etc/letsencrypt/live/turn.yourdomain.com/fullchain.pem # Path to TURN SSL cert
|
||||
TURN_KEY_PATH=/etc/letsencrypt/live/turn.yourdomain.com/privkey.pem # Path to TURN SSL key
|
||||
# Note: The backend itself doesn't directly use TURN_CERT_PATH/TURN_KEY_PATH
|
||||
# for its own operations but might pass this info or use it for internal validation
|
||||
# if you extend its functionality. The primary user of these paths is Coturn itself.
|
||||
# The backend primarily needs to know the correct TURN URL (derived from these settings)
|
||||
# to send to clients.
|
||||
|
||||
# Nginx Related (Used by helper scripts if any, or for reference)
|
||||
# NGINX_SERVER_NAME=yourdomain.com
|
||||
# NGINX_SSL_CERT=/etc/letsencrypt/live/yourdomain.com/fullchain.pem
|
||||
# NGINX_SSL_KEY=/etc/letsencrypt/live/yourdomain.com/privkey.pem
|
||||
# NGINX_FRONTEND_ROOT=/path/to/your/frontend/build # If Nginx serves frontend
|
||||
```
|
||||
**Important:**
|
||||
* Ensure `CORS_ORIGIN` is correctly set to your frontend's domain for production.
|
||||
* The `TURN_*` variables are critical for the backend to correctly inform clients how to connect to your TURN server.
|
||||
|
||||
### 4.4. Process Management with PM2
|
||||
|
||||
PM2 is a production process manager for Node.js applications.
|
||||
|
||||
1. **Install PM2 globally:**
|
||||
```bash
|
||||
sudo npm install -g pm2
|
||||
```
|
||||
2. **Start the application using the `ecosystem.config.js` file:**
|
||||
The `ecosystem.config.js` file (usually in your project root) defines how PM2 should run your application.
|
||||
```bash
|
||||
# Navigate to your backend directory if not already there
|
||||
# cd /path/to/privydrop/backend
|
||||
|
||||
sudo pm2 start ecosystem.config.js
|
||||
```
|
||||
If you have a previous instance running with the same name (e.g., `signaling-server` as defined in `ecosystem.config.js`):
|
||||
```bash
|
||||
sudo pm2 stop signaling-server && sudo pm2 delete signaling-server
|
||||
sudo pm2 start ecosystem.config.js
|
||||
```
|
||||
3. **Check application status and logs:**
|
||||
```bash
|
||||
sudo pm2 list
|
||||
sudo pm2 logs signaling-server # Or the name defined in your ecosystem file
|
||||
sudo pm2 monit
|
||||
```
|
||||
4. **Enable PM2 to start on system boot:**
|
||||
```bash
|
||||
sudo pm2 startup
|
||||
# Follow the instructions provided by the command (usually involves running another command it outputs)
|
||||
sudo pm2 save # Save current process list
|
||||
```
|
||||
|
||||
### 4.5. Firewall for Backend Application
|
||||
If your backend application's port (`3001` by default) is not proxied by Nginx for all access (e.g., health checks directly to the app), ensure it's open in the firewall. However, for typical production setups with Nginx, only Nginx ports (80, 443) need to be publicly accessible.
|
||||
```bash
|
||||
# Only if direct access to Node.js app is needed and not through Nginx
|
||||
# sudo ufw allow 3001/tcp
|
||||
```
|
||||
|
||||
## 5. Dockerized Deployment (Advanced/Optional)
|
||||
|
||||
While this guide focuses on a traditional deployment, you can also containerize the Privydrop backend. Refer to the `Dockerfile` in the `backend/docker/` directory and the Docker deployment section in `README.md` for basic Docker build and run commands.
|
||||
|
||||
For a production Docker setup, consider using `docker-compose` to orchestrate the backend application, Nginx (as a reverse proxy within Docker or on the host), Redis, and potentially Coturn (though Coturn often runs better directly on the host for network access). Managing SSL certificates and network configurations requires careful planning in a Dockerized environment.
|
||||
|
||||
## 6. Security and Maintenance
|
||||
|
||||
* **Regular Updates:** Keep your server's OS, Nginx, Node.js, PM2, and all other software packages updated.
|
||||
* **SSL Certificate Renewal:** Certbot usually sets up automatic renewal. You can test it with `sudo certbot renew --dry-run`. Ensure the renewal process has permissions to restart Nginx if needed.
|
||||
* **Log Management:** Regularly monitor logs for Nginx (`/var/log/nginx/`), Coturn (`/var/log/turnserver.log`), and your application (via PM2). Set up log rotation.
|
||||
* **Firewall:** Keep your firewall rules strict, only allowing necessary ports.
|
||||
* **Application Dependencies:** Regularly update Node.js dependencies (`npm update`) and test thoroughly.
|
||||
|
||||
## 7. Troubleshooting
|
||||
|
||||
* **Connection Issues:** Check firewall rules, Nginx proxy settings, `CORS_ORIGIN` in your backend .env file, and ensure all services (Redis, Coturn, Node.js app) are running.
|
||||
* **WebRTC Failures:** Use `chrome://webrtc-internals` (or Firefox equivalent) for debugging. Test your TURN server independently. Ensure `TURN_EXTERNAL_IP` and `TURN_REALM` are correctly set.
|
||||
* **Nginx Errors:** `sudo nginx -t` will check configuration syntax. Examine Nginx error logs.
|
||||
* **PM2 Issues:** Use `pm2 logs <app_name>` to see application errors.
|
||||
* **Certificate Permissions:** If Coturn or Nginx can't read SSL certificates, double-check file permissions and group memberships.
|
||||
|
||||
---
|
||||
This is a draft and can be expanded with more details, specific configurations for different Linux distributions, or more advanced topics.
|
||||
@@ -0,0 +1,482 @@
|
||||
# Privydrop 后端部署指南
|
||||
|
||||
本指南提供部署 Privydrop 后端应用程序的全面说明,包括设置 Redis、TURN 和 Nginx(用于生产环境)等必要服务。
|
||||
|
||||
## 1. 引言
|
||||
|
||||
本文档将引导您完成准备服务器环境、配置依赖项和部署 Privydrop 后端的步骤。无论您是设置开发/测试环境还是完整的生产实例,本指南都旨在涵盖基本方面。
|
||||
|
||||
## 2. 先决条件
|
||||
|
||||
在开始之前,请确保您的服务器环境满足以下要求:
|
||||
|
||||
* **操作系统:** Linux 发行版(例如,推荐 Ubuntu 20.04 LTS 或更高版本)。
|
||||
* **Node.js:** v18.x 或更高版本。
|
||||
* **npm (或 yarn):** Node.js 的包管理器。
|
||||
* **Git:** 用于克隆代码仓库。
|
||||
* **Curl、GnuPG 等:** 用于安装 Nginx 或其他依赖项。
|
||||
* **Root 或 Sudo 权限:** 安装软件包和配置服务所需。
|
||||
|
||||
## 3. 依赖服务安装与配置
|
||||
|
||||
Privydrop 后端依赖于多个外部服务。
|
||||
|
||||
### 3.1. Redis 服务器
|
||||
|
||||
Redis 用于房间管理、会话信息和缓存。
|
||||
|
||||
**安装 (Ubuntu 示例):**
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt install redis-server
|
||||
```
|
||||
|
||||
**配置:**
|
||||
- 默认情况下,Redis 监听 `127.0.0.1:6379` 并且不需要密码。
|
||||
- 如果您的 Redis 实例位于不同的主机、端口或需要密码,则需要相应地更新后端应用程序的环境变量(参见第 4.3 节)。
|
||||
- 确保 Redis 正在运行:
|
||||
```bash
|
||||
sudo systemctl status redis-server
|
||||
# 或对于旧系统
|
||||
# /etc/init.d/redis-server status
|
||||
```
|
||||
- 如果 Redis 未运行,则启动它:
|
||||
```bash
|
||||
sudo systemctl start redis-server
|
||||
# 或
|
||||
# sudo /etc/init.d/redis-server start
|
||||
```
|
||||
|
||||
### 3.2. TURN/STUN 服务器 (Coturn)
|
||||
|
||||
TURN 服务器对于 WebRTC 穿透 NAT 和防火墙至关重要,可确保可靠的点对点连接。Coturn 是一个流行的开源 TURN 服务器实现。
|
||||
|
||||
**安装 (Ubuntu 示例):**
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt install coturn
|
||||
```
|
||||
|
||||
**配置:**
|
||||
|
||||
1. **启用 Coturn 服务:**
|
||||
编辑 `/etc/default/coturn` 并取消注释该行:
|
||||
```
|
||||
TURNSERVER_ENABLED=1
|
||||
```
|
||||
|
||||
2. **Coturn 配置文件 (`/etc/turnserver.conf`):**
|
||||
这是主要的配置文件。以下是一个综合示例,请根据您的需求进行调整。
|
||||
|
||||
* **用于测试/开发 (使用 IP,无 TLS):**
|
||||
```conf
|
||||
# STUN/TURN 的监听 IP 地址。如果服务器在 NAT 之后,请使用服务器的私有/本地 IP,
|
||||
# 并确保后端的 TURN_EXTERNAL_IP 环境变量使用公网 IP。
|
||||
# 如果您的服务器直接拥有公网 IP,则可以使用该 IP。
|
||||
listening-ip=你的服务器私有或公网IP
|
||||
|
||||
# 服务器的外部 IP 地址。
|
||||
# 这是客户端从互联网连接到 TURN 服务器将使用的 IP。
|
||||
# 如果服务器位于 NAT 之后,则必须设置此项。
|
||||
external-ip=你的服务器公网IP
|
||||
|
||||
# TURN 服务器的 realm
|
||||
realm=你的服务器公网IP # 或用于生产环境的域名
|
||||
|
||||
# TURN 认证用户
|
||||
user=你的Turn用户名:你的Turn密码
|
||||
|
||||
# STUN/TURN 的监听端口 (UDP 和 TCP)
|
||||
listening-port=3478
|
||||
|
||||
# STUN/TURN 的其他监听端口 (UDP 和 TCP)
|
||||
# alt-listening-port=3479 # 可选
|
||||
|
||||
# 日志文件
|
||||
log-file=/var/log/turnserver.log
|
||||
verbose
|
||||
|
||||
# 如果测试时没有 SSL 证书,则禁用 TLS/DTLS
|
||||
no-tls
|
||||
no-dtls
|
||||
|
||||
# 其他推荐设置
|
||||
lt-cred-mech # 使用长期凭证机制
|
||||
fingerprint # 对 STUN 消息使用指纹
|
||||
```
|
||||
|
||||
* **用于生产 (使用域名,并为 TURNS 配置 TLS):**
|
||||
```conf
|
||||
# 监听 IP 地址
|
||||
listening-ip=你的服务器私有或公网IP
|
||||
|
||||
# 如果服务器在 NAT 之后,则为服务器的外部 IP 地址
|
||||
external-ip=你的服务器公网IP # 必须是公网 IP
|
||||
|
||||
# TURN 服务器的 realm - 必须与 SSL 证书使用的域名匹配
|
||||
realm=turn.yourdomain.com
|
||||
|
||||
# TURN 认证用户
|
||||
user=你的Turn用户名:你的Turn密码
|
||||
|
||||
# STUN/TURN 的监听端口 (UDP 和 TCP) - 标准非 TLS
|
||||
listening-port=3478
|
||||
|
||||
# TURNS (TLS-TCP) 的监听端口
|
||||
tls-listening-port=5349
|
||||
|
||||
# TURNS 使用的 SSL 证书和密钥
|
||||
cert=/etc/letsencrypt/live/turn.yourdomain.com/fullchain.pem
|
||||
pkey=/etc/letsencrypt/live/turn.yourdomain.com/privkey.pem
|
||||
|
||||
# 日志文件
|
||||
log-file=/var/log/turnserver.log
|
||||
verbose
|
||||
|
||||
# 其他推荐设置
|
||||
lt-cred-mech
|
||||
fingerprint
|
||||
# 如果需要,指定密码套件列表,例如为了兼容旧客户端,但现代默认值通常没问题。
|
||||
# cipher-list="DEFAULT"
|
||||
```
|
||||
|
||||
3. **防火墙配置:**
|
||||
在服务器的防火墙上打开必要的端口 (例如,使用 `ufw`):
|
||||
* **TCP & UDP `3478`**: 用于 STUN 和 TURN。
|
||||
* **TCP & UDP `5349`**: 用于 TURNS (TURN over TLS/DTLS) - *生产环境*。
|
||||
* **UDP `49152-65533`**: Coturn 的默认中继端口范围 (可在 `turnserver.conf` 中使用 `min-port` 和 `max-port` 配置)。
|
||||
```bash
|
||||
sudo ufw allow 3478
|
||||
sudo ufw allow 5349 # 用于生产环境
|
||||
sudo ufw allow 49152:65535/udp
|
||||
sudo ufw enable
|
||||
sudo ufw status
|
||||
```
|
||||
|
||||
4. **生产环境的 SSL 证书 (TURNS):**
|
||||
如果为生产环境部署并使用 `TURNS` (TURN over TLS),您需要为您的 TURN 域名(例如 `turn.yourdomain.com`)准备 SSL 证书。
|
||||
* 确保您有一个 DNS 'A' 记录将 `turn.yourdomain.com` 指向您服务器的公网 IP。
|
||||
* 使用 Certbot 获取证书:
|
||||
```bash
|
||||
sudo apt install certbot
|
||||
sudo certbot certonly --standalone -d turn.yourdomain.com
|
||||
```
|
||||
证书和私钥通常存储在 `/etc/letsencrypt/live/turn.yourdomain.com/`。
|
||||
|
||||
5. **SSL 证书权限 (生产环境):**
|
||||
Coturn 进程(通常以用户 `turnserver` 运行)需要读取 SSL 证书和密钥的权限。
|
||||
* 检查当前权限:
|
||||
```bash
|
||||
sudo ls -lh /etc/letsencrypt/live/turn.yourdomain.com/fullchain.pem
|
||||
sudo ls -ld /etc/letsencrypt/archive/
|
||||
```
|
||||
* 如果 Coturn 日志显示权限错误:
|
||||
创建一个组(例如 `ssl-cert`),将 `turnserver` 添加到该组,并调整权限:
|
||||
```bash
|
||||
sudo groupadd -f ssl-cert
|
||||
# 查找 coturn 运行的用户,通常是 'turnserver' 或 'coturn'
|
||||
# ps aux | grep turnserver
|
||||
sudo usermod -a -G ssl-cert turnserver # 如果不同,请替换 'turnserver'
|
||||
sudo chown -R root:ssl-cert /etc/letsencrypt/
|
||||
sudo chmod -R 750 /etc/letsencrypt/
|
||||
```
|
||||
验证 `/etc/letsencrypt/archive/` 和 `/etc/letsencrypt/live/` 上的新权限。
|
||||
|
||||
6. **启动/重启并测试 Coturn:**
|
||||
```bash
|
||||
sudo systemctl restart coturn
|
||||
sudo systemctl status coturn
|
||||
```
|
||||
检查 `/var/log/turnserver.log` 中是否有任何错误。
|
||||
|
||||
**测试您的 TURN 服务器:**
|
||||
使用在线工具,如 Metered TURN Server Tester (https://www.metered.ca/turn-server-testing):
|
||||
* **用于测试 (非 TLS):**
|
||||
* TURN URL: `turn:你的服务器公网IP:3478`
|
||||
* 用户名: `你的Turn用户名`
|
||||
* 密码: `你的Turn密码`
|
||||
* **用于生产 (TURNS):**
|
||||
* TURNS URL: `turns:turn.yourdomain.com:5349`
|
||||
* 用户名: `你的Turn用户名`
|
||||
* 密码: `你的Turn密码`
|
||||
查找 "Success" 或 "Reachable" 消息。
|
||||
|
||||
### 3.3. Nginx (反向代理 - 生产环境)
|
||||
|
||||
建议在生产环境中使用 Nginx 作为反向代理,处理 SSL 终止、提供静态文件(如果适用)并启用 HTTP/3。
|
||||
|
||||
**安装 (支持 HTTP/3,Ubuntu 示例):**
|
||||
参考: https://nginx.org/en/linux_packages.html#Ubuntu
|
||||
|
||||
1. **安装先决条件:**
|
||||
```bash
|
||||
sudo apt install curl gnupg2 ca-certificates lsb-release ubuntu-keyring
|
||||
```
|
||||
2. **导入 Nginx 签名密钥:**
|
||||
```bash
|
||||
curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
|
||||
| sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
|
||||
```
|
||||
3. **验证密钥:**
|
||||
```bash
|
||||
gpg --dry-run --quiet --no-keyring --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg
|
||||
# 期望指纹: 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62
|
||||
```
|
||||
4. **为稳定版 Nginx 包设置 apt 仓库:**
|
||||
```bash
|
||||
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
|
||||
http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" \
|
||||
| sudo tee /etc/apt/sources.list.d/nginx.list
|
||||
```
|
||||
5. **设置仓库 pinning:**
|
||||
```bash
|
||||
echo -e "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n" \
|
||||
| sudo tee /etc/apt/preferences.d/99nginx
|
||||
```
|
||||
6. **安装 Nginx:**
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt install nginx
|
||||
```
|
||||
|
||||
**配置:**
|
||||
|
||||
1. **防火墙配置:**
|
||||
* TCP `80` (用于 HTTP,重定向到 HTTPS)
|
||||
* TCP `443` (用于 HTTPS)
|
||||
* UDP `443` (用于 HTTP/3 QUIC)
|
||||
```bash
|
||||
sudo ufw allow 'Nginx Full' # 允许 HTTP 和 HTTPS
|
||||
sudo ufw allow 443/udp # 用于 HTTP/3
|
||||
sudo ufw status
|
||||
```
|
||||
|
||||
2. **主域名 SSL 证书:**
|
||||
为您的主应用程序域名(例如 `yourdomain.com` 和 `www.yourdomain.com`)获取 SSL 证书。
|
||||
```bash
|
||||
# 确保已安装 certbot 并配置为与 Nginx 一起使用
|
||||
sudo apt install python3-certbot-nginx
|
||||
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
|
||||
```
|
||||
按照提示操作。这也会尝试为 SSL 配置 Nginx。
|
||||
|
||||
3. **Nginx 配置 (`/etc/nginx/nginx.conf` 和 `/etc/nginx/conf.d/` 中的 server blocks):**
|
||||
您需要配置 Nginx 以:
|
||||
* 监听端口 80 并重定向到 HTTPS。
|
||||
* 监听端口 443 (TCP 和 UDP 用于 HTTP/3)。
|
||||
* 使用您的 SSL 证书。
|
||||
* 将请求代理传递到您的后端 Node.js 应用程序(例如,运行在 `localhost:3001`)。
|
||||
* 处理 Socket.IO 的 WebSocket 连接。
|
||||
* (可选)如果前端静态文件在同一服务器上,则由 Nginx 提供服务。
|
||||
|
||||
您的应用程序的基本 server block 示例 (`/etc/nginx/conf.d/privydrop.conf`):
|
||||
```nginx
|
||||
map $http_upgrade $connection_upgrade {
|
||||
default upgrade;
|
||||
'' close;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name yourdomain.com www.yourdomain.com;
|
||||
# 将所有 HTTP 请求重定向到 HTTPS
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
listen [::]:443 ssl http2;
|
||||
# 用于 HTTP/3 (QUIC)
|
||||
listen 443 quic reuseport;
|
||||
listen [::]:443 quic reuseport;
|
||||
|
||||
server_name yourdomain.com www.yourdomain.com;
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
|
||||
include /etc/letsencrypt/options-ssl-nginx.conf; # Certbot 推荐的 SSL 设置
|
||||
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # Certbot 推荐的 SSL 设置
|
||||
|
||||
# HTTP/3 特定头部
|
||||
# 告知浏览器 HTTP/3 可用
|
||||
add_header Alt-Svc 'h3=":443"; ma=86400';
|
||||
# 用于 0-RTT
|
||||
# add_header Alt-Svc 'h3=":443"; ma=86400, h3-29=":443"; ma=86400'; # 如果支持较旧的 h3 草案
|
||||
# ssl_early_data on; # Nginx 1.15.4+
|
||||
|
||||
# (可选) 如果由 Nginx 提供前端服务
|
||||
# root /path/to/your/frontend/build;
|
||||
# index index.html index.htm;
|
||||
|
||||
location / {
|
||||
# 如果提供前端服务:
|
||||
# try_files $uri $uri/ /index.html;
|
||||
|
||||
# 如果只有后端,或者当与前端分离时用于 API 调用:
|
||||
proxy_pass http://localhost:3001; # 假设后端运行在端口 3001
|
||||
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_set_header X-Forwarded-Host $host;
|
||||
proxy_set_header X-Forwarded-Port $server_port;
|
||||
proxy_read_timeout 86400s; # 适用于可能较长的文件传输
|
||||
proxy_send_timeout 86400s;
|
||||
}
|
||||
|
||||
# Socket.IO 特定 location (确保路径与您的 Socket.IO 路径匹配)
|
||||
location /socket.io/ {
|
||||
proxy_pass http://localhost:3001; # 假设后端运行在端口 3001
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection $connection_upgrade;
|
||||
proxy_set_header Host $host;
|
||||
}
|
||||
|
||||
# 根据需要添加其他安全头部、日志记录等
|
||||
}
|
||||
```
|
||||
* **重要:** `nginx.conf` 主文件应包含一个启用 QUIC 的 `http` 块:
|
||||
```nginx
|
||||
# 在 /etc/nginx/nginx.conf 中,位于 http {} 块内部:
|
||||
http {
|
||||
# ... 其他设置 ...
|
||||
quic_retry on; # Nginx 1.25.0+
|
||||
# ... 其他设置 ...
|
||||
}
|
||||
```
|
||||
确保您的 Nginx 版本支持 QUIC 和 `quic_retry`。官方 Nginx 包通常支持。
|
||||
|
||||
4. **测试 Nginx 配置并重启:**
|
||||
```bash
|
||||
sudo nginx -t
|
||||
sudo systemctl restart nginx
|
||||
```
|
||||
|
||||
## 4. 后端应用部署
|
||||
|
||||
### 4.1. 获取代码
|
||||
将您的仓库克隆到服务器:
|
||||
```bash
|
||||
git clone <your-repository-url> privydrop
|
||||
cd privydrop/backend
|
||||
```
|
||||
|
||||
### 4.2. 安装依赖
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
### 4.3. 环境变量
|
||||
|
||||
在 `backend/` 目录中创建一个 `.env.production.local` 文件。此文件包含敏感信息和配置。
|
||||
|
||||
```ini
|
||||
# 服务器配置
|
||||
PORT=3001 # Node.js 应用监听的端口 (Nginx 将代理到此端口)
|
||||
NODE_ENV=production
|
||||
CORS_ORIGIN=https://yourdomain.com # 你的前端应用程序 URL
|
||||
|
||||
# Redis 配置
|
||||
REDIS_HOST=127.0.0.1
|
||||
REDIS_PORT=6379
|
||||
# REDIS_PASSWORD=your_redis_password # 如果适用
|
||||
|
||||
# TURN 服务器配置
|
||||
# 后端使用这些配置来通知客户端有关 TURN 服务器的信息。
|
||||
# 用于测试 (如果使用非 TLS TURN)
|
||||
# TURN_EXTERNAL_IP=你的服务器公网IP
|
||||
# TURN_REALM=你的服务器公网IP
|
||||
# TURN_USERNAME=你的Turn用户名
|
||||
# TURN_PASSWORD=你的Turn密码
|
||||
|
||||
# 用于生产 (如果使用 TURNS)
|
||||
TURN_EXTERNAL_IP=你的服务器公网IP # TURN 服务器的公网 IP
|
||||
TURN_REALM=turn.yourdomain.com # Realm, 通常是你的 TURN 域名
|
||||
TURN_USERNAME=你的Turn用户名
|
||||
TURN_PASSWORD=你的Turn密码
|
||||
TURN_CERT_PATH=/etc/letsencrypt/live/turn.yourdomain.com/fullchain.pem # TURN SSL 证书路径
|
||||
TURN_KEY_PATH=/etc/letsencrypt/live/turn.yourdomain.com/privkey.pem # TURN SSL 密钥路径
|
||||
# 注意:后端本身并不直接使用 TURN_CERT_PATH/TURN_KEY_PATH
|
||||
# 进行其自身操作,但如果您扩展其功能,则可能会传递此信息或将其用于内部验证。
|
||||
# 这些路径的主要用户是 Coturn 本身。
|
||||
# 后端主要需要知道正确的 TURN URL (从这些设置派生) 以发送给客户端。
|
||||
|
||||
# Nginx 相关 (如果存在辅助脚本,则由它们使用,或供参考)
|
||||
# NGINX_SERVER_NAME=yourdomain.com
|
||||
# NGINX_SSL_CERT=/etc/letsencrypt/live/yourdomain.com/fullchain.pem
|
||||
# NGINX_SSL_KEY=/etc/letsencrypt/live/yourdomain.com/privkey.pem
|
||||
# NGINX_FRONTEND_ROOT=/path/to/your/frontend/build # 如果 Nginx 提供前端服务
|
||||
```
|
||||
**重要:**
|
||||
* 确保 `CORS_ORIGIN` 正确设置为您生产环境前端的域名。
|
||||
* `TURN_*` 变量对于后端正确通知客户端如何连接到您的 TURN 服务器至关重要。
|
||||
|
||||
### 4.4. 使用 PM2 进行进程管理
|
||||
|
||||
PM2 是 Node.js 应用程序的生产流程管理器。
|
||||
|
||||
1. **全局安装 PM2:**
|
||||
```bash
|
||||
sudo npm install -g pm2
|
||||
```
|
||||
2. **使用 `ecosystem.config.js` 文件启动应用程序:**
|
||||
`ecosystem.config.js` 文件(通常在您的项目根目录中)定义了 PM2 应如何运行您的应用程序。
|
||||
```bash
|
||||
# 如果尚未在后端目录中,请导航至该目录
|
||||
# cd /path/to/privydrop/backend
|
||||
|
||||
sudo pm2 start ecosystem.config.js
|
||||
```
|
||||
如果您先前运行的实例具有相同的名称(例如,在 `ecosystem.config.js` 中定义的 `signaling-server`):
|
||||
```bash
|
||||
sudo pm2 stop signaling-server && sudo pm2 delete signaling-server
|
||||
sudo pm2 start ecosystem.config.js
|
||||
```
|
||||
3. **检查应用程序状态和日志:**
|
||||
```bash
|
||||
sudo pm2 list
|
||||
sudo pm2 logs signaling-server # 或您 ecosystem 文件中定义的名称
|
||||
sudo pm2 monit
|
||||
```
|
||||
4. **使 PM2 能够开机自启:**
|
||||
```bash
|
||||
sudo pm2 startup
|
||||
# 遵循命令提供的说明 (通常涉及运行它输出的另一个命令)
|
||||
sudo pm2 save # 保存当前进程列表
|
||||
```
|
||||
|
||||
### 4.5. 后端应用程序防火墙
|
||||
如果您的后端应用程序端口(默认为 `3001`)并未由 Nginx 代理所有访问(例如,直接到应用程序的健康检查),请确保它在防火墙中已打开。但是,对于典型的 Nginx 生产设置,通常只需要 Nginx 端口(80、443)可公开访问。
|
||||
```bash
|
||||
# 仅当需要直接访问 Node.js 应用且不通过 Nginx 时
|
||||
# sudo ufw allow 3001/tcp
|
||||
```
|
||||
|
||||
## 5. Docker 化部署 (进阶/可选)
|
||||
|
||||
虽然本指南侧重于传统部署,但您也可以将 Privydrop 后端容器化。有关基本的 Docker 构建和运行命令,请参阅 `backend/docker/` 目录中的 `Dockerfile` 以及 `README.md` 中的 Docker 部署部分。
|
||||
|
||||
对于生产 Docker 设置,请考虑使用 `docker-compose` 来编排后端应用程序、Nginx(作为 Docker 内或主机上的反向代理)、Redis 以及可能的 Coturn(尽管 Coturn 通常直接在主机上运行以获得更好的网络访问效果)。在 Docker化环境中管理 SSL 证书和网络配置需要仔细规划。
|
||||
|
||||
## 6. 安全与维护
|
||||
|
||||
* **定期更新:** 保持服务器的操作系统、Nginx、Node.js、PM2 和所有其他软件包为最新状态。
|
||||
* **SSL 证书续订:** Certbot 通常会设置自动续订。您可以使用 `sudo certbot renew --dry-run` 进行测试。确保续订过程有权在需要时重新启动 Nginx。
|
||||
* **日志管理:** 定期监控 Nginx (`/var/log/nginx/`)、Coturn (`/var/log/turnserver.log`) 和您的应用程序(通过 PM2)的日志。设置日志轮替。
|
||||
* **防火墙:** 保持防火墙规则严格,仅允许必要的端口。
|
||||
* **应用程序依赖项:** 定期更新 Node.js 依赖项 (`npm update`) 并进行全面测试。
|
||||
|
||||
## 7. 故障排除
|
||||
|
||||
* **连接问题:** 检查防火墙规则、Nginx 代理设置、后端 .env 文件中的 `CORS_ORIGIN`,并确保所有服务(Redis、Coturn、Node.js 应用)都在运行。
|
||||
* **WebRTC 失败:** 使用 `chrome://webrtc-internals`(或 Firefox 等效工具)进行调试。独立测试您的 TURN 服务器。确保 `TURN_EXTERNAL_IP` 和 `TURN_REALM` 设置正确。
|
||||
* **Nginx 错误:** `sudo nginx -t` 将检查配置语法。检查 Nginx 错误日志。
|
||||
* **PM2 问题:** 使用 `pm2 logs <app_name>` 查看应用程序错误。
|
||||
* **证书权限:** 如果 Coturn 或 Nginx 无法读取 SSL 证书,请仔细检查文件权限和组成员身份。
|
||||
|
||||
---
|
||||
这是一个草稿,可以根据需要扩展更多详细信息、针对不同 Linux 发行版的特定配置或更高级的主题。
|
||||
Reference in New Issue
Block a user