2016-04-16

Pretty WordPress permalinks under OpenBSD's httpd(8)

I run a bunch of websites on OpenBSD. One of them is running WordPress for a local group. When I upgraded the server from OpenBSD 5.7 to 5.8 last year, I finally switched from the version of Apache 1.3 that used to come in the base install, to the new relayd-based httpd that had been in the works. Without mod_rewrite, I disabled the so-called "pretty" permalinks with useful titles, going back to the old numbered-posts setup.

This had been bothering me last weekend, and earlier this week, I saw someone else with the same problem. I had written a totally custom CMS for one of my other websites, and it also uses an awkward set of front-controllers written in PHP in order to make friendly-looking URLs. I decided to explore my method of setting that site up, applied to WordPress.

You have the option of using so-called "PATHINFO" Permalink URLs in WordPress. Those might look like:
     http://blog.bar.com/index.php/2016/hello-world/

That's getting there. I opted to make my site more like:
     http://blog.foo.com/posts/2016/04/hello-world/

I started by creating a symbolic link called "posts" pointed to index.php.

ln -s index.php posts

Since I'm using PHP-FPM, I had to also make sure that FPM would acknowledge this new file since it lacks the .php extension.  Beware the rule of unintended consequences here. You'll want an airtight httpd.conf when it comes to what things it decided to toss over to the PHP-FPM socket. Blank out the security.limit_extensions variable in /etc/php-fpm.conf

security.limit_extensions =

Next, adjust your httpd.conf to send stuff destined to the /posts URI (note the * at the end, it's important!) to PHP-FPM. All of my sites are under /var/www/sites/ (including the one I'm setting up WordPress on). My httpd.conf clause for this site looks kind of like this:

server "blog.foo.com" {
    listen on $ext_if port 80
    alias "fooblog.com"


    log access fooblog-access.log
    log error fooblog-error.log
    directory {index "index.php" }
    location "/*.php*" {
        root { "/sites/fooblog" }
        fastcgi socket "/run/php-fpm.sock"
    }
    location "/posts*" {
        root { "/sites/fooblog" }
        fastcgi socket "/run/php-fpm.sock"
    }
    location "/*" {
        root { "/sites/fooblog" }
    }
}



You'll need to restart php_fpm and httpd for this to take effect.

doas rcctl restart httpd
doas rcctl restart php_fpm

After that, log in to your site's admin panel and change the permalink structure to include "/posts/" at the beginning. You should be all set.