About FreeBSD

Moving WordPress to nginx

This WordPress site has been migrated from Apache to Nginx. The front-end is an internet-facing reverse-proxy using Nginx, with the back-end using Nginx and php-fpm. Both ends run inside jails on FreeBSD servers.

Since 2022, this site has moved from WordPress to AsciiDoc. This article is about the old website.

This article focusses on the back-end configuration, the Nginx instance that serves static content from the WordPress installation at /usr/local/www/wordpress/ and forwards PHP requests to the php-fpm service listening on port 9000.

Installation

The packages are installed using:

# pkg install www/nginx
# pkg install www/wordpress

Add these lines to /etc/rc.conf:

nginx_enable="YES"
php_fpm_enable="YES"

nginx Configuration

In /usr/local/etc/nginx/nginx.conf:

events { }

http {
Ψinclude      mime.types;
Ψdefault_type application/octet-stream;
Ψroot         /var/empty;
Ψsendfile     on;
Ψtcp_nodelay  on;
Ψtcp_nopush   on;

Ψupstream php { server 127.0.0.1:9000; }

Ψmap $http_x_forwarded_proto $https_flag {
ΨΨdefault off;
ΨΨhttps   on;
Ψ}

Ψserver {
ΨΨlisten 80;
ΨΨset $controller /af/index.php;

ΨΨlocation /af
ΨΨΨalias /usr/local/www/wordpress;

ΨΨΨindex index.php;
ΨΨΨif (!-e $request_filename) { rewrite ^ $controller last; }

ΨΨΨlocation ~ /wp-content/uploads/ { expires 30d; }

ΨΨΨlocation ~ \.php$ {
ΨΨΨΨif (!-f $request_filename) { rewrite ^ $controller last; }

ΨΨΨΨinclude       fastcgi_params;
ΨΨΨΨfastcgi_param SCRIPT_FILENAME $request_filename;
ΨΨΨΨfastcgi_param HTTPS $https_flag;
ΨΨΨΨfastcgi_pass  php;
ΨΨΨ}

ΨΨΨlocation ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
ΨΨΨΨif (!-f $request_filename) { rewrite ^ $controller last; }
ΨΨΨΨexpires 30d;
ΨΨΨ}
ΨΨ}
Ψ}
}

We use pretty permalinks exclusively, so all non-static content is simply rewritten to /af/index.php.

The front-end terminates any client SSL connections, the presence of which is conveyed to WordPress using the $https_flag trick above.

Nginx and php-fpm run within the same jail, with both services listening on the jail’s assigned IP address. 127.0.0.1 is used above for illustrative purposes only, although valid for a non-jailed environment.

php-fpm Configuration

Copy /usr/local/etc/php-fpm.conf.default to /usr/local/etc/php-fpm.conf and change the listen directive to the IP address assigned to the jail (if applicable).

WordPress Configuration

The only change to WordPress is related to running it in a subdirectory. We define the site URL by adding these lines to /usr/local/www/wordpress/wp-config.php:

define( ’WP_SITEURL’, ’/af’ );
define( ’WP_HOME’, ’/af’ );
We leave out the scheme and the domain to make the reverse-proxy transparent. This works for us but may break some plugins.

References