Skip to content

Nginx 快速开始

apt 安装

在 Ubuntu 系统上可以直接使用 apt 命令安装,不过版本是 1.18.0,若想体验较新版本,可以从 nginx 官方源安装。

shell
sudo apt install nginx

从官方源安装

从官方软件源安装 1.24.0

官方文档地址

导入官方签名密钥

shell
curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
    | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null

验证下载的文件是否包含正确的密钥

shell
gpg --dry-run --quiet --no-keyring --import --import-options import-show \
        /usr/share/keyrings/nginx-archive-keyring.gpg

输出应包含完整指纹573 BFD6 B3 D8 FBC641079 A6 ABABF5 BD827 BD9 BF62,如下所示

shell
pub   rsa2048 2011-08-19 [SC] [expires: 2024-06-14]
      573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62
uid                      nginx signing key <signing-key@nginx.com>

设置 apt 存储库

如果要使用 stable 版本,执行此命令

shell
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" \
    | sudo tee /etc/apt/sources.list.d/nginx.list

如果要使用 mainline 版本,执行此命令

shell
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
http://nginx.org/packages/mainline/ubuntu `lsb_release -cs` nginx" \
    | sudo tee /etc/apt/sources.list.d/nginx.list

安装

shell
sudo apt update
sudo apt install nginx

配置

全局配置

参照注释按需配置

nginx
# ...

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"';

    # 自定义一个日志格式
    log_format detail '[$time_local] ($remote_addr - $remote_user)'
                      '"$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;

    keepalive_timeout  65;

    # 禁止 Nginx 默认页面返回版本信息
    server_tokens off;
    # 设置字符集
    charset utf-8;
    # client_max_body_size 1024m;

    # 开启 gzip 压缩
    gzip  on;
    gzip_buffers 16 8k;
    gzip_min_length 2k;
    gzip_comp_level 5;
    gzip_types application/atom+xml application/geo+json application/javascript application/x-javascript application/json application/ld+json application/manifest+json application/rdf+xml application/rss+xml application/xhtml+xml application/xml font/eot font/otf font/ttf image/svg+xml text/css text/javascript text/plain text/xml;
    gzip_vary on;

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

主机配置

参照注释按需配置

nginx
server {
    # 普通 http 协议
    listen       80;
    # 开启 https 协议
    listen       443 ssl;
    server_name  niekel.cn;

    # ssl使用缓存优化
    ssl_session_cache   shared:SSL:10m;
    ssl_session_timeout 10m;
    keepalive_timeout   65;

    # ssl证书
    ssl_certificate     /home/user/cert.crt;
    ssl_certificate_key /home/user/cert.key;
    ssl_protocols       TLSv1.2 TLSv1.3;
    ssl_ciphers         ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;

    # 指定访问日志 路径  格式(在全局中添加的)
    access_log  /var/log/nginx/niekel.cn.access.log  main;

    # 如果有需要的话,可以定义最大上传文件大小。
    # client_max_body_size 1024m;

    # 减少点击劫持
    add_header X-Frame-Options DENY;
    # 禁止服务器自动解析资源类型
    add_header X-Content-Type-Options nosniff;
    # 防XSS攻击
    add_header X-Xss-Protection "1;mode=block";                                     

    location / {
        root   /opt/service/webapps;
        index  index.html;
        # 如果使用 history 模式,可以使用此配置解决刷新 404 的问题
        # try_files $uri $uri/ /index.html;
    }

    # 二级路径
    location /vue-project {
        alias /opt/service/webapps/vue-project/;
        index  index.html;
        # 如果使用 history 模式,可以使用此配置解决刷新 404 的问题
        # 二级目录并且使用 alias,注意要加上前缀
        # try_files $uri $uri/ /vue-project/index.html;
    }

    # 反向代理
    location ^~/api/ {
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header REMOTE-HOST $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://localhost:9000/;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /opt/service/webapps;
    }
}

location 部分详细解释

匹配顺序

nginx有两层指令来匹配请求 URI 。第一个层次是 server 指令,它通过域名、ip 和端口来做第一层级匹配,当找到匹配的 server 后就进入此 server 的 location 匹配。

