#!/bin/bash PRODUCT_NAME=$1 FILES_SOURCE=$2 if [ -z "$PRODUCT_NAME" ] || [ -z "$FILES_SOURCE" ]; then echo "用法: $0 " echo "示例: $0 product-a ./product-a-website" exit 1 fi DOMAIN="${PRODUCT_NAME}.novalon.cn" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" NGINX_DIR="$(dirname "$SCRIPT_DIR")" CONF_DIR="${NGINX_DIR}/conf.d" SITES_DIR="${NGINX_DIR}/sites" SSL_DIR="${NGINX_DIR}/ssl" if [ ! -d "$FILES_SOURCE" ]; then echo "错误: 源文件目录不存在: $FILES_SOURCE" exit 1 fi mkdir -p "${SITES_DIR}/${PRODUCT_NAME}" mkdir -p "${SSL_DIR}/${DOMAIN}" mkdir -p "${CONF_DIR}" cp -r "${FILES_SOURCE}/"* "${SITES_DIR}/${PRODUCT_NAME}/" 2>/dev/null || true cp -r "${FILES_SOURCE}/." "${SITES_DIR}/${PRODUCT_NAME}/" 2>/dev/null || true cat > "${CONF_DIR}/${DOMAIN}.conf" << 'CONF_TEMPLATE' server { listen 80; server_name {{DOMAIN}}; location /.well-known/acme-challenge/ { root /var/www/certbot; } location / { return 301 https://$host$request_uri; } } server { listen 443 ssl http2; server_name {{DOMAIN}}; ssl_certificate /etc/nginx/ssl/{{DOMAIN}}/fullchain.pem; ssl_certificate_key /etc/nginx/ssl/{{DOMAIN}}/privkey.pem; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305; ssl_prefer_server_ciphers off; ssl_session_cache shared:SSL:10m; ssl_session_timeout 1d; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always; add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header X-XSS-Protection "1; mode=block" always; root /var/www/sites/{{PRODUCT_NAME}}; index index.html; location ~* \.(css|js|jpg|jpeg|png|gif|webp|avif|svg|ico|woff|woff2|ttf|eot)$ { expires 1y; add_header Cache-Control "public, max-age=31536000, immutable"; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always; try_files $uri =404; } location /.well-known/acme-challenge/ { root /var/www/certbot; } location / { limit_req zone=general burst=20 nodelay; try_files $uri $uri/ =404; } error_page 404 /404.html; access_log /var/log/nginx/{{PRODUCT_NAME}}-access.log; error_log /var/log/nginx/{{PRODUCT_NAME}}-error.log; } CONF_TEMPLATE sed -i.bak "s/{{DOMAIN}}/${DOMAIN}/g" "${CONF_DIR}/${DOMAIN}.conf" sed -i.bak "s/{{PRODUCT_NAME}}/${PRODUCT_NAME}/g" "${CONF_DIR}/${DOMAIN}.conf" rm -f "${CONF_DIR}/${DOMAIN}.conf.bak" echo "✅ 产品站点 ${PRODUCT_NAME} 配置完成" echo "" echo "后续步骤:" echo " 1. 添加 DNS A 记录: ${DOMAIN} -> 服务器IP" echo " 2. 申请 SSL 证书: ./scripts/ssl-product-site.sh ${DOMAIN}" echo " 3. 重载 Nginx: docker exec novalon-nginx-secure nginx -s reload"