配置Nginx提高Ghost性能

前面文章详细介绍了在debian上安装ghost。本文介绍如何配置nginx提高ghost性能。

使用UNIX Domain Socket代替IP加端口

这一段是从网上摘抄,据说对性能提升有很大帮助。原帖请看这里 configure unix socket instead of host & port.
首先编辑Ghost的config.js文件。将第24行附近的server

server: {  
    host: '127.0.0.1',
    port: '2368'
 }

替换成下面内容,注意根据自己的ghost安装目录更改路径。

server: {  
    socket: {
        path: '/srv/www/denpe.com/socket.sock',
        permissions: '0666'
    }
}

最终成下面这个样子

var path = require('path'),  
    config;

config = {  
    // ### Production
    // When running Ghost in the wild, use the production environment.
    // Configure your URL and mail settings here
    production: {
        url: 'http://www.denpe.com',
        mail: {},
        database: {
            client: 'sqlite3',
            connection: {
                filename: path.join(__dirname, '/content/data/ghost.db')
            },
            debug: false
        },
       // server: {
       //     host: '127.0.0.1',
      //      port: '2368'
      //  }

        server: {
           socket: {
               path: '/srv/www/denpe.com/socket.sock',
               permissions: '0666'
              }
         }
    },
};

然后pm2 restart ghost重启Ghost,会发现ghost目录下多出一个socket.sock文件夹。设置它的权限为777。这时打开博客会出现502错误,很正常。因为Nginx还没做对应修改。

chmod 777 socket.sock  

配置Nginx

编辑配置文件/etc/nginx/sites-available/denpe.com

首先定义一个upstream来说明ghost运行位置。

upstream ghost_upstream {  
    server unix:/srv/www/denpe.com/socket.sock;
    keepalive 64;
}

这段配置告诉nginx,Ghost运行的路径,同时设定连接保持64秒以避免每个请求都要重建连接。

代理缓存

我们希望nginx能缓存下来自Ghost的响应,从而避免每个(来自客户端)请求都通过反向代理再次向 Ghost 应用发起请求。这时要做的第一件事是在配置文件中设置proxycachepath。下面这段配置设定了一个 100MB 的内存空间来缓存来自 Ghost 的响应,并且会在 24 小时后移除那些没有被再次请求的文件:

proxy_cache_path /srv/www/cache levels=1:2 keys_zone=STATIC:100m inactive=24h max_size=512m;  

1.处理博客页面的 location 字段

下面这个配置将根据对来自 upstream 的 200 响应进行 30 分钟的缓存,对 404 响应进行一分钟的缓存,缓存写入 STATIC 区域。我们同样也希望能够忽略和(或)隐藏掉几条来自 Ghost 的响应头,因为我们将使用自己的 header 信息来取代它。除了在 nginx 上缓存下这些请求,我们同样会在浏览器中进行 10 分钟的缓存,expires 10m;。

location / {  
    proxy_cache STATIC;
    proxy_cache_valid 200 60m;
    proxy_cache_valid 404 1m;
    proxy_ignore_headers X-Accel-Expires Expires        Cache-Control;
    proxy_ignore_headers Set-Cookie;
    proxy_hide_header Set-Cookie;
    proxy_hide_header X-powered-by;    
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $http_host;
    proxy_set_header X-Forwarded-For     $proxy_add_x_forwarded_for;
    proxy_pass http://ghost_upstream;
    expires 10m;
    }

2.处理静态文件的 location 字段

在这个部分,我们将要告诉 nginx 去哪儿找到 Ghost 应用的静态文件,诸如 css、js 和图片。这里需要使用四个 location 字段来分别指向 images 目录、assets 目录、public 目录 和 scripts 目录。我们将使用 expires max; 来缓存这些文件,以便它们能在客户端上永久保存下来。不要担心这样做会来带什么危害,因为当 node.js 初始化时,Ghost 会在每个静态文件(不包括 images 目录下的文件)后面加上一个版本号。注意assets文件夹在主题目录下,请根据主题名更改相应路径。

 location /content/images {
        alias /srv/www/denpe.com/content/images;
        access_log off;
        expires max;        
    }
    location /assets {
        alias /srv/www/denpe.com/content/themes/casper/assets;
        access_log off;
        expires max;         
    }
    location /example {
        alias /srv/www/denpe.com/content/themes/casper/example;
        access_log off;
        expires max;         
    }    

    location /public {
        alias /srv/www/denpe.com/core/built/public;
         access_log off;
        expires max;        
    }

    location /ghost/scripts {
        alias /srv/www/denpe.com/core/built/scripts;
        access_log off;
        expires max;         
    }

3.处理后台管理的location字段 Ghost的后台不应该被缓存,下面代码确保Ghost后台管理登录和登出页面不被缓存。

location ~ ^/(?:ghost|signout) {  
    proxy_set_header   X-Real-IP $remote_addr;
    proxy_set_header   Host      $http_host;
    proxy_pass http://ghost_upstream;
    add_header Cache-Control "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0";
    proxy_redirect off;
    }

