Files
PrivyDrop/docker/scripts/generate-config.sh
T
2025-09-11 06:46:04 +08:00

600 lines
16 KiB
Bash
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.
#!/bin/bash
# 导入环境检测脚本
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/detect-environment.sh"
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# 日志函数
log_info() {
echo -e "${BLUE}$1${NC}"
}
log_success() {
echo -e "${GREEN}$1${NC}"
}
log_warning() {
echo -e "${YELLOW}⚠️ $1${NC}"
}
log_error() {
echo -e "${RED}$1${NC}"
}
# 生成环境变量文件
generate_env_file() {
log_info "生成环境变量配置..."
local env_file=".env"
# 生成随机密码
local turn_password=$(openssl rand -base64 32 2>/dev/null || echo "privydrop$(date +%s)")
cat > "$env_file" << EOF
# PrivyDrop Docker 配置文件
# 自动生成时间: $(date)
# 网络模式: $NETWORK_MODE
# 部署模式: $DEPLOYMENT_MODE
# =============================================================================
# 网络配置
# =============================================================================
CORS_ORIGIN=http://${LOCAL_IP}
NEXT_PUBLIC_API_URL=http://${LOCAL_IP}:3001
# =============================================================================
# 端口配置
# =============================================================================
FRONTEND_PORT=3000
BACKEND_PORT=3001
HTTP_PORT=80
HTTPS_PORT=443
# =============================================================================
# Redis配置
# =============================================================================
REDIS_HOST=redis
REDIS_PORT=6379
# =============================================================================
# 部署配置
# =============================================================================
DEPLOYMENT_MODE=${DEPLOYMENT_MODE}
NETWORK_MODE=${NETWORK_MODE}
LOCAL_IP=${LOCAL_IP}
PUBLIC_IP=${PUBLIC_IP:-}
# =============================================================================
# SSL配置
# =============================================================================
SSL_MODE=self-signed
DOMAIN_NAME=${DOMAIN_NAME:-}
# =============================================================================
# TURN服务器配置 (可选)
# =============================================================================
TURN_ENABLED=${TURN_ENABLED:-false}
TURN_USERNAME=privydrop
TURN_PASSWORD=${turn_password}
TURN_REALM=${DOMAIN_NAME:-turn.local}
# =============================================================================
# Nginx配置
# =============================================================================
NGINX_SERVER_NAME=${DOMAIN_NAME:-${LOCAL_IP}}
# =============================================================================
# 日志配置
# =============================================================================
LOG_LEVEL=info
EOF
# 根据部署模式调整配置
if [[ "$DEPLOYMENT_MODE" == "full" ]]; then
sed -i "s|CORS_ORIGIN=http://|CORS_ORIGIN=https://|g" "$env_file"
sed -i "s|NEXT_PUBLIC_API_URL=http://|NEXT_PUBLIC_API_URL=https://|g" "$env_file"
sed -i "s|SSL_MODE=self-signed|SSL_MODE=letsencrypt|g" "$env_file"
sed -i "s|TURN_ENABLED=false|TURN_ENABLED=true|g" "$env_file"
elif [[ "$DEPLOYMENT_MODE" == "public" ]]; then
sed -i "s|TURN_ENABLED=false|TURN_ENABLED=true|g" "$env_file"
fi
log_success "环境变量配置已生成: $env_file"
}
# 生成Nginx配置
generate_nginx_config() {
log_info "生成Nginx配置..."
mkdir -p docker/nginx/conf.d
local server_name="${DOMAIN_NAME:-${LOCAL_IP} localhost}"
local upstream_backend="backend:3001"
local upstream_frontend="frontend:3000"
# 生成主Nginx配置
cat > docker/nginx/nginx.conf << 'EOF'
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
use epoll;
multi_accept on;
}
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;
server_tokens off;
# 客户端配置
client_max_body_size 100M;
client_header_timeout 60s;
client_body_timeout 60s;
# Gzip配置
gzip on;
gzip_vary on;
gzip_min_length 1000;
gzip_proxied expired no-cache no-store private auth;
gzip_types
text/plain
text/css
text/xml
text/javascript
application/javascript
application/xml+rss
application/json;
# 包含站点配置
include /etc/nginx/conf.d/*.conf;
}
EOF
# 生成站点配置
cat > docker/nginx/conf.d/default.conf << EOF
# 上游服务定义
upstream backend {
server ${upstream_backend};
keepalive 32;
}
upstream frontend {
server ${upstream_frontend};
keepalive 32;
}
# HTTP服务器配置
server {
listen 80;
server_name ${server_name};
# 安全头
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
# 健康检查端点
location /nginx-health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
# 后端API代理
location /api/ {
proxy_pass http://backend/api/;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
proxy_cache_bypass \$http_upgrade;
# 超时配置
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
# 后端健康检查代理
location /health {
proxy_pass http://backend/health;
proxy_http_version 1.1;
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;
}
# Socket.IO代理
location /socket.io/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
# WebSocket特殊配置
proxy_buffering off;
proxy_cache off;
}
# 前端应用代理
location / {
proxy_pass http://frontend;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
proxy_cache_bypass \$http_upgrade;
# Next.js特殊配置
proxy_buffering off;
}
}
EOF
log_success "Nginx配置已生成"
echo " 主配置: docker/nginx/nginx.conf"
echo " 站点配置: docker/nginx/conf.d/default.conf"
}
# 生成SSL证书
generate_ssl_certificates() {
if [[ "$SSL_MODE" == "self-signed" ]] || [[ "$NETWORK_MODE" == "private" ]]; then
log_info "生成自签名SSL证书..."
mkdir -p docker/ssl
# 生成CA私钥
openssl genrsa -out docker/ssl/ca-key.pem 4096 2>/dev/null
# 生成CA证书
openssl req -new -x509 -days 365 -key docker/ssl/ca-key.pem \
-out docker/ssl/ca-cert.pem \
-subj "/C=CN/ST=Local/L=Local/O=PrivyDrop/CN=PrivyDrop-CA" 2>/dev/null
# 生成服务器私钥
openssl genrsa -out docker/ssl/server-key.pem 4096 2>/dev/null
# 生成服务器证书请求
openssl req -new -key docker/ssl/server-key.pem \
-out docker/ssl/server.csr \
-subj "/C=CN/ST=Local/L=Local/O=PrivyDrop/CN=${LOCAL_IP}" 2>/dev/null
# 创建扩展配置
cat > docker/ssl/server.ext << EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = localhost
DNS.2 = *.local
DNS.3 = ${DOMAIN_NAME:-privydrop.local}
IP.1 = ${LOCAL_IP}
IP.2 = 127.0.0.1
EOF
# 签名服务器证书
openssl x509 -req -days 365 -in docker/ssl/server.csr \
-CA docker/ssl/ca-cert.pem -CAkey docker/ssl/ca-key.pem \
-out docker/ssl/server-cert.pem -CAcreateserial \
-extensions v3_req -extfile docker/ssl/server.ext 2>/dev/null
# 清理临时文件
rm -f docker/ssl/server.csr docker/ssl/server.ext docker/ssl/ca-cert.srl
# 设置权限
chmod 600 docker/ssl/*-key.pem
chmod 644 docker/ssl/*-cert.pem
log_success "SSL证书已生成: docker/ssl/"
log_info "要信任证书,请导入CA证书: docker/ssl/ca-cert.pem"
# 生成HTTPS Nginx配置
if [[ "$DEPLOYMENT_MODE" != "basic" ]]; then
generate_https_nginx_config
fi
fi
}
# 生成HTTPS Nginx配置
generate_https_nginx_config() {
log_info "生成HTTPS Nginx配置..."
cat >> docker/nginx/conf.d/default.conf << EOF
# HTTPS服务器配置
server {
listen 443 ssl http2;
server_name ${DOMAIN_NAME:-${LOCAL_IP}};
# SSL配置
ssl_certificate /etc/nginx/ssl/server-cert.pem;
ssl_certificate_key /etc/nginx/ssl/server-key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# 安全头
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
# 健康检查端点
location /nginx-health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
# 后端API代理
location /api/ {
proxy_pass http://backend/api/;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_cache_bypass \$http_upgrade;
}
# 后端健康检查代理
location /health {
proxy_pass http://backend/health;
proxy_http_version 1.1;
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 https;
}
# Socket.IO代理
location /socket.io/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_buffering off;
proxy_cache off;
}
# 前端应用代理
location / {
proxy_pass http://frontend;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_cache_bypass \$http_upgrade;
proxy_buffering off;
}
}
EOF
log_success "HTTPS配置已添加"
}
# 生成Coturn配置
generate_coturn_config() {
if [[ "$TURN_ENABLED" == "true" ]]; then
log_info "生成Coturn TURN服务器配置..."
mkdir -p docker/coturn
cat > docker/coturn/turnserver.conf << EOF
# PrivyDrop TURN服务器配置
# 自动生成时间: $(date)
# 监听端口
listening-port=3478
tls-listening-port=5349
# 监听IP
listening-ip=0.0.0.0
relay-ip=0.0.0.0
# 外部IP (用于NAT环境)
external-ip=${PUBLIC_IP:-${LOCAL_IP}}
# 服务器域名
realm=${TURN_REALM}
server-name=${TURN_REALM}
# 认证方式
lt-cred-mech
# 用户认证
user=${TURN_USERNAME}:${TURN_PASSWORD}
# SSL证书 (如果启用TLS)
cert=/etc/ssl/certs/server-cert.pem
pkey=/etc/ssl/certs/server-key.pem
# 日志配置
no-stdout-log
log-file=/var/log/turnserver.log
verbose
# 安全配置
no-cli
no-loopback-peers
no-multicast-peers
# 性能配置
min-port=49152
max-port=65535
# 数据库 (可选)
# userdb=/var/lib/turn/turndb
# 其他配置
mobility
no-tlsv1
no-tlsv1_1
EOF
log_success "Coturn配置已生成: docker/coturn/turnserver.conf"
log_info "TURN服务器用户名: ${TURN_USERNAME}"
log_warning "TURN服务器密码已保存在.env文件中"
fi
}
# 生成Docker忽略文件
generate_dockerignore() {
log_info "生成Docker忽略文件..."
# 后端.dockerignore
cat > backend/.dockerignore << EOF
node_modules
npm-debug.log*
.npm
.env*
.git
.gitignore
README.md
Dockerfile
.dockerignore
coverage
.nyc_output
logs
*.log
EOF
# 前端.dockerignore
cat > frontend/.dockerignore << EOF
node_modules
.next
.git
.gitignore
README.md
Dockerfile
.dockerignore
.env*
npm-debug.log*
.npm
coverage
.nyc_output
*.log
public/sw.js
public/workbox-*.js
EOF
log_success "Docker忽略文件已生成"
}
# 创建日志目录
create_log_directories() {
log_info "创建日志目录..."
mkdir -p logs/{nginx,backend,frontend,coturn}
# 设置权限
chmod 755 logs
chmod 755 logs/*
log_success "日志目录已创建: logs/"
}
# 主函数
main() {
echo -e "${BLUE}=== PrivyDrop 配置生成 ===${NC}"
echo ""
# 首先运行环境检测
if ! detect_network_environment; then
log_error "环境检测失败"
exit 1
fi
if ! check_system_resources; then
log_error "系统资源检查失败"
exit 1
fi
detect_deployment_mode
echo ""
# 生成所有配置文件
generate_env_file
echo ""
generate_nginx_config
echo ""
generate_ssl_certificates
echo ""
generate_coturn_config
echo ""
generate_dockerignore
echo ""
create_log_directories
echo ""
log_success "🎉 所有配置文件生成完成!"
echo ""
echo -e "${BLUE}生成的文件:${NC}"
echo " .env - 环境变量配置"
echo " docker/nginx/ - Nginx配置"
echo " docker/ssl/ - SSL证书"
[[ "$TURN_ENABLED" == "true" ]] && echo " docker/coturn/ - TURN服务器配置"
echo " logs/ - 日志目录"
echo ""
echo -e "${BLUE}下一步:${NC}"
echo " 运行 './deploy.sh' 开始部署"
}
# 如果脚本被直接执行
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
main "$@"
fi