Tag Archives: Nginx

Enable HTTP2 for WordPress on nginx Ubuntu 14.04

HTTP2 is enabled on mainline version of nginx (v1.9.x), while Ubuntu 14.04 is using nginx 1.4.6.
To enable HTTP2, the simplest way is to upgrade nginx to the mainline version.
But I met several issues during the upgrade, and here’re the steps, the issues and solutions.

Upgrade to mainline nginx

Let’s use nginx’s official pre-built packages.

  • Add below lines into /etc/apt/sources.list.d/nginx.list
    sudo sh -c 'echo deb http://nginx.org/packages/mainline/ubuntu/ trusty nginx >> /etc/apt/sources.list.d/nginx.list'
    sudo sh -c 'echo deb-src http://nginx.org/packages/mainline/ubuntu/ trusty nginx >> /etc/apt/sources.list.d/nginx.list'
    
  • Add nginx apt key
    wget -q -O- http://nginx.org/keys/nginx_signing.key | sudo apt-key add -
    
  • Update ans install nginx
    sudo apt-get update
    sudo apt-get install nginx
    

However, it fails with error that it tries to overwrite nginx-common’s file:

dpkg: error processing archive /var/cache/apt/archives/nginx_1.9.11-1~trusty_amd64.deb (--unpack):
 trying to overwrite '/usr/share/nginx/html/index.html'

The solution is to remove old nginx on Ubuntu and re-install mainline nginx.

sudo apt-get remove nginx-common
sudo apt-get install nginx

Now nginx is upgraded to 1.9.11

