Skip to content

Nginx生产环境完整配置模板

nginx.conf配置

# main 块(全局配置)
worker_processes auto;  # 自动匹配 CPU 核心数
worker_rlimit_nofile 51200;  # 设置 worker 进程最大 FD 数

# 错误日志
error_log /var/log/nginx/error.log notice; 
error_log /dev/stdout notice; # 将错误日志输出到标准输出,方便 Docker 容器日志管理

# events 块
events {
    worker_connections 5120;  # 单个 worker 最大并发连接
    use epoll;  # 高性能事件模型(Linux 推荐)
    multi_accept on;  # 一次性接受所有新连接
}

http {
    include mime.types;
    default_type application/octet-stream;

    server_tokens off; 
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 60;
    keepalive_requests 1000;

    types_hash_max_size 4096;
    server_names_hash_bucket_size 128;
    client_header_buffer_size 32k;
    client_max_body_size 1024m;

    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 /dev/stdout main; # 将访问日志输出到标准输出,方便 Docker 容器日志管理

    gzip on;
    gzip_min_length 10k;
    gzip_buffers 4 16k;
    gzip_http_version 1.1;
    gzip_comp_level 6;
    gzip_types text/plain application/javascript application/x-javascript text/javascript text/css application/xml;
    gzip_vary on;
    gzip_proxied expired no-cache no-store private auth;
    gzip_disable "MSIE [1-6]\.";

    # 1. 创建限流共享内存区域(仅http块)
    limit_req_zone $binary_remote_addr zone=api:10m rate=100r/s; # 频率限流:单IP 100请求/秒
    limit_conn_zone $binary_remote_addr zone=perip:10m; # 按IP限流区域
    limit_conn_zone $server_name zone=perserver:10m; # 按域名限流区域

    # 2. 全局限流默认值(可在server/location覆盖)
    limit_req_log_level warn; # 频率限流触发时记录 warn 日志
    limit_req_status 429; # 频率限流返回 429(请求过多),而非默认 503
    limit_conn_log_level warn; # 并发限流触发时记录 warn 日志
    limit_conn_status 503; # 并发限流返回503错误(默认503)

    include /etc/nginx/conf/conf.d/*.conf; 
}

server.conf配置

# 上游服务
upstream gateway {
    least_conn;
    server 10.0.1.10:8080 weight=1 max_fails=3 fail_timeout=30s;
    server 10.0.1.11:8080 weight=1 max_fails=3 fail_timeout=30s backup;
    keepalive 100;
}

# 前端站点
server {
    listen 80;
    listen 443 ssl http2;
    server_name www.example.com example.com;

    access_log /www/sites/www.example.com/log/access.log main;
    error_log /www/sites/www.example.com/log/error.log notice;

    location ~ ^/(\.user.ini|\.htaccess|\.git|\.env|\.svn|\.project|LICENSE|README.md) {
        return 404; 
    }

    # 3. 生效限流规则
    limit_conn perip 100; # 单个IP最多100个并发连接
    limit_conn perserver 1000; # 该域名总并发最多1000个连接
    limit_req zone=api burst=100 nodelay; # 频率限流:基础速率 + 突发缓冲 + 无延迟

    if ($scheme = http) {
        return 301 https://$host$request_uri;
    }

    ssl_certificate /www/sites/www.example.com/ssl/fullchain.pem;
    ssl_certificate_key /www/sites/www.example.com/ssl/privkey.pem;
    ssl_protocols TLSv1.3 TLSv1.2;
    ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:!aNULL:!eNULL:!EXPORT:!DSS:!DES:!RC4:!3DES:!MD5:!PSK:!KRB5:!SRP:!CAMELLIA:!SEED;
    ssl_prefer_server_ciphers off;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    error_page 497 https://$host$request_uri;
    proxy_set_header X-Forwarded-Proto https;

    # 安全头
    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-Content-Type-Options "nosniff";
    add_header X-XSS-Protection "1; mode=block";
    add_header Strict-Transport-Security "max-age=31536000";

    root /www/sites/www.example.com/index; 
    index index.html;

    # 静态资源
    location ~* .*\.(js|css|png|jpg|jpeg|gif|webp|webm|avif|ico|bmp|swf|eot|svg|ttf|woff2?)$ {
        expires 30d;
        access_log off;
        log_not_found off;
        add_header Cache-Control "public, immutable";
    }

    # SPA路由
    location / {
        try_files $uri $uri/ /index.html;
    }

    # 配置 stub_status 访问路径(推荐设置访问限制,提高安全性)
    location /nginx_status {
        # 启用统计信息功能
        stub_status on;
        # 关闭日志记录(避免统计请求占用日志空间)
        access_log off;
        # 允许指定 IP 访问(安全加固,拒绝所有 IP 后放行信任 IP)
        allow 127.0.0.1; # 允许本地访问
        allow 192.168.1.0/24; # 允许内网网段访问(根据你的实际网段调整)
        deny all; # 拒绝其他所有 IP 访问
    }

    # API代理
    location ^~ /api/ {
        proxy_pass http://gateway/;
        proxy_http_version 1.1;

        # 核心请求头透传(后端识别真实客户端信息)
        proxy_set_header Host $host; # 透传客户端请求的 Host 头
        proxy_set_header X-Real-IP $remote_addr; # 透传客户端真实 IP
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 透传代理链 IP(含多层代理)
        proxy_set_header X-Forwarded-Proto $scheme; # 透传协议(http/https)
        proxy_set_header X-Forwarded-Port $server_port; # 透传客户端访问的端口
        proxy_set_header Connection "";  # 清空 Connection 头,避免后端关闭长连接

        # 响应头配置
        add_header X-Cache $upstream_cache_status; # 标识后端缓存状态(HIT/MISS/EXPIRED)
        add_header Cache-Control no-cache; # 禁用客户端缓存 API 响应

        # 代理超时配置(配合 fail_timeout)
        proxy_connect_timeout 5s; # 连接后端超时(短一点,快速检测故障)
        proxy_read_timeout 60s; # 读取后端响应超时
        proxy_send_timeout 60s;
    }
}

# API站点(如果需要独立域名)
server {
    listen 80;
    listen 443 ssl http2;
    server_name api.example.com;

    access_log /www/sites/api.example.com/log/access.log main;
    error_log /www/sites/api.example.com/log/error.log notice;

    limit_conn perip 10;
    limit_conn perserver 1000;
    limit_req zone=api burst=100 nodelay;

    if ($scheme = http) {
        return 301 https://$host$request_uri;
    }

    ssl_certificate /www/sites/api.example.com/ssl/fullchain.pem;
    ssl_certificate_key /www/sites/api.example.com/ssl/privkey.pem;
    ssl_protocols TLSv1.3 TLSv1.2;
    ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:!aNULL:!eNULL:!EXPORT:!DSS:!DES:!RC4:!3DES:!MD5:!PSK:!KRB5:!SRP:!CAMELLIA:!SEED;
    ssl_prefer_server_ciphers off;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    error_page 497 https://$host$request_uri;
    proxy_set_header X-Forwarded-Proto https;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-Content-Type-Options "nosniff";
    add_header X-XSS-Protection "1; mode=block";
    add_header Strict-Transport-Security "max-age=31536000";

    location ^~ / {
        proxy_pass http://gateway/;
        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;
        proxy_set_header X-Forwarded-Port $server_port;
        proxy_set_header Connection "";
        add_header X-Cache $upstream_cache_status;
        add_header Cache-Control no-cache;

        proxy_connect_timeout 5s;
        proxy_read_timeout 60s;
        proxy_send_timeout 60s;
    }
}