DevToolBox免费
博客

Nginx 配置示例:反向代理、SSL 和静态站点

11 分钟阅读作者 DevToolBox

Nginx 是全球最流行的 Web 服务器,支撑着超过 30% 的网站。无论你需要提供静态文件、设置反向代理、配置 SSL 还是在多个后端之间进行负载均衡,本全面的 Nginx 配置指南提供了可直接使用的生产级示例。每个配置块都包含详细的注释说明。

Nginx 基础

Nginx(发音为 "engine-x")是一个高性能的 HTTP 服务器、反向代理和负载均衡器。其事件驱动架构以极少的内存处理数千个并发连接。主配置文件通常位于 /etc/nginx/nginx.conf,站点配置位于 /etc/nginx/conf.d//etc/nginx/sites-available/

# Main configuration file structure
# /etc/nginx/nginx.conf

user nginx;
worker_processes auto;          # One worker per CPU core
error_log /var/log/nginx/error.log warn;
pid /run/nginx.pid;

events {
    worker_connections 1024;    # Max connections per worker
    multi_accept on;            # Accept multiple connections at once
}

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

    # Logging format
    log_format main '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent"';

    access_log /var/log/nginx/access.log main;

    sendfile on;                # Efficient file transfer
    tcp_nopush on;              # Optimize TCP packets
    tcp_nodelay on;             # Disable Nagle's algorithm
    keepalive_timeout 65;       # Keep connections alive
    types_hash_max_size 2048;

    # Include site configurations
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}

静态站点配置

最简单也最常见的用例:直接从磁盘提供 HTML、CSS、JavaScript 和图片文件。此配置包含缓存头以获得最佳性能。

# Static website configuration
# /etc/nginx/conf.d/static-site.conf

server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;

    # Document root
    root /var/www/example.com/html;
    index index.html index.htm;

    # Main location block
    location / {
        try_files $uri $uri/ =404;
    }

    # Cache static assets aggressively
    location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2|ttf|eot)$ {
        expires 30d;
        add_header Cache-Control "public, immutable";
        access_log off;
    }

    # Cache HTML files with shorter duration
    location ~* \.html$ {
        expires 1h;
        add_header Cache-Control "public, must-revalidate";
    }

    # Deny access to hidden files (.htaccess, .git, etc.)
    location ~ /\. {
        deny all;
        access_log off;
        log_not_found off;
    }

    # Custom error pages
    error_page 404 /404.html;
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
        root /usr/share/nginx/html;
    }

    access_log /var/log/nginx/example.com.access.log;
    error_log /var/log/nginx/example.com.error.log;
}

反向代理配置

反向代理位于客户端和后端应用(Node.js、Python、Go 等)之间,转发请求并返回响应。这是 Web 应用最常见的生产部署方式。

# Reverse proxy to Node.js/Python/Go application
# /etc/nginx/conf.d/app-proxy.conf

server {
    listen 80;
    server_name app.example.com;

    # Max upload size
    client_max_body_size 50M;

    # Proxy all requests to the backend application
    location / {
        proxy_pass http://127.0.0.1:3000;

        # Pass the real client IP to the backend
        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 support (for Socket.IO, etc.)
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        # Timeouts
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;

        # Buffering settings
        proxy_buffering on;
        proxy_buffer_size 4k;
        proxy_buffers 8 4k;
    }

    # Serve static files directly (bypass the backend)
    location /static/ {
        alias /var/www/app/static/;
        expires 30d;
        add_header Cache-Control "public, immutable";
    }

    # Health check endpoint
    location /health {
        proxy_pass http://127.0.0.1:3000/health;
        access_log off;
    }

    access_log /var/log/nginx/app.access.log;
    error_log /var/log/nginx/app.error.log;
}

SSL/TLS 配置

使用 HTTPS 保护你的站点是现代 Web 开发的必备要求。此配置使用 Let's Encrypt 证书,遵循当前 TLS 安全最佳实践,包括强加密套件和 HSTS。

# SSL/TLS configuration with Let's Encrypt
# /etc/nginx/conf.d/ssl-site.conf

# Redirect all HTTP traffic to HTTPS
server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;

    # Let's Encrypt ACME challenge
    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }

    # 301 permanent redirect to HTTPS
    location / {
        return 301 https://$server_name$request_uri;
    }
}

