生产环境部署指南
生产环境部署指南
本指南提供 PowerWiki 的企业级生产环境部署方案,包括高可用、性能优化、安全加固等。
架构设计
推荐架构
┌─────────────────────────────────────────────────────┐
│ 用户访问 │
└────────────────────┬────────────────────────────────┘
│
┌────────────────────▼────────────────────────────────┐
│ CDN / 负载均衡器 │
│ (Cloudflare / Nginx / HAProxy) │
└────────────────────┬────────────────────────────────┘
│
┌────────────┼────────────┐
│ │ │
┌───────▼──┐ ┌──────▼──┐ ┌─────▼────┐
│ PowerWiki│ │PowerWiki│ │PowerWiki │
│ 实例 1 │ │ 实例 2 │ │ 实例 3 │
└───────┬──┘ └──────┬──┘ └─────┬────┘
│ │ │
└────────────┼────────────┘
│
┌────────────▼────────────┐
│ 共享存储 / 数据卷 │
│ (NFS / Docker Volume) │
└────────────┬────────────┘
│
┌────────────▼────────────┐
│ Git 仓库 / 缓存 │
│ (GitHub / GitLab) │
└─────────────────────────┘
部署方案对比
| 方案 | 可用性 | 性能 | 成本 | 复杂度 | 适用场景 |
|---|---|---|---|---|---|
| 单机 Docker | 低 | 中 | 低 | 低 | 小型团队 |
| Docker Swarm | 中 | 中 | 中 | 中 | 中型企业 |
| Kubernetes | 高 | 高 | 高 | 高 | 大型企业 |
单机生产部署
使用 Docker Compose
创建 docker-compose.prod.yml:
version: '3.8'
services:
powerwiki:
image: sayunchuan/powerwiki:latest
container_name: powerwiki
restart: always
ports:
- "3150:3150"
environment:
- NODE_ENV=production
- DATA_DIR=/app/data
- GIT_CACHE_DIR=/app/cache
- LANG=zh-CN
volumes:
- ./config.json:/app/config.json:ro
- powerwiki_data:/app/data
- powerwiki_cache:/app/cache
networks:
- powerwiki-net
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3150"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
nginx:
image: nginx:alpine
container_name: powerwiki-nginx
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./ssl:/etc/nginx/ssl:ro
- ./logs/nginx:/var/log/nginx
depends_on:
- powerwiki
networks:
- powerwiki-net
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
volumes:
powerwiki_data:
driver: local
powerwiki_cache:
driver: local
networks:
powerwiki-net:
driver: bridge
Nginx 配置
创建 nginx.conf:
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
use epoll;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
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;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
client_max_body_size 20M;
# Gzip 压缩
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
application/rss+xml font/truetype font/opentype
application/vnd.ms-fontobject image/svg+xml;
# 缓存设置
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=powerwiki_cache:10m
max_size=1g inactive=60m use_temp_path=off;
upstream powerwiki {
server powerwiki:3150;
}
server {
listen 80;
server_name _;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name wiki.example.com;
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;
ssl_prefer_server_ciphers on;
# 安全头
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
location / {
proxy_pass http://powerwiki;
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 $server_name;
# 缓存设置
proxy_cache powerwiki_cache;
proxy_cache_valid 200 1h;
proxy_cache_use_stale error timeout invalid_header updating;
add_header X-Cache-Status $upstream_cache_status;
}
# 静态文件缓存
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
proxy_pass http://powerwiki;
proxy_cache powerwiki_cache;
proxy_cache_valid 200 30d;
expires 30d;
add_header Cache-Control "public, immutable";
}
# 健康检查
location /health {
access_log off;
proxy_pass http://powerwiki;
}
}
}
启动生产环境
# 启动服务
docker-compose -f docker-compose.prod.yml up -d
# 查看日志
docker-compose -f docker-compose.prod.yml logs -f
# 停止服务
docker-compose -f docker-compose.prod.yml down
高可用部署
使用 Docker Swarm
初始化 Swarm:
docker swarm init
创建 docker-compose.swarm.yml:
version: '3.8'
services:
powerwiki:
image: sayunchuan/powerwiki:latest
deploy:
replicas: 3
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
update_config:
parallelism: 1
delay: 10s
environment:
- NODE_ENV=production
- DATA_DIR=/app/data
- GIT_CACHE_DIR=/app/cache
volumes:
- ./config.json:/app/config.json:ro
- powerwiki_data:/app/data
- powerwiki_cache:/app/cache
networks:
- powerwiki-net
nginx:
image: nginx:alpine
deploy:
replicas: 2
restart_policy:
condition: on-failure
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
networks:
- powerwiki-net
volumes:
powerwiki_data:
driver: local
powerwiki_cache:
driver: local
networks:
powerwiki-net:
driver: overlay
部署:
docker stack deploy -c docker-compose.swarm.yml powerwiki
Kubernetes 部署
创建 Namespace
kubectl create namespace powerwiki
创建 ConfigMap
kubectl create configmap powerwiki-config \
--from-file=config.json \
-n powerwiki
创建 Deployment
创建 k8s-deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: powerwiki
namespace: powerwiki
spec:
replicas: 3
selector:
matchLabels:
app: powerwiki
template:
metadata:
labels:
app: powerwiki
spec:
containers:
- name: powerwiki
image: sayunchuan/powerwiki:latest
ports:
- containerPort: 3150
env:
- name: NODE_ENV
value: "production"
- name: DATA_DIR
value: "/app/data"
- name: GIT_CACHE_DIR
value: "/app/cache"
volumeMounts:
- name: config
mountPath: /app/config.json
subPath: config.json
- name: data
mountPath: /app/data
- name: cache
mountPath: /app/cache
livenessProbe:
httpGet:
path: /
port: 3150
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 3150
initialDelaySeconds: 5
periodSeconds: 5
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
volumes:
- name: config
configMap:
name: powerwiki-config
- name: data
persistentVolumeClaim:
claimName: powerwiki-data
- name: cache
persistentVolumeClaim:
claimName: powerwiki-cache
创建 Service
apiVersion: v1
kind: Service
metadata:
name: powerwiki
namespace: powerwiki
spec:
selector:
app: powerwiki
ports:
- protocol: TCP
port: 80
targetPort: 3150
type: LoadBalancer
创建 Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: powerwiki
namespace: powerwiki
spec:
ingressClassName: nginx
rules:
- host: wiki.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: powerwiki
port:
number: 80
tls:
- hosts:
- wiki.example.com
secretName: powerwiki-tls
部署:
kubectl apply -f k8s-deployment.yaml
kubectl apply -f k8s-service.yaml
kubectl apply -f k8s-ingress.yaml
监控和告警
使用 Prometheus 监控
创建 prometheus.yml:
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'powerwiki'
static_configs:
- targets: ['localhost:3150']
使用 Grafana 可视化
docker run -d -p 3000:3000 grafana/grafana
备份和恢复
自动备份脚本
创建 backup.sh:
#!/bin/bash
BACKUP_DIR="/backups"
DATE=$(date +%Y%m%d_%H%M%S)
# 备份数据卷
docker run --rm \
-v powerwiki_data:/data \
-v $BACKUP_DIR:/backup \
alpine tar czf /backup/data_$DATE.tar.gz -C /data .
# 备份缓存
docker run --rm \
-v powerwiki_cache:/cache \
-v $BACKUP_DIR:/backup \
alpine tar czf /backup/cache_$DATE.tar.gz -C /cache .
# 备份配置
cp config.json $BACKUP_DIR/config_$DATE.json
# 清理旧备份(保留 7 天)
find $BACKUP_DIR -name "*.tar.gz" -mtime +7 -delete
设置定时任务:
# 每天凌晨 2 点执行备份
0 2 * * * /path/to/backup.sh
安全加固
SSL/TLS 证书
使用 Let's Encrypt:
# 安装 Certbot
sudo apt-get install certbot python3-certbot-nginx
# 获取证书
sudo certbot certonly --standalone -d wiki.example.com
# 自动续期
sudo systemctl enable certbot.timer
防火墙配置
# 允许 HTTP 和 HTTPS
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
# 限制 SSH 访问
sudo ufw allow from 192.168.1.0/24 to any port 22
定期更新
# 更新 Docker 镜像
docker pull sayunchuan/powerwiki:latest
# 重启容器
docker-compose -f docker-compose.prod.yml up -d
性能优化
资源限制
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
自动扩展
# Docker Swarm 自动扩展
docker service update --limit-memory 512m powerwiki_powerwiki
故障恢复
健康检查
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3150"]
interval: 30s
timeout: 10s
retries: 3
自动重启
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
提示: 生产环境部署需要考虑高可用、性能、安全等多个方面。建议根据实际需求选择合适的部署方案。
更新时间:2026年2月24日