Files
astro-jiao77.cn/docs/SINGLE_VPS_DEPLOYMENT_PLAN.md
2025-10-21 01:44:01 +08:00

1146 lines
27 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 🚀 单机 VPS 部署方案 - 优化 TodoList
**部署环境**:单机 VPS公网 IP + 大带宽 + 100GB 存储)
**优化方向**:资源优化、单机部署、简化运维
**项目周期**4-5 周 | **总任务数**72 项 | **优先级分布**P0(20) | P1(30) | P2(15) | P3(7)
---
## 📋 环境特点分析
### ✅ 优势
- 单一公网 IP简化网络配置
- 大带宽支持高并发
- 100GB 存储足够应用 + 数据库 + 备份
### ⚠️ 制约
- 单机故障 = 全部服务宕机
- 内存/CPU 有限(需要优化)
- 需要更严格的监控和备份
### 🎯 优化策略
1. **容器精简** - 使用 Alpine 基础镜像
2. **资源共享** - 数据库、应用、Web 服务器在同一机器
3. **缓存优先** - Redis 缓存热数据
4. **监控告警** - 及时发现问题
5. **自动备份** - 防止数据丢失
---
## 🎯 第一阶段:环境准备与优化(第 1 周)
### 🔴 P0 任务VPS 环境初始化
#### 1.1 VPS 系统准备
- [ ] SSH 连接 VPS验证系统版本建议 Ubuntu 20.04 LTS
- [ ] 更新系统:`sudo apt update && apt upgrade -y`
- [ ] 安装基础工具:`sudo apt install -y curl wget git htop`
- [ ] 配置防火墙UFW
```bash
sudo ufw enable
sudo ufw allow 22/tcp # SSH
sudo ufw allow 80/tcp # HTTP
sudo ufw allow 443/tcp # HTTPS
```
- [ ] 配置时区和 NTP
- [ ] 创建普通用户用于应用运行(非 root
#### 1.2 Docker 和 Docker Compose 安装
- [ ] 安装 Docker`curl -fsSL https://get.docker.com | sh`
- [ ] 配置 Docker 权限:添加用户到 docker 组
- [ ] 安装 Docker Compose最新版本
- [ ] 验证 Docker 和 Compose 可用性
#### 1.3 域名和 SSL 配置
- [ ] 配置域名 DNS 解析到公网 IP
- [ ] 申请 Let's Encrypt SSL 证书(使用 Certbot
- [ ] 配置 SSL 证书自动续期
- [ ] 测试 HTTPS 连接
#### 1.4 存储规划
- [ ] 检查磁盘使用情况:`df -h`
- [ ] 规划存储分配100GB
```
系统20GB
数据库30GB
应用20GB
备份20GB
日志10GB
```
- [ ] 创建数据目录结构
### 🟠 P1 任务:后端项目创建
#### 1.5 创建后端项目
- [ ] 在 VPS 上克隆项目:`git clone <repo> /home/app/backend`
- [ ] 创建 `/backend` 目录结构
```
backend/
├── src/
│ ├── server.ts
│ ├── config/
│ ├── routes/
│ ├── controllers/
│ ├── middleware/
│ ├── database/
│ └── types/
├── docker/
│ ├── Dockerfile
│ └── .dockerignore
├── scripts/
│ ├── db-init.sql
│ └── backup.sh
├── package.json
├── tsconfig.json
└── .env
```
- [ ] 本地初始化 Node.js 项目npm init
- [ ] 编写最小化 package.json仅必需依赖
#### 1.6 依赖选择(针对单机优化)
- [ ] 后端依赖:
```json
{
"express": "^4.18.2",
"pg": "^8.10.0",
"cors": "^2.8.5",
"dotenv": "^16.3.1",
"zod": "^3.22.4",
"pino": "^8.16.1"
}
```
- [ ] 开发依赖:
```json
{
"typescript": "^5.2.2",
"ts-node": "^10.9.1",
"nodemon": "^3.0.1",
"@types/express": "^4.17.20",
"@types/node": "^20.8.0",
"jest": "^29.7.0",
"@types/jest": "^29.5.6"
}
```
- [ ] **移除不必要包**@astrojs/node, 重量级 ORM 等
### 🟡 P2 任务:文档和规划
#### 1.7 部署文档编写
- [ ] 编写 VPS 部署指南
- [ ] 记录环境配置清单
- [ ] 编写故障恢复流程
- [ ] 编写备份和恢复步骤
---
## 🎯 第二阶段:后端开发(第 2 周)
### 🔴 P0 任务:核心后端功能
#### 2.1 Server 基础配置(精简版)
- [ ] 创建 `src/server.ts` 主文件
- [ ] 配置 Express 应用
```typescript
app.use(cors({ origin: process.env.FRONTEND_URL }));
app.use(express.json({ limit: '10mb' }));
app.use(compression()); // 启用 Gzip
```
- [ ] 配置错误处理中间件
- [ ] 实现健康检查端点 `GET /health`
- [ ] 配置日志(使用 Pino性能优于 Winston
#### 2.2 数据库配置(针对单机)
- [ ] 创建 PostgreSQL 容器配置
```yaml
postgres:
image: postgres:15-alpine # 使用 Alpine 减少镜像大小
environment:
POSTGRES_DB: jiao77_db
POSTGRES_USER: app
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
restart: always
```
- [ ] 创建连接池配置
```typescript
new Pool({
max: 20, // 单机限制连接数
idleTimeoutMillis: 30000,
connectionTimeoutMillis: 2000,
})
```
- [ ] 实现连接池监控函数
#### 2.3 数据库 Schema优化版
- [ ] 创建 SQL 初始化脚本
```sql
-- 评论表(带分区考虑)
CREATE TABLE comments (
id SERIAL PRIMARY KEY,
report_id VARCHAR(100) NOT NULL,
author VARCHAR(100) NOT NULL,
content TEXT NOT NULL CHECK (char_length(content) <= 5000),
status VARCHAR(20) DEFAULT 'pending',
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
-- 索引优化
CREATE INDEX CONCURRENTLY idx_comments_report_id
ON comments(report_id, created_at DESC);
CREATE INDEX CONCURRENTLY idx_comments_status
ON comments(status, created_at DESC);
-- 统计表
CREATE TABLE report_stats (
id SERIAL PRIMARY KEY,
report_id VARCHAR(100) UNIQUE NOT NULL,
views INTEGER DEFAULT 0,
comments INTEGER DEFAULT 0,
likes INTEGER DEFAULT 0,
shares INTEGER DEFAULT 0,
last_updated TIMESTAMP DEFAULT NOW()
);
-- 点赞表
CREATE TABLE likes (
id SERIAL PRIMARY KEY,
report_id VARCHAR(100) NOT NULL,
client_id VARCHAR(100) NOT NULL,
created_at TIMESTAMP DEFAULT NOW(),
UNIQUE(report_id, client_id)
);
```
- [ ] 创建数据库初始化脚本 `scripts/db-init.sql`
- [ ] 准备数据库迁移工具(简单的 SQL 文件版本控制)
#### 2.4 评论 API 实现(轻量级)
- [ ] `GET /api/comments?reportId=xxx&page=1&limit=20` - 分页获取
- [ ] `POST /api/comments` - 创建评论(含速率限制)
- [ ] `DELETE /api/comments/:id` - 删除评论(仅作者或管理员)
- [ ] 实现数据验证(使用 Zod
- [ ] 实现错误处理
#### 2.5 统计 API 实现(轻量级)
- [ ] `GET /api/stats/:reportId` - 获取统计数据(加缓存)
- [ ] `POST /api/stats/:reportId/view` - 记录浏览(批量处理)
- [ ] `POST /api/stats/:reportId/like` - 点赞
- [ ] 实现请求去重(基于 IP + clientId
- [ ] 实现缓存策略
#### 2.6 中间件实现(安全 + 性能)
- [ ] 速率限制中间件
```typescript
const rateLimit = require('express-rate-limit');
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 分钟
max: 100, // 单机限制请求数
keyGenerator: (req) => req.ip,
skip: (req) => req.path === '/health'
});
```
- [ ] 请求日志中间件Pino
- [ ] 数据验证中间件Zod
- [ ] 错误处理中间件
#### 2.7 本地测试
- [ ] 运行 `npm run dev` 本地启动
- [ ] 测试各个 API 端点
- [ ] 测试数据库连接
- [ ] 验证错误处理
### 🟠 P1 任务:后端测试
#### 2.8 单元测试(简化版)
- [ ] 编写 API 端点测试
- [ ] 编写数据验证测试
- [ ] 编写错误处理测试
- [ ] 目标覆盖率 > 70%(单机优先功能质量)
#### 2.9 集成测试
- [ ] 测试完整的评论流程
- [ ] 测试完整的统计流程
- [ ] 测试异常场景
---
## 🎯 第三阶段:前端开发(第 2-3 周)
### 🔴 P0 任务:前端集成
#### 3.1 Astro 混合渲染配置
- [ ] 更新 `astro.config.mjs`
```javascript
export default defineConfig({
integrations: [react(), tailwind()],
output: 'hybrid',
adapter: node({ mode: 'standalone' }),
vite: {
ssr: { external: ['pg'] }
}
});
```
- [ ] 本地测试混合渲染
#### 3.2 API 客户端库
- [ ] 创建 `src/lib/api-client.ts`
```typescript
const API_BASE = process.env.PUBLIC_API_URL || 'http://localhost:3000';
export async function fetchAPI(
path: string,
options?: RequestInit
) {
const response = await fetch(`${API_BASE}${path}`, {
headers: {
'Content-Type': 'application/json',
...options?.headers,
},
...options,
});
if (!response.ok) {
throw new Error(`API Error: ${response.status}`);
}
return response.json();
}
```
- [ ] 实现缓存策略
#### 3.3 React 组件开发(轻量级)
- [ ] 开发 `CommentSection` 组件
```typescript
export default function CommentSection({
reportId
}: {
reportId: string
}) {
const [comments, setComments] = useState<Comment[]>([]);
const [loading, setLoading] = useState(false);
useEffect(() => {
setLoading(true);
fetchAPI(`/api/comments?reportId=${reportId}`)
.then(setComments)
.finally(() => setLoading(false));
}, [reportId]);
// ... 组件逻辑
}
```
- [ ] 开发 `StatsPanel` 组件(简化版)
```typescript
export default function StatsPanel({ reportId }: { reportId: string }) {
const [stats, setStats] = useState<Stats | null>(null);
useEffect(() => {
fetchAPI(`/api/stats/${reportId}`).then(setStats);
}, [reportId]);
if (!stats) return <Skeleton />;
return (
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
<StatCard label="浏览" value={stats.views} />
<StatCard label="评论" value={stats.comments} />
<StatCard label="点赞" value={stats.likes} />
<StatCard label="分享" value={stats.shares} />
</div>
);
}
```
- [ ] 开发 `LikeButton` 组件
#### 3.4 页面集成
- [ ] 在报告页面导入组件
- [ ] 设置客户端加载指令
- [ ] 样式适配
### 🟠 P1 任务:前端测试
#### 3.5 组件测试
- [ ] 编写简单的组件测试Vitest
- [ ] 测试数据加载
- [ ] 测试用户交互
---
## 🎯 第四阶段:单机容器化部署(第 3 周)
### 🔴 P0 任务Docker 化应用
#### 4.1 后端 DockerfileAlpine 优化)
- [ ] 创建 `backend/Dockerfile`
```dockerfile
# 构建阶段
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force
# 运行阶段
FROM node:18-alpine
WORKDIR /app
RUN apk add --no-cache dumb-init
COPY --from=builder /app/node_modules ./node_modules
COPY . .
EXPOSE 3000
ENTRYPOINT ["dumb-init", "--"]
CMD ["node", "dist/server.js"]
```
- [ ] 镜像大小目标:< 200MB
#### 4.2 前端 Dockerfile静态优化
- [ ] 创建 `frontend/Dockerfile`
```dockerfile
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
EXPOSE 3000
CMD ["node", "./dist/server/entry.mjs"]
```
#### 4.3 Docker Compose 配置(单机专用)
- [ ] 创建 `docker-compose.yml`
```yaml
version: '3.8'
services:
postgres:
image: postgres:15-alpine
container_name: jiao77_postgres
environment:
POSTGRES_DB: ${DB_NAME}
POSTGRES_USER: ${DB_USER}
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
- ./scripts/db-init.sql:/docker-entrypoint-initdb.d/init.sql
restart: unless-stopped
# 资源限制
deploy:
resources:
limits:
cpus: '1'
memory: 1G
reservations:
cpus: '0.5'
memory: 512M
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${DB_USER}"]
interval: 10s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
container_name: jiao77_redis
restart: unless-stopped
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
volumes:
- redis_data:/data
api:
build:
context: ./backend
dockerfile: Dockerfile
container_name: jiao77_api
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_started
environment:
NODE_ENV: production
DATABASE_URL: postgresql://${DB_USER}:${DB_PASSWORD}@postgres:5432/${DB_NAME}
REDIS_URL: redis://redis:6379
PORT: 3000
ports:
- "3000:3000"
restart: unless-stopped
deploy:
resources:
limits:
cpus: '1'
memory: 1G
reservations:
cpus: '0.5'
memory: 512M
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
web:
build:
context: ./frontend
dockerfile: Dockerfile
container_name: jiao77_web
depends_on:
- api
environment:
PUBLIC_API_URL: http://api:3000
ports:
- "3001:3000"
restart: unless-stopped
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
nginx:
image: nginx:alpine
container_name: jiao77_nginx
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./ssl:/etc/nginx/ssl:ro
- nginx_cache:/var/cache/nginx
depends_on:
- web
- api
restart: unless-stopped
deploy:
resources:
limits:
cpus: '0.5'
memory: 256M
volumes:
postgres_data:
redis_data:
nginx_cache:
```
- [ ] 本地测试 Docker Compose
#### 4.4 Nginx 配置(单机反向代理)
- [ ] 创建 `nginx.conf`
```nginx
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 2048;
use epoll;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# 性能优化
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
# 日志格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
# 缓存配置
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=http_cache:10m
max_size=1g inactive=60m use_temp_path=off;
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml text/javascript
application/json application/javascript application/xml+rss;
upstream api {
server api:3000;
}
upstream web {
server web:3000;
}
server {
listen 80;
server_name _;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name jiao77.cn www.jiao77.cn;
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
# 静态文件
location ~* \.(js|css|png|jpg|jpeg|gif|ico|woff|woff2)$ {
proxy_pass http://web;
proxy_cache http_cache;
proxy_cache_valid 200 30d;
expires 30d;
add_header Cache-Control "public, immutable";
}
# API 接口
location /api/ {
proxy_pass http://api;
proxy_cache http_cache;
proxy_cache_valid 200 10m;
proxy_cache_key "$scheme$request_method$host$request_uri";
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;
}
# 健康检查
location /health {
access_log off;
proxy_pass http://api;
}
# 前端
location / {
proxy_pass http://web;
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;
}
}
}
```
#### 4.5 环境配置
- [ ] 创建 `.env` 模板
```bash
NODE_ENV=production
# 数据库
DB_NAME=jiao77_db
DB_USER=app
DB_PASSWORD=<strong-password>
# Redis
REDIS_URL=redis://redis:6379
# 应用
PORT=3000
FRONTEND_URL=https://jiao77.cn
API_BASE=https://jiao77.cn/api
# 日志
LOG_LEVEL=info
```
#### 4.6 启动脚本
- [ ] 创建 `scripts/start.sh`
```bash
#!/bin/bash
set -e
echo "🚀 启动应用..."
# 拉取最新代码
git pull origin main
# 构建镜像
docker-compose build --no-cache
# 启动服务
docker-compose up -d
# 等待数据库启动
sleep 10
# 运行数据库迁移
docker-compose exec -T api npm run migrate
# 健康检查
echo "✅ 等待服务健康..."
for i in {1..30}; do
if curl -f http://localhost:3000/health > /dev/null 2>&1; then
echo "✅ 应用已启动"
exit 0
fi
echo "⏳ 尝试 $i/30..."
sleep 1
done
echo "❌ 启动失败"
exit 1
```
- [ ] 创建 `scripts/stop.sh` - 优雅关闭
- [ ] 创建 `scripts/backup.sh` - 数据备份
### 🟠 P1 任务:性能优化
#### 4.7 数据库优化(单机)
- [ ] 优化 PostgreSQL 配置
```yaml
environment:
POSTGRES_INITDB_ARGS: |
-c shared_buffers=256MB
-c effective_cache_size=1GB
-c maintenance_work_mem=64MB
-c work_mem=16MB
```
- [ ] 创建必要的数据库索引
- [ ] 配置连接池大小
#### 4.8 API 性能优化
- [ ] 实现 API 分页20 条/页)
- [ ] 实现查询结果缓存Redis
- [ ] 实现请求压缩Gzip
- [ ] 实现 HTTP 缓存头
#### 4.9 前端性能优化
- [ ] Astro 静态生成优化
- [ ] 图片优化和懒加载
- [ ] 代码分割
- [ ] 浏览器缓存配置
---
## 🎯 第五阶段:监控与备份(第 4 周)
### 🔴 P0 任务:核心监控
#### 5.1 应用健康监控
- [ ] 配置 `/health` 端点
- [ ] 配置 `/metrics` 端点Prometheus 格式)
- [ ] 编写简单的监控脚本
```bash
#!/bin/bash
# 定期检查服务状态
curl -f http://localhost:3000/health || {
echo "❌ API 宕机" | mail -s "告警" admin@jiao77.cn
docker-compose restart api
}
```
#### 5.2 数据库监控
- [ ] 监控数据库连接数
- [ ] 监控磁盘使用率
- [ ] 监控查询缓慢日志
#### 5.3 系统监控
- [ ] 监控 CPU 使用率(< 70%
- [ ] 监控内存使用率(< 80%
- [ ] 监控磁盘使用率(< 80%
- [ ] 配置告警规则
#### 5.4 日志管理
- [ ] 配置 Docker 日志驱动json-file + 轮转)
```yaml
logging:
driver: "json-file"
options:
max-size: "100m"
max-file: "3"
```
- [ ] 实现日志聚合可选ELK Stack 精简版)
### 🔴 P0 任务:备份策略
#### 5.5 数据库备份
- [ ] 创建自动备份脚本
```bash
#!/bin/bash
BACKUP_DIR="/backup/postgresql"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
docker-compose exec -T postgres pg_dump \
-U app jiao77_db | gzip > $BACKUP_DIR/backup_$TIMESTAMP.sql.gz
# 保留最近 7 天的备份
find $BACKUP_DIR -name "backup_*.sql.gz" -mtime +7 -delete
```
- [ ] 配置每日凌晨 2 点自动备份crontab
- [ ] 测试备份恢复流程
#### 5.6 应用备份
- [ ] 备份应用代码Git
- [ ] 备份配置文件
- [ ] 备份日志文件(定期轮转)
#### 5.7 存储规划
- [ ] 本地备份30GB7 天备份)
- [ ] 云存储备份20GB使用 Aliyun OSS 或 COS
- [ ] 监控备份完成状态
### 🟠 P1 任务:故障恢复
#### 5.8 故障恢复流程
- [ ] 编写数据库恢复脚本
```bash
#!/bin/bash
# 恢复数据库
docker-compose exec -T postgres psql -U app jiao77_db < backup.sql
```
- [ ] 编写服务重启脚本
- [ ] 编写完整的应急响应手册
#### 5.9 测试和演练
- [ ] 测试备份恢复(月度)
- [ ] 测试服务重启(周度)
- [ ] 演练故障场景(季度)
---
## 🎯 第六阶段:上线和运维(第 5 周)
### 🔴 P0 任务:上线前准备
#### 6.1 最终检查清单
- [ ] 所有功能测试通过
- [ ] 性能基线建立
- [ ] 安全审计完成
- [ ] 备份策略验证
- [ ] 文档完备
- [ ] 监控告警配置
- [ ] 回滚计划准备
#### 6.2 SSL 证书配置
- [ ] 使用 Certbot 申请证书
```bash
sudo certbot certonly --standalone -d jiao77.cn -d www.jiao77.cn
```
- [ ] 配置自动续期
```bash
sudo systemctl enable certbot.timer
```
- [ ] 配置 Nginx 使用证书
#### 6.3 域名配置
- [ ] 配置 A 记录指向公网 IP
- [ ] 配置 CNAMEwww
- [ ] 配置 MX 记录(邮件,可选)
- [ ] 测试 DNS 解析
#### 6.4 上线检查
- [ ] SSH 配置(禁用密码登录)
- [ ] 防火墙规则验证
- [ ] 资源使用率基线
- [ ] 日志系统就位
### 🔴 P0 任务:正式部署
#### 6.5 发布到 VPS
- [ ] 登录 VPS
- [ ] 执行部署脚本:`bash scripts/start.sh`
- [ ] 验证所有服务正常运行
- [ ] 验证 HTTPS 连接
- [ ] 验证所有功能可用
#### 6.6 上线后验证
- [ ] 访问前端页面
- [ ] 测试评论功能
- [ ] 测试统计功能
- [ ] 检查日志无错误
#### 6.7 持续监控(上线后 24h
- [ ] 监控 CPU、内存、磁盘
- [ ] 监控应用日志
- [ ] 监控用户反馈
- [ ] 记录性能数据
### 🟠 P1 任务:运维自动化
#### 6.8 Cron 任务设置
- [ ] 每日 02:00 - 数据库备份
- [ ] 每周日 03:00 - 系统备份
- [ ] 每小时 - 健康检查
- [ ] 每 10 分钟 - 监控检查
#### 6.9 日常运维任务
- [ ] 周度备份验证
- [ ] 月度性能分析
- [ ] 季度灾难恢复演练
- [ ] 定期安全更新
#### 6.10 长期维护计划
- [ ] Docker 镜像定期更新
- [ ] 依赖包定期更新
- [ ] PostgreSQL 大版本升级计划
- [ ] 磁盘空间管理计划
### 🟠 P1 任务:文档和培训
#### 6.11 运维文档
- [ ] 部署操作手册
- [ ] 故障排查指南
- [ ] 备份恢复流程
- [ ] 监控告警规则
#### 6.12 应急响应
- [ ] 编写应急响应计划
- [ ] 列出主要故障场景
- [ ] 编写恢复步骤
---
## 🎯 可选优化P2 任务)
### 🟡 P2 任务:性能优化
#### 7.1 查询优化
- [ ] 数据库慢查询分析
- [ ] 添加查询索引
- [ ] 优化 N+1 查询
- [ ] 实现查询结果缓存
#### 7.2 缓存优化
- [ ] Redis 缓存热数据
- [ ] 实现缓存预热
- [ ] 实现缓存失效策略
#### 7.3 API 优化
- [ ] 减少 API 响应大小
- [ ] 实现字段选择
- [ ] 实现 API 聚合
---
## 🎯 后续扩展P3 任务)
### 🟢 P3 任务:功能扩展
#### 8.1 用户系统
- [ ] 用户认证
- [ ] 用户资料
- [ ] 权限管理
#### 8.2 社区功能
- [ ] 评论回复
- [ ] 用户关注
- [ ] 排行榜
#### 8.3 数据分析
- [ ] 用户行为分析
- [ ] 内容热力分析
---
## 📊 单机配置资源预算
### VPS 规格建议
```
配置4核 CPU、8GB 内存、100GB SSD
操作系统Ubuntu 20.04 LTS
带宽:大带宽(>10 Mbps
```
### 容器资源分配
```
PostgreSQL
- CPU limit: 1 核
- Memory limit: 1GB
- 实际使用0.5 核、500MB
Redis
- CPU limit: 0.5 核
- Memory limit: 512MB
- 实际使用0.2 核、256MB
API (Node.js)
- CPU limit: 1 核
- Memory limit: 1GB
- 实际使用0.3 核、300MB
Web (Astro)
- CPU limit: 0.5 核
- Memory limit: 512MB
- 实际使用0.1 核、100MB
Nginx
- CPU limit: 0.5 核
- Memory limit: 256MB
- 实际使用0.05 核、50MB
总计峰值3 核、3.5GB
实际使用1.15 核、1.2GB(预留安全边际)
```
### 存储分配100GB
```
系统和 Docker20GB
PostgreSQL 数据30GB
Redis 数据2GB
应用代码5GB
日志文件3GB
备份文件30GB
缓冲区10GB
```
---
## ⏱️ 时间表(针对单机优化)
```
第1周 - VPS 准备 + 后端开发 60 小时
第2周 - 前端开发 + 集成 50 小时
第3周 - Docker 化 + 部署 40 小时
第4周 - 监控 + 备份 + 测试 40 小时
第5周 - 上线 + 优化 30 小时
──────────────────────────────────
总计220 小时 ≈ 5-6 周(单人开发)
≈ 3-4 周(双人开发)
```
---
## 🚀 快速开始指南
### 立即开始(第 1 天)
```bash
# 1. SSH 登录 VPS
ssh root@<ip>
# 2. 安装 Docker 和 Compose
curl -fsSL https://get.docker.com | sh
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
# 3. 克隆项目
git clone <repo> /home/app
# 4. 配置环境
cd /home/app
cp .env.example .env
# 编辑 .env配置数据库密码等
# 5. 启动应用
docker-compose up -d
# 6. 验证
curl http://localhost:3000/health
```
### 配置 SSL第 2 天)
```bash
# 使用 Certbot
sudo apt install certbot
sudo certbot certonly --standalone -d jiao77.cn -d www.jiao77.cn
# 在 docker-compose.yml 中配置证书路径
# 重启 Nginx
docker-compose restart nginx
```
### 配置备份(第 3 天)
```bash
# 添加 cron 任务
crontab -e
# 添加备份命令
0 2 * * * cd /home/app && bash scripts/backup.sh
```
---
## 💡 单机部署最佳实践
### ✅ DO应该做
- ✅ 定期备份数据库
- ✅ 监控资源使用率
- ✅ 设置告警规则
- ✅ 使用 Alpine 镜像减少内存
- ✅ 配置资源限制
- ✅ 日志轮转
- ✅ 定期更新依赖
### ❌ DON'T不应该做
- ❌ 不使用 root 运行容器
- ❌ 不在生产用开发镜像
- ❌ 不忽视监控告警
- ❌ 不手动管理依赖版本
- ❌ 不连续部署到生产(需要测试)
---
## 🔧 常见问题排查
### 问题 1内存不足
```bash
# 检查内存使用
docker stats
# 解决方案:
# 1. 减少 PostgreSQL 缓冲区
# 2. 减少 Redis 最大内存
# 3. 优化 Node.js 堆大小
```
### 问题 2磁盘满
```bash
# 检查磁盘
df -h
# 清理 Docker 镜像
docker image prune -a
# 清理 Docker 容器
docker container prune
```
### 问题 3性能下降
```bash
# 检查慢查询
docker-compose logs api | grep "SLOW"
# 检查数据库连接
docker-compose exec postgres psql -c "SELECT count(*) FROM pg_stat_activity;"
```
---
## 📈 性能指标目标
| 指标 | 目标 | 说明 |
|-----|------|------|
| 页面加载时间 | < 2s | 首次加载 |
| API 响应时间 | < 200ms | 平均响应 |
| 数据库查询 | < 100ms | 95 分位 |
| CPU 使用率 | < 60% | 平均 |
| 内存使用率 | < 75% | 峰值 |
| 磁盘使用率 | < 80% | 实时 |
| 可用性 | 99.5% | 月度 |
---
## 🎯 总结
这个方案针对**单机 VPS 环境**进行了全面优化:
1. **资源优化** - 使用 Alpine 镜像、资源限制、连接池优化
2. **部署简化** - Docker Compose 单文件部署、Nginx 反向代理
3. **监控自动化** - 健康检查、告警规则、自动重启
4. **备份完善** - 每日备份、7 天保留、恢复流程
5. **成本低** - 无需复杂基础设施、单机成本 ~¥100/月
**建议**:从 P0 任务开始,按阶段稳步推进,确保每个阶段的质量。