Skip to content

Instantly share code, notes, and snippets.

@danielwrobert
Created January 2, 2016 01:38
Show Gist options
  • Select an option

  • Save danielwrobert/6412c6e50c41db26db1f to your computer and use it in GitHub Desktop.

Select an option

Save danielwrobert/6412c6e50c41db26db1f to your computer and use it in GitHub Desktop.
Notes for Sitepoint Premium course Faster Websites with Nginx - https://www.sitepoint.com/premium/courses/faster-websites-with-nginx-2757/

Faster Websites with Nginx

Course at SitePoint Premium URL: https://www.sitepoint.com/premium/courses/faster-websites-with-nginx-2757

Lesson 5 - Example: PHP with WordPress

This lesson will look at configuring Nginx with a PHP backend, running WordPress. Will show some advanced Nginx configuration examples, using the WP-SuperCache plugin.

Notes:

  • Install php5-fpm
  • Configure php-fpm at /etc/php5/fpm/pool.d/
    • cd /etc/php5/fpm/pool.d/
  • Edit www.conf file from that location:
    • open - vim www.conf
    • Check user and group to make sure they're set to your user
    • Set `listen = /var/run/php5-fpm.sock
    • Set process manager to be dynamic - pm = dynamic. This will make php children to work like Apache children. Saves a bit of RAM.
    • Set process manager worker limit - pm.max_children = 40. This only works to handle PHP requests. 40 is a high number.
    • Set number of servers to start - pm.start_servers
    • Set minimum number of idle server processes (backups) - pm.min_spare_servers = 4
    • Set maximum number of idle server processes (backups) - pm.min_spare_servers = 5
    • Set process timeouts (max num of requests executed before respawning itself) - pm.max_requests = 500
  • Restart init script - /etc/init.d/php5-fpm restart
  • Configure Nginx to run processes:
    • Move to Nginx dir - cd /etc/nginx/sites-enabled
    • Configure site file - vim example.com
    • See example config file below (from video)

Lesson 6: Advanced Topics

Notes:

TCP Sockets:

  • Can make PHP listen on TCP Socket:
    • Open www.conf file from above section
    • Search for section "The address on which to accept FastCGI requests"
    • Use listen = 127.0.0.1:9000 configuration.
    • Restart PHP: /etc/init.d/php5-fpm restart
    • Update Nginx to inform change to TCP socket:
      • In Nginx config file, change upstream configuration (see example below)
    • Reload Nginx: /etc/init.d/nginx reload

SSL:

  • Add ssl to listen paramteter (see example below).
  • Add cert paths to server paramteter (see example below).
  • SSL directory is relative to /etc/nginx/. So below example certs woud be at /etc/nginx/ssl/example.com.crt.
  • Difference between crt file in Nginx and Apache is that Apache may have separate crt and chain-crt files. If you already have this set up, for Apache, you can actually just concatenate the chain-crt files to the crt file and it will work as expected in Nginx. This is because Nginx you would create one file that has the certificate and the chain certs, all in one file. The certificate comes first and then the chain certs immediately follow, with no spaces in the middle.
  • MAY need to reload Nginx, if you do this as a change later: /etc/init.d/nginx reload

SPDY Support

  • SPDY is a protocol, developed by Google, designed to overcome some of the limitations of vanilla HTTP. Automattic has sponsored development so that Nginx now supports a lot of the important parts of the SPDY protocol (not all). This improves the initial pageload significantly.
  • Need modern version of Nginx.
  • Need OpenSSL version 1.0.1 or greater. This is the tricky part because most UNIX distro's do not ship with these later versions.
  • SPDY support is distributed as a patch. To get the latest patch, visit: nginx.org/patches/spdy/.
  • Once you have the patch file, complete the following steps (also in README at aforementioned patches URL):
    • Patch Nginx with patch command:
      • From Nginx dir run: patch -p1 < ../path-to-patchfile.txt
    • Configure Nginx build: ./configure --with-http_ssl_module --with-http_spdy_module
    • Point OpenSSL to custom version of OpenSSL (unpacked tar ball): --with-openssl=../openssl-1.0.1e. This will point to latest version, regardless of system OpenSSL configuration.
    • Two previous commands should be executed at once with configure: ./configure --with-http_ssl_module --with-http_spdy_module --with-openssl=../openssl-1.0.1e

Extra notes/treats:

Wrap Up

Resources:

Example Nginx config file (/etc/nginx/sites-enabled/example.com)

	# Upstream to abstract backend connection(s) for php
	# Unix socket example:
	upstream php {
		server unix:/var/run/php5-fpm.sock;
	}
	
	# TCP socket example:
	upstream php {
		server 127.0.0.1:9000;
		# Can add multiple servers here to act as a load-balancer.
		# For example, if you have a local network with multiple servers,
		# running this PHP backend. Nginx would assume this to be a load-balenced
		# situation and would distribute all of the requests "round-robin" across these servers.
		# See upstream documentation at the Nginx Wiki.
		server 10.15.0.20:9000;
		server 10.15.0.21:9000;
	}
	
	
	server {
		listen: 205.186.156.173:80 #Be sure to set proper IP
		server_name example.com www.example.com;
		return 301 https://example.com$request_uri;
		# Forces SSL with no `www`
	}
	
	server {
		# Tells port to listen, ssl enables ssl, and spdy enables spdy:
		listen 443 ssl spdy;
		server_name example.com;
	
		access_log /var/log/nginx/example.com-access.log;
		error_log /var/log/nginx/example.com-error.log;
	
		# Sets up SSL cert use.
		# SSL directory is relative to `/etc/nginx/`. So
		# below example certs woud be at `/etc/nginx/ssl/example.com.cert
		ssl_certificate     ssl/example.com.crt;
		ssl_certificate_key ssl/example.com.key;
		ssl_ciphers RC4:HIGH:!aNULL:!MD5;
		ssl_prefer_server_ciphers on;
		add_header Strict-Transport-Security max-age=604800;
		add_header X-Frame-Options DENY;
	
		root /var/www/example.com;
		index index.php index.html;
	
		rewrite ^/sitemap_index\.xml$ /index.php?sitemap=1 last;
		rewrite ^/([^/]+?)-sitemap([0-9]+)?\.xml$ /index.php?sitemap=1&sitemap_n=$2 last;
	
		location = /favicon.ico {
			log_not_found off;
			access_log off;
		}
	
		location = /robots.txt {
			allow all;
			log_not_found off;
			access_log off;
		}
	
		location / {
			include "/etc/nginx/naxsi.rules";
			# This is cool because no php is touched for static content.
			# Include the "?$args" part so non-default permalinks doesn't break when using query string
			try_files $uri $uri/ /index.php?$args;
	
			gzip on;
			default_type text/html;
	
			# Below are some matching settings to make Nginx play nice with WP-Supercache plugin
			# If Nginx request filename is already there, serve and break out of this block
			if ( -f $request_filename ) {
				break;
			}
	
			# Set variables to be used
			set $supercache_file '';
			set $supercache_uri $request_uri;
	
			#If request is a post (someone posting something), unset variable
			if ( $request_method = POST ) {
				set $supercache_uri '';
			}
	
			# If request is a query string (someone searching), unset variable
			if ( $query_string ) {
				set $supercache_uri '';
			}
	
			# If hasn't been unset above, set file variable to match with host protocol (http, https, etc)
			if ( $suercache_uri ~ ^(.+)$ ) {
				set $supercache_file /wp-content/cache/supercache/$http_host/$1index.html;
			}
	
			# If file exists (`-f` in Nginx), rewrite/serve html file as static and break out of block
			if ( -f $document_root$supercache_file ) {
				rewrite ^ supercache_file break;
			}
	
			# If no file or dir, send everything to index.php so WordPress can handle 404
			if ( !-e $request_filename ) {
				rewrite ^ /index.php last;
			}
		}
	
		location ~ \.php$ {
			# NOTE: You should have "cgi.fix_pathinfo = 0; in php.ini
			# If request goes to a php file, this tells to talk to PHP over fastcgi.
			# Includes params file (included in Nginx distribution, so no need to worry about it):
			include fastcgi_params;
			fastcgi_index index.php;
			fastcgi_intercept_errors on;
			# This `php` coresponds with above upstream setting:
			fastcgi_pass php;
		}
	
		location ~* \.(?:js|css|png|jpe?g|gif|ico|html|txt)$ {
			expires 7d;
			log_not_found off;
		}
	}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment