ngixn conditionally reverse proxy or serve directly
The basic solution is, make nginx as a reverse-proxy with fail_timout, when it receives a request, it dispatch to the upstreams where Ubuntu has higher priority, and if Ubuntu is offline, RPi will handle the request by itself.
This requires:
- mysql can be access by two clients with different ip, which is already supported;
- wordpress should be the same for RPi and Ubuntu, which can be done by nfs share;
- nginx should be correctly configured.
Below is the details of configuration.
Note, in my configureation:
- RPi's IP is 192.168.1.100, Ubuntu's IP is 192.168.1.101;
- The wordpress only allows https, all http requests are redirected to https;
- Server listens at port 80 and 443, upstreams listen on port 8000;
Mysql
Set bind-address = 192.168.1.100
in /etc/mysql/my.cnf
, and make sure skip-networking
is not defined;
Grant permission to RPi and Ubuntu in mysql's console:
grant all on minewpdb.* to 'mineblog'@'192.168.1.100' identified by 'xxx';grant all on minewpdb.* to 'mineblog'@'192.168.1.100' identified by 'xxx';
Wordpress
Set DB_HOST correctly:
define('DB_NAME', 'minewpdb');define('DB_USER', 'mineblog');define('DB_PASSWORD', 'xxx');define('DB_HOST', '192.168.1.100');
NFS
On RPi, install nfs-kernel-server, and export by /etc/exports
/path/to/wordpress 192.168.1.101(rw,no_root_squash,insecure,sync,no_subtree_check)
To enable nfs server on RPi, rpcbind is also required:
sudo service rpcbind startsudo update-rc.d rpcbind enablesudo service nfs-kernel-server start
On Ubuntu, mount the nfs (it should also be set in /etc/fstab to make it mount automatically)
sudo mount -t nfs 192.168.1.100:/path/to/wordpress /path/to/wordpress
Nginx
On RPi, make a new config file /etc/nginx/sites-available/wordpress-load-balance
, with below parameters:
upstream php { server unix:/var/run/php5-fpm.sock;}upstream mineservers { # upstreams, Ubuntu has much higher priority 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/cert_file; ssl_certificate_key /path/to/cert/cert_key_file; 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 / { # reverse-proxy to upstreams 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; listen 8000; server_name mine260309.me; ... # normal wordpress configurations}
On Ubuntu, it can use the same config file.
Now any request received by RPi's nginx server on port 443, it's dispatched to either Ubuntu or RPi's port 8000, where Ubuntu has much higher priority. If Ubuntu is offline, RPi itself can handle the request as well.
Any comments are welcome!