Nginx 实操-静态资源服务器

静态网站

Nginx 可以作为静态资源服务器,当只有静态资源的时候,就可以使用 Nginx 来做服务器,例如,如果一个网站只是静态页面的话,就可以通过类似以下的配置来实现部署一个静态的网站:

http {
  log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

  server {
    listen       80;
    server_name  docs.chenfangxu.com;

    access_log logs/docs.chenfangxu.com.access.log main;

    location / {
        root   /usr/local/app;
        index  index.html;
    }
  }
}

这样如果访问 http://docs.chenfangxu.comarrow-up-right 就会默认访问到 usr/local/app 目录下面的 index.html

静态目录服务

访问 http://static.chenfangxu.comarrow-up-right,就可以看到一个简单的目录。

gzip 压缩

使用 gzip 不仅需要 Nginx 配置,浏览器端也需要配合,需要在请求头中包含 Accept-Encoding: gzip(IE5 之后所有的浏览器都支持了,是现代浏览器的默认设置)。一般在请求 html 和 css 等静态资源的时候,支持的浏览器在 request 请求静态资源的时候,会加上 Accept-Encoding: gzip 这个 header,表示自己支持 gzip 的压缩方式,Nginx 在拿到这个请求的时候,如果有相应配置,就会返回经过 gzip 压缩过的文件给浏览器,并在 response 相应的时候加上 content-encoding: gzip 来告诉浏览器自己采用的压缩方式(因为浏览器在传给服务器的时候一般还告诉服务器自己支持好几种压缩方式),浏览器拿到压缩的文件后,根据自己的解压方式进行解析。

这个配置可以插入到 http 上下文里,也可以插入到需要使用的虚拟主机的 server 或者下面的 location 上下文中。

  • gzip_typs:要采用 gzip 压缩的 MIME 文件类型,其中 text/html 被系统强制启用。

  • gzip_static:默认为 off,该模块启用后,Nginx 首先检查请求的静态文件是否有 .gz 结尾的文件,如果有,直接返回该 .gz 文件内容。

  • gzip_proxied:默认为 off,Nginx 作为反向代理时启用,用于设置启用或禁用从代理服务器收到相应内容 gzip 压缩。

  • gzip_vary:用于在相应消息头中添加 Vary: Accept-Encoding,使代理服务器根据请求头中的 Accept-Encoding识别是否启用 gzip 压缩。

  • gzip_comp_level:gzip 压缩比,压缩级别是 1-9,1 压缩级别最低,9 压缩级别最高,级别越高压缩率越高,压缩时间也越长,建议 4 - 6。

  • gzip_buffers:获取多少内存用于缓存压缩结果, 16 8k 表示以 8k * 16 为单位获得,以 8k 为单位,按照原始数据大小以 8k 为单位的 16 倍申请内存。

  • gzip_min_length:允许压缩的页面最小字节数,页面字节数从 header 头中的 Content-Length 中获取。默认值是 0,不管页面多大都压缩。建议设置成大于 1k 的字节数,小于 1k,可能会越压越大。

  • gzip_http_version:默认 1.1,启用 gzip 所需的 HTTP 最低版本。

可以通过网页 GZIP 压缩检测,看一下 docs.chenfangxu.com 的相关数据。

前端项目 gzip 压缩

当前端项目使用 Webpack 等打包工具进行打包时,一般都有配置可以开启 gzip 压缩,打包出来的文件会有经过 gzip 压缩之后的 .gz 文件。

为什么在 Nginx 已经有了 gzip 压缩,打包工具还需要整个 gzip 呢?

因为如果全都是使用 Nginx 来压缩文件,会耗费服务器的计算资源,如果 gzip_comp_level 配置的比较高,就更增加了服务器的开销,相应也会增加客户端的请求时间,得不偿失。

如果压缩在前端打包的时候就做了,把打包之后的高压缩等级文件作为静态资源放在服务器上,Nginx 会优先查找这些压缩之后的文件返回给客户端,相当于把压缩文件的动作从 Nginx 提前到了打包的时候完成, 节约了服务器资源,所以一般推荐在生产环境使用打包工具配置 gzip 压缩。

配置 HTTPS

HTTPS 是在应用层 HTTP 之下加入了表示层 SSL(Secure Socket Layer)/TLS(Transport Layer Security)。 Nginx 配置 HTTPS 主要两个步骤:签署第三方可信任的 SSL 证书配置 HTTPS

例如腾讯云申请的免费证书,下载证书压缩文件,解压后把 Nginx 文件夹下的 xxx.crtxxx.key 文件拷贝到服务器目录 /usr/local/nginx/conf/ssl。在编译安装的时候添加了 ssl 和 http2 相关的模块,可以直接如下配置:

ssl_protocolsssl_ciphers 可以用来限制连接只包含 SSL/TLS 的加强版本和算法,默认值如下:

由于这两个命令的默认值已经好几次发生了改变,因此不建议显性定义,除非有需要额外定义的值,如定义 D-H 算法:

首先在目录 /etc/ssl/certs 运行 openssl dhparam -out dhparam.pem 2048 ,生成 dhparam.pem 文件,然后增加配置:

创建证书(自签名证书 Chrome 会不允许访问)

  • 创建根证书

    • 创建 CA 私钥

      • openssl genrsa -out ca.key 2048

    • 制作 CA 公钥

      • openssl req -new -x509 -days 3650 -key ca.key -out ca.crt

  • 签发证书

    • 创建私钥

      • openssl genrsa -out a.pem 1024

      • openssl rsa -in a.pem -out a.key

    • 生成签发请求

      • openssl req -new -key a.pem -out a.csr -subj "/C=CN/ST=BJ/L=BJ/O=a/OU=a/CN=*.a.com"

    • 使用 CA 证书进行签发

      • openssl x509 -req -sha256 -in a.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 3650 -out a.crt

    • 验证签发证书是否正确

      • openssl verify -CAfile ca.crt a.crt

HTTP 重定向到 HTTPS

之前配置过 http://docs.chenfangxu.comarrow-up-right,我们可以修改配置,当访问 http 时重定向到 https:

配置文件优化

为了让更多的二级域名支持 https 功能,每个 server 都这么写又太麻烦。可以将 https 相关的 listen、ssl、add_header 相关的单独写在一个文件上,然后使用 include 指令引入。

新建 conf.custom 文件夹,编写配置 vim /usr/local/nginx/conf/conf.custom/https-base.conf

gzip 也可以同样优化一下

vim /usr/local/nginx/conf/conf.custom/gzip-base.conf

之后在 /usr/local/nginx/conf/nginx.conf 中新增配置:

推荐阅读

Nginx 配置 HTTPS 服务器arrow-up-right

Last updated