# HTTPS server block
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name example.com www.example.com;

    # Let's Encrypt certificate paths
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    # SSL session settings
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;

    # Modern TLS configuration (TLS 1.2 + 1.3 only)
    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:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;

    # OCSP Stapling (faster certificate verification)
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;

    # HSTS (force HTTPS for 2 years, including subdomains)
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;

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

    location / {
        try_files $uri $uri/ =404;
    }

    access_log /var/log/nginx/example.com.ssl.access.log;
    error_log /var/log/nginx/example.com.ssl.error.log;
}

SPA(React/Vue/Angular)配置

单页应用使用客户端路由,这意味着所有路由必须回退到 index.html。此配置正确处理了这一点,同时也高效地提供静态资源。

# SPA configuration (React, Vue, Angular, Next.js static export)
# /etc/nginx/conf.d/spa.conf

server {
    listen 80;
    server_name spa.example.com;

    root /var/www/spa/dist;
    index index.html;

    # The key directive for SPAs: fallback to index.html
    # This ensures client-side routing works correctly
    location / {
        try_files $uri $uri/ /index.html;
    }

    # Cache JavaScript and CSS bundles (with hash in filename)
    location ~* \.(js|css)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
        access_log off;
    }

    # Cache images, fonts, and media
    location ~* \.(jpg|jpeg|png|gif|ico|svg|webp|avif|woff|woff2|ttf|eot|mp4|webm)$ {
        expires 30d;
        add_header Cache-Control "public";
        access_log off;
    }

    # Do NOT cache index.html (always serve the latest version)
    location = /index.html {
        expires -1;
        add_header Cache-Control "no-store, no-cache, must-revalidate";
    }

    # API proxy (forward /api requests to the backend)
    location /api/ {
        proxy_pass http://127.0.0.1:4000;
        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;
    }

    # Deny access to source maps in production
    location ~* \.map$ {
        deny all;
    }
}

负载均衡

将传入流量分配到多个后端服务器,以实现高可用性和更好的性能。Nginx 开箱支持多种负载均衡算法。

# Load balancing across multiple backend servers
# /etc/nginx/conf.d/load-balancer.conf

# Define backend server group
upstream app_servers {
    # Round-robin (default) - requests distributed evenly
    server 10.0.0.1:3000;
    server 10.0.0.2:3000;
    server 10.0.0.3:3000;

    # Mark a server as backup (used only when others are down)
    server 10.0.0.4:3000 backup;

    # Health check: mark server down after 3 failed attempts
    # max_fails=3  fail_timeout=30s (default)
}

# Weighted load balancing (send more traffic to powerful servers)
upstream app_weighted {
    server 10.0.0.1:3000 weight=5;   # Gets 5x the traffic
    server 10.0.0.2:3000 weight=3;   # Gets 3x the traffic
    server 10.0.0.3:3000 weight=1;   # Gets 1x the traffic
}

# Least connections (send to the server with fewest active requests)
upstream app_least_conn {
    least_conn;
    server 10.0.0.1:3000;
    server 10.0.0.2:3000;
    server 10.0.0.3:3000;
}

# IP hash (same client always goes to same server - sticky sessions)
upstream app_ip_hash {
    ip_hash;
    server 10.0.0.1:3000;
    server 10.0.0.2:3000;
    server 10.0.0.3:3000;
}

server {
    listen 80;
    server_name lb.example.com;

    location / {
        proxy_pass http://app_servers;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        # Connection keep-alive to backends
        proxy_http_version 1.1;
        proxy_set_header Connection "";
    }

    # Simple health check endpoint
    location /nginx-health {
        access_log off;
        return 200 "OK";
        add_header Content-Type text/plain;
    }
}

安全头

HTTP 安全头保护你的站点免受点击劫持、XSS 和内容注入等常见攻击。这些头应添加到每个生产 Nginx 配置中。

# Security headers configuration
# Add these inside your server {} block or create a snippet

# /etc/nginx/snippets/security-headers.conf
# Include with: include /etc/nginx/snippets/security-headers.conf;

# Prevent clickjacking: deny embedding in iframes
add_header X-Frame-Options "SAMEORIGIN" always;