Config file changes

  1.   Previously the site config files are stored in /etc/nginx/site-available, and the enabled sites are soft-linked in /etc/nginx/site-enabled/.
    But mainline nginx only load config files in /etc/nginx/conf.d/*.conf.
    So either copy the old config files to conf.d, or add include /etc/nginx/sites-enabled/ in nginx.conf.
  2. Mainline nginx’s user is nginx, but Ubuntu uses www-data, so change it in nginx.conf.
    #user nginx;
    user www-data;
    
  3. Change spdy to http2 in site config.

Reload nginx, and now the site’s HTTP2 is working.
However, try to open any page of WordPress, it just shows a blank page without any error. The log shows HTTP 200 OK.

Blank page issue

After googling the issue, it’s found that a missing FastCGI param is the root cause.
Add below line in /etc/nginx/fastcgi_params:

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

Reload nginx again, and now everything works fine.

Share

Nginx https load-balance on Raspberry Pi

我的Raspberry Pi工作了大约半年之后,文件系统开始出现莫名其妙的问题,各种文件都出现乱码,以至于某系统命令一执行就segment fault。到重新“安装”系统的时候了。

之前主要跑的服务是我的博客,nginx + wordpress搭的,在RPi上因为CPU的问题(php-fpm执行时几乎占满cpu),响应比较慢。既然重新弄了,考虑把某些请求交给家里的其它机器来处理。
家里还有一台跑Ubuntu的笔记本,希望满足如下要求:
1) 如果笔记本开机着,http请求(几乎)都交给笔记本处理;
2) 如果笔记本关机,http请求都由RPi来处理;
这些应该是完全自动实现的。

在Stackoverflow上问了这个问题,有人提示说可以通过nginx的load-balance功能来实现我的需求。于是开始google一番,找到了解决方案。
基本的思想是,把nginx配置成反向代理,笔记本和RPi都作为upstream来处理http请求;通过nfs共享同一个wordpress目录;配置mysql让wordpress访问同一个数据库。
一步一步来配置这些。
其中Raspberry Pi的地址固定为192.168.1.100,笔记本的地址固定为192.168.1.101,数据库名为minewpdb,数据库用户名为minedb

1. 配置Mysql
mysql仍然放在RPi上,让mysql接受网络的请求,这样不同的机器可以用同一个mysql数据库。

sudo vim /etc/mysql/my.cnf
==> 把 bind-address 改成RPi的ip地址
bind-address            = 192.168.1.100

mysql -u root -p #登录mysql控制台
mysql> grant all on minewpdb.* to 'mineblog'@'192.168.1.100' identified by 'xxx'; # 本地RPi的wordpress访问
mysql> grant all on minewpdb.* to 'mineblog'@'192.168.1.101' identified by 'xxx'; # 笔记本的wordpress访问
mysql> quit;
sudo service mysql restart # 重启mysql服务

# 在RPi和笔记本上分别测试一下
mysql -u mineblog -h 192.168.1.100 -p # 如果能登录成功,就ok了

2. 配置wordpress
Wordpress仍然在RPi上,只要修改wordpress的config文件,把数据库的host,用户名和密码都设对就行了。

sudo vim /path/to/wordpress/wp-config.php
==> 修改DB_HOST等参数
define('DB_NAME', 'minewpdb');
define('DB_USER', 'mineblog');
define('DB_PASSWORD', 'xxx');
define('DB_HOST', '192.168.1.100');

3. 配置nfs
在RPi上设置nfs export,让笔记本mount它,这样可以保证跑的wordpress是同一份。


sudo vim /etc/exports
==> 添加wordpress目录到exports
/path/to/wordpress 192.168.1.101(rw,no_root_squash,insecure,sync,no_subtree_check)
sudo service rpcbind start  # RPi的nfs依赖于rpcbind
sudo update-rc.d rpcbind enable  # 设置rpcbind自动启动
sudo service nfs-kernel-server start  # 重启nfs

在笔记本上,mount这个目录:

sudo mount -t nfs 192.168.1.100:/path/to/wordpress /path/to/wordpress

4. 配置nginx
在RPi上要把nginx配置成反向代理,upstream是RPi和笔记本,端口号都是8000,真正的wordpress运行在8000端口上。
添加新的配置文件 /etc/nginx/sites-available/wordpress-load-balance,注意我把http的访问全部重定向到https,以防GFW

# Upstream to abstract backend connection(s) for php
upstream php {
server unix:/var/run/php5-fpm.sock;
}

upstream mineservers {
# 设置两个upstream, 其中笔记本优先,同时设置5s的fail_timout
# 因为局域网很稳定,所以max_fails设成1就行了,
# 如果fail就说明笔记本关机中,让RPi自己来处理
server 192.168.1.101:8000   weight=999 fail_timeout=5s max_fails=1;
server 192.168.1.100:8000;
}

server {
listen 80;
server_name mine260309.me;
rewrite     ^ https://$server_name$request_uri? permanent;
}

server {
listen          443 ssl;
server_name     mine260309.me;

ssl_certificate     /path/to/cert/mine260309.me.2014.chain.crt;
ssl_certificate_key /path/to/cert/mine260309.me.2014.key;
ssl_protocols       SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers         HIGH:!aNULL:!MD5;
access_log         /path/to/wordpress/logs/proxy.log;
error_log            /path/to/wordpress/logs/proxy_error.log;

location / {
# 代理到upstream
proxy_pass  http://mineservers;

### force timeouts if one of backend is died ##
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;

### Set headers ####
proxy_set_header        Accept-Encoding   "";
proxy_set_header        Host            $host;
proxy_set_header        X-Real-IP       $remote_addr;
proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;

### Most PHP, Python, Rails, Java App can use this header ###
#proxy_set_header X-Forwarded-Proto https;##
#This is better##
proxy_set_header        X-Forwarded-Proto $scheme;
add_header              Front-End-Https   on;

### By default we don't want to redirect it ####
proxy_redirect     off;
}
}

server {
root /path/to/wordpress;
# 在8000端口监听
listen          8000;
server_name     mine260309.me;
... # normal wordpress configurations
}

在笔记本上用同样的配置就可以了。

这样,任何一个请求到RPi,它会让nginx优先反向代理到笔记本的nginx的8000端口,由笔记本来处理;
如果笔记本关机,在5秒钟之后它会fail,于是再由RPi自己的8000端口处理。

Q.E.D.

Share