完成配置后在后台修改更新文章,页面并不会实时更新。如有必要,可以清楚缓存。

rm -r /srv/www/cache/*  

完整的配置nginx配置文件如下:

upstream ghost_upstream {  
    server unix:/srv/www/denpe.com/socket.sock;
    keepalive 64;
}

proxy_cache_path /srv/www/cache levels=1:2 keys_zone=STATIC:100m inactive=24h max_size=512m;

server {  
    listen 80;
    server_name www.denpe.com;
    add_header X-Cache $upstream_cache_status;
    access_log /srv/www/logs/denpe.com.log;
    error_log  /srv/www/logs/error.log;

    location /content/images {
        alias /srv/www/denpe.com/content/images;
        access_log off;
        expires max;        
    }
    location /assets {
        alias /srv/www/denpe.com/content/themes/casper/assets;
        access_log off;
        expires max;         
    } 

    location /public {
        alias /srv/www/denpe.com/core/built/public;
        access_log off;
        expires max;        
    }

    location /ghost/scripts {
        alias /srv/www/denpe.com/core/built/scripts;
        access_log off;
        expires max;         
    }

    location ~ ^/(?:ghost|signout) {
        proxy_set_header   X-Real-IP $remote_addr;
        proxy_set_header   Host      $http_host;
        proxy_pass http://ghost_upstream;
        add_header Cache-Control "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0";
        proxy_redirect off;
    }
    location / {
        proxy_cache STATIC;
        proxy_cache_valid 200 60m;
        proxy_cache_valid 404 1m;
        proxy_ignore_headers X-Accel-Expires Expires Cache-Control;
        proxy_ignore_headers Set-Cookie;
        proxy_hide_header Set-Cookie;
        proxy_hide_header X-powered-by;    
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://ghost_upstream;
        expires 10m;
    }
}
server {  
    server_name denpe.com 107.167.184.244;
    return 301 http://www.denpe.com$request_uri;
    }

最后面一个server的解释在这里配置Nginx让IP跳转到域名

开启SSL/TLS后的设置

首先将Ghost目录里config.js的第14行url改为https链接。 然后再网站Nginx配置文件的location /location ~ ^/(?:ghost|signout)块里加入proxy_set_header X-Forwarded-Proto https

完整的SSL配置

upstream ghost_upstream {  
    server unix:/srv/www/denpe.com/socket.sock;
      keepalive 64;
}

proxy_cache_path /srv/www/cache levels=1:2 keys_zone=STATIC:100m inactive=24h max_size=512m;

server {  
    listen 443 ssl;
      server_name www.denpe.com;
      ssl on;
      add_header X-Cache $upstream_cache_status;
      access_log /srv/www/logs/denpe.com.log;
      error_log  /srv/www/logs/error.log;
      ssl_dhparam /etc/ssl/private/dhparams_2048.pem;
      ssl_certificate /etc/letsencrypt/live/www.denpe.com/fullchain.pem;
      ssl_certificate_key /etc/letsencrypt/live/www.denpe.com/privkey.pem;
      ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
      ssl_ciphers "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA";
    ssl_prefer_server_ciphers on;
    ssl_session_cache builtin:1000 shared:SSL:10m;
      ssl_session_timeout 10m;
      add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload";
    location /content/images {
        alias /srv/www/denpe.com/content/images;
        access_log off;
        expires max;        
    }
    location /assets {
        alias /srv/www/denpe.com/content/themes/casper/assets;
        access_log off;
        expires max;         
    } 

    location /public {
        alias /srv/www/denpe.com/core/built/public;
         access_log off;
        expires max;        
    }

    location /ghost/scripts {
        alias /srv/www/denpe.com/core/built/scripts;
        access_log off;
        expires max;         
    }

    location ~ ^/(?:ghost|signout) {
        proxy_set_header   X-Real-IP $remote_addr;
        proxy_set_header   Host      $http_host;
        #proxy_set_header X-NginX-Proxy true;
        proxy_pass http://ghost_upstream;
        add_header Cache-Control "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0";
        proxy_set_header X-Forwarded-Proto https;
        proxy_redirect off;
    }
    location / {
        proxy_cache STATIC;
        proxy_cache_valid 200 60m;
        proxy_cache_valid 404 1m;
        proxy_ignore_headers X-Accel-Expires Expires Cache-Control;
        proxy_ignore_headers Set-Cookie;
        proxy_hide_header Set-Cookie;
        proxy_hide_header X-powered-by;    
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
        proxy_pass http://ghost_upstream;
        expires 10m;
    }
}

server {  
        listen 80;
        server_name denpe.com www.denpe.com 107.167.184.244;
        return 301 https://www.denpe.com$request_uri;
    }
server {  
        listen 443;
        server_name denpe.com 107.167.184.244;
        return 301 https://www.denpe.com$request_uri;
    }