location 的匹配并不完全按照其在配置文件中出现的顺序来匹配,请求 URI 会按如下规则进行匹配:

  1. 先精准匹配 = ,精准匹配成功则会立即停止其他类型匹配;
  2. 没有精准匹配成功时,进行前缀匹配。先查找带有 ^~ 的前缀匹配,带有 ^~ 的前缀匹配成功则立即停止其他类型匹配,普通前缀匹配(不带参数 ^~ )成功则会暂存,继续查找正则匹配;
  3. = 和 ^~ 均未匹配成功前提下,查找正则匹配 ~ 和 ~* 。当同时有多个正则匹配时,按其在配置文件中出现的先后顺序优先匹配,命中则立即停止其他类型匹配;
  4. 所有正则匹配均未成功时,返回步骤 2 中暂存的普通前缀匹配(不带参数 ^~ )结果

以上规则简单总结就是优先级从高到低依次为(序号越小优先级越高):

1. location =    # 精准匹配
2. location ^~   # 带参前缀匹配
3. location ~    # 正则匹配(区分大小写)
4. location ~*   # 正则匹配(不区分大小写)
5. location /a   # 普通前缀匹配,优先级低于带参数前缀匹配。
6. location /    # 任何没有匹配成功的,都会匹配这里处理

另一种解释

location 的匹配顺序,是先遍历所有的普通前缀,也就是说普通前缀和出现顺序无关。如果有精确匹配 = 的,就停止。否则先记下最长的普通前缀,当最长前缀恰好是 ^~ 匹配的,那么就不会进行正则匹配。否则,进行正则匹配。正则匹配时,nginx 按正则在配置文件的出现顺序,逐一匹配,第一个命中正则,就会使用正则的 location。如果,所有正则都没有匹配上,就会使用之前记住的最长普通前缀。

匹配时 url 的写法

关于 URI 尾部的 / 有三点也需要说明一下。第一点与 location 配置有关,其他两点无关。

  1. location 中的字符有没有 / 都没有影响。也就是说 /user/ 和 /user 是一样的。
  2. 如果 URI 结构是 https://domain.com/ 的形式,尾部有没有 / 都不会造成重定向。因为浏览器在发起请求的时候,默认加上了 / 。虽然很多浏览器在地址栏里也不会显示 / 。这一点,可以访问 baidu 验证一下。
  3. 如果 URI 的结构是 https://domain.com/some-dir/ 。尾部如果缺少 / 将导致重定向。因为根据约定,URL 尾部的 / 表示目录,没有 / 表示文件。所以访问 /some-dir/ 时,服务器会自动去该目录下找对应的默认文件。如果访问 /some-dir 的话,服务器会先去找 some-dir 文件,找不到的话会将 some-dir 当成目录,重定向到 /some-dir/ ,去该目录下找默认文件。

转发时 url 的写法

外部访问地址为 http://ip/api/xxx

proxy_pass \ location/api//api
http://localhost/http://localhost/ xxxhttp://localhost/ /xxx
http://localhosthttp://localhost /api/xxxhttp://localhost /api/xxx
http://localhost/a/http://localhost/a/ xxxhttp://localhost/a/ /xxx
http://localhost/ahttp://localhost/a xxxhttp://localhost/a /xxx

总结

如果 proxy_pass 代理的 url 只有域名和端口(根路径/也不能有),那么此时会把请求 url 的 资源路径 部分全部拼接到 proxy_pass 后面,否则会将 location 匹配到的剩余的部分追加到 proxy_pass 后面。 结论:proxy_pass 和 location 所以要么都带上 /,要么都不带 /

常用命令

使用 nginx -h 可查看所有命令及使用方法

shell
nginx -s reload  # 向主进程发送信号,重新加载配置文件,热重启
nginx -s reopen  # 重启 Nginx
nginx -s stop    # 快速关闭
nginx -s quit    # 等待工作进程处理完成后关闭
nginx -T         # 查看当前 Nginx 最终的配置
nginx -t -c <配置路>  # 检查配置是否有问题,如果已经在配置目录,则不需要 -c