# Prevent MIME-type sniffing
add_header X-Content-Type-Options "nosniff" always;

# Enable XSS protection (legacy browsers)
add_header X-XSS-Protection "1; mode=block" always;

# Control referrer information sent with requests
add_header Referrer-Policy "strict-origin-when-cross-origin" always;

# Content Security Policy (customize based on your needs)
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https://cdn.example.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: https:; font-src 'self' https://fonts.gstatic.com; connect-src 'self' https://api.example.com; frame-ancestors 'self';" always;

# Permissions Policy (formerly Feature-Policy)
add_header Permissions-Policy "camera=(), microphone=(), geolocation=(), interest-cohort=()" always;

# Prevent information leakage
add_header X-Permitted-Cross-Domain-Policies "none" always;

# HSTS (only add if you have SSL configured)
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;

# Hide Nginx version number
server_tokens off;

Gzip 压缩

启用 Gzip 压缩可将传输响应的大小减少多达 90%,显著提升页面加载速度。此配置压缩所有文本类型的内容。

# Gzip compression configuration
# Add inside the http {} block in nginx.conf

# Enable gzip compression
gzip on;

# Minimum file size to compress (skip tiny files)
gzip_min_length 256;

# Compression level (1-9, higher = more CPU, smaller files)
# Level 6 is a good balance between compression ratio and CPU usage
gzip_comp_level 6;

# Number and size of compression buffers
gzip_buffers 16 8k;

# Compress responses for HTTP/1.0 clients too
gzip_http_version 1.0;

# Compress all text-based content types
gzip_types
    text/plain
    text/css
    text/xml
    text/javascript
    application/json
    application/javascript
    application/x-javascript
    application/xml
    application/xml+rss
    application/atom+xml
    application/vnd.ms-fontobject
    font/opentype
    font/ttf
    image/svg+xml
    image/x-icon;

# Add Vary: Accept-Encoding header (important for caching proxies)
gzip_vary on;

# Disable gzip for old IE browsers
gzip_disable "MSIE [1-6]\.";

# Enable gzip for proxied requests too
gzip_proxied any;

速率限制

速率限制保护你的服务器免受滥用、暴力攻击和 DDoS。Nginx 的 limit_req 模块使用漏桶算法控制请求速率。

# Rate limiting configuration
# Define zones in the http {} block, apply in server/location blocks

# ── Define rate limit zones (in http {} block) ──

# General rate limit: 10 requests/second per IP
limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;

# Strict rate limit for login/auth: 5 requests/minute per IP
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;

# API rate limit: 30 requests/second per IP
limit_req_zone $binary_remote_addr zone=api:10m rate=30r/s;

# Rate limit by server name (protect against virtual host abuse)
limit_req_zone $server_name zone=per_server:10m rate=100r/s;

# ── Apply rate limits (in server {} block) ──

server {
    listen 80;
    server_name api.example.com;

    # Custom error page for rate-limited requests
    error_page 429 = @rate_limited;
    location @rate_limited {
        default_type application/json;
        return 429 '{"error": "Too many requests. Please try again later."}';
    }

    # General pages: allow burst of 20, no delay for first 10
    location / {
        limit_req zone=general burst=20 nodelay;
        limit_req_status 429;
        proxy_pass http://127.0.0.1:3000;
    }

    # Login endpoint: strict rate limiting
    location /api/auth/login {
        limit_req zone=login burst=3 nodelay;
        limit_req_status 429;
        proxy_pass http://127.0.0.1:3000;
    }

    # API endpoints: higher limit with burst
    location /api/ {
        limit_req zone=api burst=50 nodelay;
        limit_req_status 429;
        proxy_pass http://127.0.0.1:3000;
    }

    # Whitelist certain IPs from rate limiting
    # geo $limit {
    #     default 1;
    #     10.0.0.0/8 0;       # Internal network
    #     192.168.0.0/16 0;   # Local network
    # }
    # map $limit $limit_key {
    #     0 "";
    #     1 $binary_remote_addr;
    # }
    # limit_req_zone $limit_key zone=custom:10m rate=10r/s;
}

常用指令参考

以下是最常用的 Nginx 指令及其说明的快速参考。

