我的博客是用 Hugo 生成的静态站点,生成之后就是一堆 HTML、CSS、JS 和图片文件。这种静态站点最适合用 Nginx 直接托管,速度快、配置简单、资源占用低。
这篇文章分享一下我目前用的 Nginx 配置,算是给静态博客的一个参考模板。
基础配置
最简单的静态博客配置只需要指定根目录和 index 文件:
1server {
2 listen 80;
3 server_name blog.moxuan.xin;
4 root /var/www/blog/public;
5 index index.html;
6
7 location / {
8 try_files $uri $uri/ /index.html;
9 }
10}
try_files $uri $uri/ /index.html 这个配置很重要,因为 Hugo 很多页面是干净的 URL,比如 /about/ 而不是 /about.html。如果直接访问目录找不到文件,就回退到 index.html。
强制 HTTPS
现在 HTTP 基本已经被淘汰了,我直接把所有 80 端口的请求 301 跳转到 HTTPS:
1server {
2 listen 80;
3 server_name blog.moxuan.xin;
4 return 301 https://$server_name$request_uri;
5}
6
7server {
8 listen 443 ssl http2;
9 server_name blog.moxuan.xin;
10 root /var/www/blog/public;
11 index index.html;
12
13 ssl_certificate /etc/letsencrypt/live/blog.moxuan.xin/fullchain.pem;
14 ssl_certificate_key /etc/letsencrypt/live/blog.moxuan.xin/privkey.pem;
15
16 location / {
17 try_files $uri $uri/ /index.html;
18 }
19}
http2 建议加上,能提升多资源并发加载的效率。
启用 Gzip 压缩
静态博客的 HTML、CSS、JS 都是文本,开启 Gzip 能大幅减少传输体积。在 http 块里加:
1gzip on;
2gzip_vary on;
3gzip_proxied any;
4gzip_comp_level 6;
5gzip_types text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml;
gzip_comp_level 是压缩级别,1 最快但压缩率低,9 最慢但压缩率高。一般 6 是个不错的平衡点。
静态资源缓存
对于 CSS、JS、图片这些不常变化的文件,可以让浏览器和 CDN 缓存久一点:
1location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2)$ {
2 expires 6M;
3 access_log off;
4 add_header Cache-Control "public, immutable";
5}
expires 6M 表示缓存 6 个月。如果以后更新了这些文件,可以通过改文件名(比如加 hash)来强制刷新。
图片懒加载配合
Nginx 本身不负责图片懒加载,这是前端的事情。但 Nginx 可以优化图片的传输方式。比如开启 sendfile 和 tcp_nopush:
1sendfile on;
2tcp_nopush on;
3tcp_nodelay on;
这些参数可以提升静态文件的发送效率。
安全相关 Header
顺手加一些安全响应头:
1add_header X-Frame-Options "SAMEORIGIN" always;
2add_header X-Content-Type-Options "nosniff" always;
3add_header Referrer-Policy "strict-origin-when-cross-origin" always;
这些不会直接影响性能,但能提升安全性。
配合 CDN 使用
如果博客流量比较大,建议前面套一个 CDN。我目前用的是 Cloudflare,配置好之后:
- DNS 解析到 Cloudflare。
- Cloudflare 回源到我的源站 Nginx。
- 静态资源被缓存到 Cloudflare 的边缘节点。
CDN 配置我单独写了一篇文章,这里就不展开了。
完整的配置示例
把上面的内容整合起来,我的完整配置大概是这样:
1http {
2 sendfile on;
3 tcp_nopush on;
4 tcp_nodelay on;
5 keepalive_timeout 65;
6
7 gzip on;
8 gzip_vary on;
9 gzip_proxied any;
10 gzip_comp_level 6;
11 gzip_types text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml;
12
13 server {
14 listen 80;
15 server_name blog.moxuan.xin;
16 return 301 https://$server_name$request_uri;
17 }
18
19 server {
20 listen 443 ssl http2;
21 server_name blog.moxuan.xin;
22 root /var/www/blog/public;
23 index index.html;
24
25 ssl_certificate /etc/letsencrypt/live/blog.moxuan.xin/fullchain.pem;
26 ssl_certificate_key /etc/letsencrypt/live/blog.moxuan.xin/privkey.pem;
27
28 add_header X-Frame-Options "SAMEORIGIN" always;
29 add_header X-Content-Type-Options "nosniff" always;
30
31 location / {
32 try_files $uri $uri/ /index.html;
33 }
34
35 location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2)$ {
36 expires 6M;
37 access_log off;
38 add_header Cache-Control "public, immutable";
39 }
40 }
41}
验证配置
每次改完 Nginx 配置,一定要先用 nginx -t 检查语法:
1nginx -t
没有报错再重载:
1nginx -s reload
总结
静态博客的 Nginx 配置不复杂,但有几个点做好了能明显提升体验:
- 强制 HTTPS,启用 HTTP/2。
- 开启 Gzip 压缩,减少传输体积。
- 静态资源长期缓存,配合 CDN 效果更佳。
- 加安全响应头,提升安全性。
如果你也用 Hugo、Hexo、Jekyll 这类静态生成器,这个配置基本可以直接拿去用,改改域名和路径就行。