Nginx 教程

纯干货教学,从零开始学习 Nginx

Nginx 基础配置

掌握 Nginx 的基本配置语法和常用指令

Nginx 配置文件结构

Nginx 的配置文件采用模块化结构,主要包含以下几个部分:

# 主配置文件结构示例
user nginx;
worker_processes auto;
worker_rlimit_nofile 65536;

events {
    worker_connections 10240;
    use epoll;
    multi_accept on;
}

http {
    include 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;
    error_log /var/log/nginx/error.log warn;
    
    # 性能优化
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    
    # Gzip 压缩
    gzip on;
    gzip_comp_level 6;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
    
    # 包含站点配置
    include /etc/nginx/conf.d/*.conf;
    
    # 虚拟主机配置
    server {
        listen 80;
        server_name example.com www.example.com;
        
        root /var/www/html;
        index index.html index.htm index.php;
        
        location / {
            try_files $uri $uri/ =404;
        }
        
        # 静态文件缓存
        location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
            expires 30d;
            add_header Cache-Control "public, max-age=2592000";
        }
        
        # 错误页面
        error_page 404 /404.html;
        error_page 500 502 503 504 /50x.html;
        
        location = /404.html {
            root /var/www/html;
        }
        
        location = /50x.html {
            root /var/www/html;
        }
    }
}

# 流模块配置(用于 TCP/UDP 代理)
# stream {
#     server {
#         listen 8080;
#         proxy_pass backend_server:8080;
#     }
# }

主要配置块说明:

  • user - 指定 Nginx 进程运行的用户
  • worker_processes - 指定工作进程数量,通常设置为 CPU 核心数
  • worker_rlimit_nofile - 设置每个工作进程可以打开的最大文件数
  • events - 配置事件处理相关参数
  • http - 配置 HTTP 服务器相关参数
  • server - 配置虚拟主机
  • location - 配置 URL 路径匹配规则
  • stream - 配置 TCP/UDP 代理(可选)

配置文件组织最佳实践:

# 主配置文件
/etc/nginx/nginx.conf

# 站点配置文件目录
/etc/nginx/conf.d/
├── default.conf          # 默认站点配置
├── example.com.conf      # 示例站点配置
└── api.example.com.conf  # API 站点配置

# 虚拟主机配置目录(Ubuntu/Debian)
/etc/nginx/sites-available/   # 可用站点配置
/etc/nginx/sites-enabled/     # 启用的站点配置(符号链接)

# 模块配置目录
/etc/nginx/modules-available/  # 可用模块
/etc/nginx/modules-enabled/    # 启用的模块(符号链接)

# 证书目录
/etc/nginx/ssl/

# 日志目录
/var/log/nginx/

Nginx 配置语法基础

指令格式

Nginx 配置指令的基本格式为:

指令名 参数;  # 注释

配置块

配置块使用大括号包围,格式为:

配置块名称 {
    指令1 参数1;
    指令2 参数2;
    ...
}

包含其他配置文件

使用 include 指令可以包含其他配置文件:

# 包含单个文件
include /etc/nginx/mime.types;

# 包含目录下所有 .conf 文件
include /etc/nginx/conf.d/*.conf;

# 包含多个文件
include /etc/nginx/conf.d/site1.conf /etc/nginx/conf.d/site2.conf;

变量使用

Nginx 支持在配置中使用变量,变量以 $ 开头:

# 内置变量示例
server {
    listen 80;
    server_name $host;
    
    location / {
        root /var/www/$host;
        index index.html;
    }
    
    # 自定义变量
    set $custom_var "Hello World";
    
    location /test {
        return 200 "$custom_var";
    }
}

常用内置变量

  • $host - 请求的主机名
  • $uri - 请求的 URI 路径
  • $request_uri - 完整的请求 URI(包含查询参数)
  • $args - 请求参数
  • $remote_addr - 客户端 IP 地址
  • $http_user_agent - 用户代理字符串
  • $status - 响应状态码
  • $request_method - 请求方法(GET、POST 等)
  • $content_length - 请求体长度
  • $cookie_name - 获取指定名称的 cookie 值

条件判断

Nginx 支持使用 if 指令进行条件判断:

server {
    listen 80;
    server_name example.com;
    
    location / {
        if ($http_user_agent ~* "MSIETrident") {
            return 301 https://example.com/ie-not-supported;
        }
        
        if ($request_method !~ ^(GET|POST)$) {
            return 405;
        }
        
        if (!-f $request_filename) {
            return 404;
        }
        
        root /var/www/html;
        index index.html;
    }
}

正则表达式

Nginx 配置中可以使用正则表达式,常用的正则表达式修饰符:

  • ~ - 区分大小写的正则匹配
  • ~* - 不区分大小写的正则匹配
  • !~ - 区分大小写的正则不匹配
  • !~* - 不区分大小写的正则不匹配
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
    expires 30d;
    add_header Cache-Control "public, max-age=2592000";
}

location ~ ^/api/ {
    proxy_pass http://localhost:3000;
}

注释

Nginx 配置中的注释使用 # 开头:

# 这是一行注释
server {
    listen 80;  # 监听 80 端口
    server_name example.com;  # 服务器名称
}

# 多行注释示例
# 配置虚拟主机
# 监听 80 端口
# 服务器名称为 example.com
server {
    listen 80;
    server_name example.com;
}

基本 HTTP 服务器配置

最简单的服务器配置

server {
    listen 80;
    server_name example.com;
    location / {
        root /usr/share/nginx/html;
        index index.html;
    }
}

完整的服务器配置示例

server {
    # 监听端口和 IP
    listen 80;
    listen [::]:80;
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    
    # 服务器名称
    server_name example.com www.example.com;
    
    # SSL 配置(可选)
    ssl_certificate /etc/nginx/ssl/example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;
    
    # 网站根目录
    root /var/www/example.com/public;
    
    # 默认索引文件
    index index.html index.htm index.php;
    
    # 主 location 配置
    location / {
        try_files $uri $uri/ =404;
    }
    
    # PHP 支持(如果需要)
    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php7.4-fpm.sock;
    }
    
    # 静态文件缓存
    location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2|ttf|svg|eot)$ {
        expires 30d;
        add_header Cache-Control "public, max-age=2592000";
        add_header Vary Accept-Encoding;
    }
    
    # 禁止访问隐藏文件
    location ~ /\. {
        deny all;
        access_log off;
        log_not_found off;
    }
    
    # 错误页面
    error_page 404 /404.html;
    error_page 500 502 503 504 /50x.html;
    
    # 错误页面 location
    location = /404.html {
        root /var/www/example.com/errors;
        internal;
    }
    
    location = /50x.html {
        root /var/www/example.com/errors;
        internal;
    }
    
    # 访问日志
    access_log /var/log/nginx/example.com.access.log main;
    error_log /var/log/nginx/example.com.error.log warn;
}

# HTTP 重定向到 HTTPS
server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;
    return 301 https://$host$request_uri;
}

配置说明:

  • listen - 指定服务器监听的端口和 IP 地址
  • server_name - 指定服务器名称,多个名称用空格分隔
  • root - 指定网站根目录
  • index - 指定默认索引文件
  • location - 配置 URL 路径匹配规则
  • try_files - 尝试按顺序查找文件
  • expires - 设置静态文件缓存时间
  • deny - 禁止访问特定路径
  • error_page - 配置错误页面
  • access_log - 配置访问日志
  • error_log - 配置错误日志

多端口配置

# 端口 80 配置
server {
    listen 80;
    server_name example.com;
    return 301 https://$host$request_uri;
}

# 端口 443 配置(HTTPS)
server {
    listen 443 ssl http2;
    server_name example.com;
    
    ssl_certificate /etc/nginx/ssl/example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;
    
    root /var/www/html;
    index index.html;
    
    location / {
        try_files $uri $uri/ =404;
    }
}

# 端口 8080 配置(内部服务)
server {
    listen 8080;
    server_name localhost;
    
    root /var/www/internal;
    index index.html;
    
    location / {
        try_files $uri $uri/ =404;
    }
}

静态文件服务配置

基本静态文件服务

server {
    listen 80;
    server_name example.com;
    root /var/www/html;
    index index.html index.htm;
    
    # 配置静态文件缓存
    location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
        expires 30d;
        add_header Cache-Control "public, max-age=2592000";
    }
    
    # 禁止访问隐藏文件
    location ~ /\. {
        deny all;
    }
}

高级静态文件服务配置

server {
    listen 80;
    server_name static.example.com;
    root /var/www/static;
    
    # 优化静态文件服务
    location / {
        # 启用 sendfile
        sendfile on;
        
        # 启用 tcp_nopush
        tcp_nopush on;
        
        # 启用 tcp_nodelay
        tcp_nodelay on;
        
        # 启用 gzip 压缩
        gzip on;
        gzip_min_length 1000;
        gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript application/x-javascript application/vnd.ms-fontobject application/x-font-ttf font/opentype image/svg+xml image/x-icon;
        
        # 尝试文件
        try_files $uri $uri/ =404;
    }
    
    # 图片文件配置
    location ~* \.(jpg|jpeg|png|gif|webp|avif)$ {
        expires 30d;
        add_header Cache-Control "public, max-age=2592000";
        add_header Vary Accept-Encoding;
        access_log off;
    }
    
    # CSS 和 JS 文件配置
    location ~* \.(css|js)$ {
        expires 7d;
        add_header Cache-Control "public, max-age=604800";
        add_header Vary Accept-Encoding;
        access_log off;
    }
    
    # 字体文件配置
    location ~* \.(woff|woff2|ttf|otf|eot)$ {
        expires 365d;
        add_header Cache-Control "public, max-age=31536000";
        add_header Vary Accept-Encoding;
        access_log off;
    }
    
    # 图标文件配置
    location ~* \.(ico|svg)$ {
        expires 365d;
        add_header Cache-Control "public, max-age=31536000";
        add_header Vary Accept-Encoding;
        access_log off;
    }
    
    # 禁止访问隐藏文件
    location ~ /\. {
        deny all;
        access_log off;
        log_not_found off;
    }
    
    # 禁止访问特定文件类型
    location ~* \.(sh|pl|py|php|cgi|exe|bat)$ {
        deny all;
        access_log off;
        log_not_found off;
    }
    
    # 自定义 404 页面
    error_page 404 /404.html;
    location = /404.html {
        internal;
    }
}

# 静态文件 CDN 配置示例
server {
    listen 80;
    server_name cdn.example.com;
    root /var/www/cdn;
    
    # 跨域资源共享 (CORS)
    location / {
        add_header Access-Control-Allow-Origin *;
        add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
        add_header Access-Control-Allow-Headers "Origin, Content-Type, Accept";
        
        if ($request_method = 'OPTIONS') {
            return 204;
        }
        
        try_files $uri $uri/ =404;
    }
    
    # 静态文件缓存
    location ~* \.(jpg|jpeg|png|gif|webp|avif|css|js|woff|woff2|ttf|otf|eot|ico|svg)$ {
        expires 365d;
        add_header Cache-Control "public, immutable, max-age=31536000";
        add_header Vary Accept-Encoding;
        access_log off;
    }
}

文件类型配置

Nginx 使用 mime.types 文件来映射文件扩展名到 MIME 类型,确保正确的 Content-Type 响应头:

http {
    include mime.types;
    default_type application/octet-stream;
    
    # 自定义 MIME 类型
    types {
        text/plain txt;
        text/html html htm shtml;
        text/css css;
        application/javascript js;
        application/json json;
        image/jpeg jpg jpeg;
        image/png png;
        image/gif gif;
        image/webp webp;
        image/avif avif;
        image/svg+xml svg;
        font/woff woff;
        font/woff2 woff2;
        font/ttf ttf;
        font/otf otf;
        application/vnd.ms-fontobject eot;
        image/x-icon ico;
    }
    
    # 其他配置...
}

静态文件服务最佳实践:

  • 使用专用域名:为静态文件使用专用域名(如 static.example.com 或 cdn.example.com)
  • 启用压缩:启用 gzip 或 brotli 压缩,减少传输大小
  • 设置合理的缓存时间:根据文件类型设置不同的缓存时间
  • 使用 immutable 缓存控制:对于不经常变化的文件使用 immutable 指令
  • 启用 sendfile:提高文件传输性能
  • 配置 CORS:如果静态文件需要跨域访问,配置适当的 CORS 头
  • 禁止执行脚本:禁止在静态文件目录中执行脚本文件
  • 使用 HTTPS:为静态文件服务启用 HTTPS
  • 监控访问日志:监控静态文件的访问情况,优化热门资源
  • 考虑使用 CDN:对于全球用户,考虑使用 CDN 加速静态资源

虚拟主机配置

基于域名的虚拟主机

# 第一个虚拟主机
server {
    listen 80;
    server_name site1.com www.site1.com;
    root /var/www/site1;
    index index.html;
}

# 第二个虚拟主机
server {
    listen 80;
    server_name site2.com www.site2.com;
    root /var/www/site2;
    index index.html;
}

基于端口的虚拟主机

# 端口 80 上的网站
server {
    listen 80;
    server_name example.com;
    root /var/www/site1;
    index index.html;
}

# 端口 8080 上的网站
server {
    listen 8080;
    server_name example.com;
    root /var/www/site2;
    index index.html;
}

location 指令详解

location 匹配规则

  • 精确匹配 - location = /path,完全匹配指定路径
  • 前缀匹配 - location ^~ /path,优先匹配指定前缀
  • 正则匹配 - location ~ /path,区分大小写的正则匹配
  • 正则匹配(不区分大小写) - location ~* /path,不区分大小写的正则匹配
  • 普通前缀匹配 - location /path,普通前缀匹配

location 优先级

  1. 精确匹配 (=)
  2. 前缀匹配 (^~)
  3. 正则匹配 (~~*)
  4. 普通前缀匹配

location 示例

server {
    listen 80;
    server_name example.com;
    
    # 精确匹配根路径
    location = / {
        return 200 "Welcome to homepage";
    }
    
    # 优先匹配静态文件目录
    location ^~ /static/ {
        root /var/www;
    }
    
    # 正则匹配图片文件
    location ~* \.(jpg|jpeg|png|gif)$ {
        root /var/www/images;
        expires 7d;
    }
    
    # 普通前缀匹配
    location /api {
        proxy_pass http://localhost:3000;
    }
    
    # 默认匹配
    location / {
        root /var/www/html;
        index index.html;
    }
}

错误页面配置

自定义错误页面

server {
    listen 80;
    server_name example.com;
    root /var/www/html;
    
    # 配置错误页面
    error_page 404 /404.html;
    error_page 500 502 503 504 /50x.html;
    
    # 错误页面位置
    location = /404.html {
        root /var/www/errors;
    }
    
    location = /50x.html {
        root /var/www/errors;
    }
}

错误页面内容示例

<!-- 404.html -->
<!DOCTYPE html>
<html>
<head>
    <title>404 Not Found</title>
    <style>
        body { font-family: Arial, sans-serif; text-align: center; padding: 50px; }
        h1 { font-size: 48px; color: #333; }
        p { font-size: 18px; color: #666; }
    </style>
</head>
<body>
    <h1>404 Not Found</h1>
    <p>Sorry, the page you are looking for does not exist.</p>
    <p><a href="/">Go back to homepage</a></p>
</body>
</html>

日志配置

访问日志配置

http {
    # 访问日志格式定义
    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;
    
    # 错误日志文件
    error_log /var/log/nginx/error.log warn;
    
    # 其他配置...
}

按虚拟主机分离日志

server {
    listen 80;
    server_name site1.com;
    root /var/www/site1;
    
    # 独立的访问日志
    access_log /var/log/nginx/site1.access.log main;
    # 独立的错误日志
    error_log /var/log/nginx/site1.error.log warn;
    
    # 其他配置...
}

server {
    listen 80;
    server_name site2.com;
    root /var/www/site2;
    
    # 独立的访问日志
    access_log /var/log/nginx/site2.access.log main;
    # 独立的错误日志
    error_log /var/log/nginx/site2.error.log warn;
    
    # 其他配置...
}

配置管理命令

测试配置文件

nginx -t

重新加载配置

nginx -s reload

停止 Nginx

nginx -s stop

启动 Nginx

nginx

实践练习

练习 1:创建基本网站

  1. 创建网站目录:mkdir -p /var/www/mywebsite
  2. 创建 index.html 文件:
    <!DOCTYPE html>
    <html>
    <head>
        <title>My Website</title>
    </head>
    <body>
        <h1>Welcome to My Website</h1>
        <p>This is a basic website served by Nginx.</p>
    </body>
    </html>
  3. 创建 Nginx 配置文件:
    server {
        listen 80;
        server_name mywebsite.local;
        root /var/www/mywebsite;
        index index.html;
    }
    
  4. 测试配置:nginx -t
  5. 重新加载配置:nginx -s reload
  6. 在本地 hosts 文件中添加:127.0.0.1 mywebsite.local
  7. 在浏览器中访问:http://mywebsite.local

练习 2:配置静态文件缓存

  1. 在网站目录中创建 static 子目录
  2. static 目录中添加一些静态文件(如 CSS、JS、图片等)
  3. 更新 Nginx 配置,添加静态文件缓存规则:
    server {
        # 现有配置...
        
        location /static/ {
            expires 7d;
            add_header Cache-Control "public, max-age=604800";
        }
    }
    
  4. 测试配置并重新加载
  5. 使用浏览器开发者工具检查静态文件的响应头,确认缓存设置生效

常见问题解答

Q: Nginx 配置文件的默认位置在哪里?

A: 不同系统的默认位置可能不同:

  • Ubuntu/Debian: /etc/nginx/nginx.conf
  • CentOS/RHEL: /etc/nginx/nginx.conf
  • Windows: nginx/conf/nginx.conf(安装目录下)

Q: 如何检查 Nginx 是否正在运行?

A: 可以使用以下命令:

# 检查进程
ps aux | grep nginx

# 检查端口
netstat -tuln | grep :80

# 使用 systemctl(系统服务)
systemctl status nginx

Q: 为什么我的配置修改没有生效?

A: 可能的原因:

  • 配置文件有语法错误
  • 没有重新加载配置
  • 配置文件路径不正确
  • 权限问题

解决方法:

  • 使用 nginx -t 检查配置语法
  • 使用 nginx -s reload 重新加载配置
  • 确认配置文件路径正确
  • 检查文件和目录权限