指令说明
worker_processes工作进程数(设置为 auto 则等于 CPU 核数)
worker_connections每个工作进程的最大同时连接数
server_name此 server 块响应的域名
listen监听的端口和协议
root文件服务的根目录
index目录请求的默认文件
location匹配请求 URI 以应用特定配置
proxy_pass将请求转发到后端服务器
try_files按顺序尝试提供文件,最后回退到最后一个选项
ssl_certificateSSL 证书文件路径
ssl_certificate_keySSL 私钥文件路径
add_header添加自定义 HTTP 响应头
gzip启用或禁用 gzip 压缩
expires设置静态资源的 Cache-Control max-age
upstream定义一组后端服务器用于负载均衡
limit_req_zone定义速率限制的共享内存区域
error_page为特定状态码定义自定义错误页面
access_log访问日志的路径和格式
error_log错误日志的路径和级别
client_max_body_size客户端请求体的最大允许大小
sendfile启用使用内核 sendfile 的高效文件传输

常见问题

Nginx 和 Apache 有什么区别?

Nginx 使用事件驱动的异步架构,以较低的内存占用高效处理大量并发连接。Apache 传统上使用每连接一个进程或线程的模型,在高负载下消耗更多内存。Nginx 在提供静态内容和作为反向代理方面表现出色,而 Apache 提供更多内置模块和 .htaccess 支持。许多生产环境使用 Nginx 作为 Apache 前面的反向代理。

如何在重载前测试 Nginx 配置?

在重载前始终运行 "nginx -t"。此命令会解析配置文件并检查语法错误而不实际应用更改。如果测试通过,可以安全地使用 "nginx -s reload" 或 "systemctl reload nginx" 重载。在生产环境中切勿不测试就重启 Nginx。

如何使用 Let's Encrypt 设置 SSL 证书?

安装 Certbot 并运行 "certbot --nginx -d yourdomain.com"。Certbot 会自动获取证书并修改你的 Nginx 配置。它还会通过 cron 或 systemd 定时器设置自动续期。证书存储在 /etc/letsencrypt/live/yourdomain.com/。

"proxy_set_header X-Real-IP $remote_addr" 有什么作用?

当 Nginx 作为反向代理时,后端应用看到的是 Nginx 的 IP 而不是客户端 IP。X-Real-IP 头将原始客户端 IP 传递给后端,使你的应用能正确记录真实访客 IP、按用户限速和进行地理定位。

如何在 Nginx 中将 HTTP 重定向到 HTTPS?

创建一个监听 80 端口的单独 server 块,返回 301 重定向:"return 301 https://$server_name$request_uri;"。这确保所有 HTTP 流量被永久重定向到安全的 HTTPS 版本。

try_files 指令是什么?为什么对 SPA 很重要?

try_files 指令告诉 Nginx 按顺序检查文件是否存在并提供第一个找到的文件。对于 SPA,"try_files $uri $uri/ /index.html" 首先尝试提供请求的确切文件,然后查找目录,最后回退到 index.html。这很重要因为 SPA 的路由如 /about 或 /dashboard 并不对应磁盘上的实际文件。

这些 Nginx 配置涵盖了最常见的生产场景。重载前始终使用 "nginx -t" 测试配置,并定期监控访问日志和错误日志以尽早发现问题。

𝕏 Twitterin LinkedIn
这篇文章有帮助吗?

保持更新

获取每周开发技巧和新工具通知。

无垃圾邮件,随时退订。

试试这些相关工具

NXNginx Config Generator.ht.htaccess Generator🛡️CSP Header Generator

相关文章

Docker Compose 速查表:服务、卷和网络

Docker Compose 核心参考:服务定义、卷挂载、网络配置、环境变量和常见栈示例。

.htaccess 重定向速查表:可复制粘贴的示例

完整的 .htaccess 重定向参考。301 重定向、HTTPS 强制、尾斜杠、自定义错误页、安全头和缓存规则。

Nginx 配置生成器 - 在线生成 nginx.conf(免费工具 + 完整指南)

在线生成生产级 nginx.conf 配置文件。涵盖 server 块、反向代理、SSL/TLS、负载均衡、gzip 压缩、安全头、速率限制、缓存,以及静态站点、SPA、API 网关、WordPress 等常见模式。