部署指南
本指南介绍如何将 AudioDock 部署到生产环境,包括单机部署、集群部署和云平台部署。
目录
部署前准备
系统要求
| 资源 | 最低要求 | 推荐配置 |
|---|---|---|
| CPU | 2 核心 | 4 核心 |
| 内存 | 4GB | 8GB |
| 存储 | 50GB | 200GB+ |
| 网络 | 100Mbps | 1Gbps |
环境检查
# 检查系统版本
uname -a
# 检查内存
free -h
# 检查磁盘空间
df -h
# 检查网络
ping -c 4 8.8.8.8端口要求
| 端口 | 协议 | 用途 | 必需 |
|---|---|---|---|
| 3000 | HTTP | Web 界面 | 是 |
| 3001 | HTTP | API 服务 | 是 |
| 5432 | TCP | PostgreSQL | 是 |
| 6379 | TCP | Redis | 是 |
| 9000 | TCP | MinIO (可选) | 否 |
单机部署
手动部署步骤
1. 安装依赖
# Ubuntu/Debian
sudo apt update
sudo apt install -y nodejs npm postgresql redis-server nginx
# CentOS/RHEL
sudo yum install -y nodejs npm postgresql-server redis nginx2. 配置数据库
# 初始化 PostgreSQL
sudo postgresql-setup initdb
sudo systemctl start postgresql
sudo systemctl enable postgresql
# 创建数据库用户
sudo -u postgres createuser audiodock
sudo -u postgres createdb audiodock_prod
sudo -u postgres psql -c "ALTER USER audiodock WITH PASSWORD 'secure_password';"
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE audiodock_prod TO audiodock;"3. 配置 Redis
sudo systemctl start redis
sudo systemctl enable redis
# 测试 Redis
redis-cli ping4. 部署应用
# 克隆代码
git clone https://github.com/mmdctjj/AudioDock.git /opt/audiodock
cd /opt/audiodock
# 安装依赖
npm install --production
# 构建应用
npm run build
# 配置环境变量
cp .env.example .env.production
# 编辑 .env.production 文件5. 配置 systemd 服务
sudo tee /etc/systemd/system/audiodock.service << EOF
[Unit]
Description=AudioDock Service
After=network.target postgresql.service redis.service
[Service]
Type=simple
User=audiodock
WorkingDirectory=/opt/audiodock
Environment=NODE_ENV=production
ExecStart=/usr/bin/npm start
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
# 启动服务
sudo systemctl daemon-reload
sudo systemctl start audiodock
sudo systemctl enable audiodock6. 配置 Nginx 反向代理
sudo tee /etc/nginx/sites-available/audiodock << EOF
server {
listen 80;
server_name audiodock.example.com;
location / {
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_cache_bypass \$http_upgrade;
}
location /api/ {
proxy_pass http://localhost:3001;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
}
}
server {
listen 443 ssl;
server_name audiodock.example.com;
ssl_certificate /etc/letsencrypt/live/audiodock.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/audiodock.example.com/privkey.pem;
# SSL 配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;
ssl_prefer_server_ciphers off;
location / {
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_cache_bypass \$http_upgrade;
}
}
EOF
# 启用配置
sudo ln -s /etc/nginx/sites-available/audiodock /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginxDocker 部署
使用 Docker Compose
1. 创建 docker-compose.yml
version: '3.8'
services:
postgres:
image: postgres:15-alpine
environment:
POSTGRES_DB: audiodock
POSTGRES_USER: audiodock
POSTGRES_PASSWORD: secure_password
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- audiodock-network
redis:
image: redis:7-alpine
command: redis-server --requirepass redis_password
volumes:
- redis_data:/data
networks:
- audiodock-network
minio:
image: minio/minio
command: server /data --console-address ":9001"
environment:
MINIO_ROOT_USER: minioadmin
MINIO_ROOT_PASSWORD: minioadmin
volumes:
- minio_data:/data
ports:
- "9000:9000"
- "9001:9001"
networks:
- audiodock-network
api:
image: audiodock/api:latest
depends_on:
- postgres
- redis
environment:
DATABASE_URL: postgresql://audiodock:secure_password@postgres:5432/audiodock
REDIS_URL: redis://:redis_password@redis:6379
MINIO_ENDPOINT: http://minio:9000
NODE_ENV: production
ports:
- "3001:3001"
networks:
- audiodock-network
web:
image: audiodock/web:latest
depends_on:
- api
environment:
API_URL: http://api:3001
NODE_ENV: production
ports:
- "3000:3000"
networks:
- audiodock-network
nginx:
image: nginx:alpine
depends_on:
- web
- api
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
ports:
- "80:80"
- "443:443"
networks:
- audiodock-network
volumes:
postgres_data:
redis_data:
minio_data:
networks:
audiodock-network:
driver: bridge2. 创建 nginx.conf
events {
worker_connections 1024;
}
http {
upstream api {
server api:3001;
}
upstream web {
server web:3000;
}
server {
listen 80;
server_name audiodock.example.com;
location / {
proxy_pass http://web;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /api/ {
proxy_pass http://api;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
}3. 启动服务
# 拉取镜像
docker-compose pull
# 启动所有服务
docker-compose up -d
# 查看日志
docker-compose logs -f
# 停止服务
docker-compose down使用 Docker Swarm
# 初始化 Swarm
docker swarm init
# 部署堆栈
docker stack deploy -c docker-compose.yml audiodock
# 查看服务状态
docker service ls
# 扩展服务
docker service scale audiodock_web=3Kubernetes 部署
创建命名空间
# namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: audiodock创建 ConfigMap
# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: audiodock-config
namespace: audiodock
data:
DATABASE_URL: postgresql://audiodock:secure_password@postgres:5432/audiodock
REDIS_URL: redis://:redis_password@redis:6379
NODE_ENV: production创建 Deployment
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: audiodock-api
namespace: audiodock
spec:
replicas: 3
selector:
matchLabels:
app: audiodock-api
template:
metadata:
labels:
app: audiodock-api
spec:
containers:
- name: api
image: audiodock/api:latest
ports:
- containerPort: 3001
envFrom:
- configMapRef:
name: audiodock-config
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 3001
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 3001
initialDelaySeconds: 5
periodSeconds: 5创建 Service
# service.yaml
apiVersion: v1
kind: Service
metadata:
name: audiodock-api
namespace: audiodock
spec:
selector:
app: audiodock-api
ports:
- port: 80
targetPort: 3001
type: ClusterIP创建 Ingress
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: audiodock-ingress
namespace: audiodock
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: audiodock.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: audiodock-web
port:
number: 80
- path: /api
pathType: Prefix
backend:
service:
name: audiodock-api
port:
number: 80部署到 Kubernetes
# 应用所有配置
kubectl apply -f namespace.yaml
kubectl apply -f configmap.yaml
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
kubectl apply -f ingress.yaml
# 查看部署状态
kubectl get all -n audiodock
# 查看日志
kubectl logs -l app=audiodock-api -n audiodock -f云平台部署
AWS ECS 部署
# 创建 ECR 仓库
aws ecr create-repository --repository-name audiodock
# 推送镜像
docker tag audiodock/api:latest 123456789012.dkr.ecr.us-east-1.amazonaws.com/audiodock/api:latest
docker push 123456789012.dkr.ecr.us-east-1.amazonaws.com/audiodock/api:latest
# 创建 ECS 任务定义
aws ecs register-task-definition --cli-input-json file://task-definition.json
# 创建 ECS 服务
aws ecs create-service --cluster audiodock-cluster --service-name audiodock --task-definition audiodock:1Google Cloud Run
# 构建镜像
gcloud builds submit --tag gcr.io/PROJECT_ID/audiodock
# 部署到 Cloud Run
gcloud run deploy audiodock \
--image gcr.io/PROJECT_ID/audiodock \
--platform managed \
--region us-central1 \
--allow-unauthenticatedAzure Container Instances
# 创建容器组
az container create \
--resource-group myResourceGroup \
--name audiodock \
--image audiodock/api:latest \
--ports 3001 \
--dns-name-label audiodock-dns \
--environment-variables DATABASE_URL=postgresql://...监控与维护
健康检查端点
# API 健康检查
curl http://localhost:3001/health
# 数据库连接检查
curl http://localhost:3001/health/db
# Redis 连接检查
curl http://localhost:3001/health/redis日志管理
# 查看应用日志
journalctl -u audiodock -f
# 查看 Docker 日志
docker-compose logs -f api
# 查看 Kubernetes 日志
kubectl logs -l app=audiodock-api -f备份与恢复
数据库备份
# PostgreSQL 备份
pg_dump -U audiodock -h localhost audiodock_prod > backup_$(date +%Y%m%d).sql
# 使用 pg_dumpall 备份所有数据库
pg_dumpall -U postgres > full_backup_$(date +%Y%m%d).sql
# 自动备份脚本
#!/bin/bash
BACKUP_DIR="/var/backups/audiodock"
DATE=$(date +%Y%m%d_%H%M%S)
pg_dump -U audiodock audiodock_prod | gzip > $BACKUP_DIR/audiodock_$DATE.sql.gz
find $BACKUP_DIR -name "*.sql.gz" -mtime +30 -delete恢复数据库
# 从备份恢复
gunzip -c backup_20240306.sql.gz | psql -U audiodock -d audiodock_prod
# 或者使用 psql 直接恢复
psql -U audiodock -d audiodock_prod -f backup.sql性能监控
使用 Prometheus + Grafana
# prometheus.yml
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'audiodock'
static_configs:
- targets: ['audiodock-api:3001']关键指标监控
- API 响应时间 (< 200ms)
- 数据库连接池使用率 (< 80%)
- 内存使用率 (< 80%)
- CPU 使用率 (< 70%)
- 磁盘 I/O 延迟 (< 10ms)
安全维护
定期更新
# 更新系统包
sudo apt update && sudo apt upgrade -y
# 更新 Docker 镜像
docker-compose pull
docker-compose up -d
# 更新 Kubernetes 部署
kubectl set image deployment/audiodock-api api=audiodock/api:latest安全扫描
# 使用 Trivy 扫描镜像漏洞
trivy image audiodock/api:latest
# 使用 Snyk 扫描依赖漏洞
snyk test
# 使用 OWASP ZAP 进行安全测试
docker run -v $(pwd):/zap/wrk/:rw -t owasp/zap2docker-stable zap-baseline.py \
-t http://audiodock.example.com相关文档: