Like most things in life, WordPress isn’t perfect. But for a publishing platform, it is quite up there with the best in the business. For writing, I haven’t had any complaints so far, but when it came to customization or workflows around maintaining a theme, I was a little lost.
To me it somehow felt very liberating and restricting at the same time. Liberating, because of the ecosystem; themes, plugins, hosting platforms, tons of helpful resources and support. Restricting, if and when you want to build a custom theme and don’t speak much PHP, general added complexity compared to a static site generator, having to deal with hosting providers, updates and added maintenance work.
But depending on the requirements, WordPress might actually make a lot of sense as a publishing platform (well, of course. It powers 40% of the web). My blog used to be hosted on Github Pages with Jekyll as the site generator until I made the switch to WordPress a couple of months ago. What I did struggle with was finding a setup that offered a smooth workflow around managing a custom theme with self hosted WordPress instance.
This article is an attempt at fixing that and aggregating some useful tips. I’ll try to cover the following:
- A self hosted WordPress website that’s affordable yet stable
- Continuous deployment pipeline for custom themes
- Backups that are reliable
- CDN and caching
- Securing the website
Let’s get started.
I decided to go with AWS Lightsail one click WordPress install. You’ll find more information on the Bitnami WordPress page about the stack. It is lightweight and runs perfectly fine on a 512MB RAM / 1vCPU instance. Once behind a CDN and page cache, the website can handle a fair number of visitors.
Continuous Deployment (CD) pipeline (optional: Continuous Integration)
This step assumes you have a custom WordPress theme or source code of a theme available on a GitHub repository. You only need to follow this step if you think you’ll be making frequent changes to your theme files and would like to have a pipeline for the automatic deploy of the theme (say, for example, when you commit a change to the master branch of your repository). Alternatively, you can always create a zip file of the theme and upload it manually via the WordPress admin panel if you prefer to keep things simple.
Assuming you have a theme hosted on GitHub, you’ll need to make use of Travis CI to build your code (if there’s any CSS or JS that needs to be transpiled), test it (if there are any checks) and then upload the files to the AWS LightSail instance using secure copy (scp). Following are some resources to help you get started.
- Underscore – Minimal WordPress starter template: https://underscores.me/
- Tutorial for deploying from Travis using SSH and SCP: https://oncletom.io/2016/travis-ssh-deploy/
- Elementary WordPress template Travis file, package.json and deploy script for reference.
For backups, I’m using a couple of strategies but I think either one should suffice for my usecase.
AWS Lightsail snapshots
I’d recommend enabling automatic daily snapshots of your instance in AWS Lightsail. So if things go very south, you will lose 1 day’s worth of data at most. Since my blog’s content is rarely updated, this means this works near perfectly.
WPVivid WordPress plugin
WPVivid is a nice plugin that offers more precise backups, meaning you can choose to backup just your database, or files, or both. It also has cron functionality and offer 12 hourly backups (more frequent if you’re a paying customer). WPVivid allows you to transfer the backups to Google Drive, AWS S3, Dropbox among many other third party providers.
Server health monitoring and alerts
I’m using New Relic to monitor the health of the WordPress instance. It isn’t necessary as AWS Lighsail already comes with basic dashboards for monitoring CPU performance and burst usage (giving a rough idea about whether the server is sweating under load), but if you’d like to go a bit fancy with the whole monitoring thing and set up alerts for throughput, error rate etc, New Relic is quite good.
New Relic really shines at showing you the external services your instance is talking to, database operations and the CPU usage share per plugin that you have installed on your WordPress website. That information can help you debug any services / plugins that are slowing down your website or doing something strange behind your back.
Both AWS Lightsail alerts and New Relic alerts support multiple channels, so feel free to use SMS, email, Slack or whatever your preferred way of getting alerted is.
CDN and Caching
My go-to CDN for any personal website is Cloudflare and that is what I’m using here. I didn’t have any problems with the admin interface behind the CDN and all seems to work very well. I have a page rule that overwrites cache control headers from WordPress and forces everything under /wp-content/* to be cached.
For page caching, I’m using a plugin called WP Total Cache. It was the most popular performance optimization plugin and was recommended to me. It has a “Page Cache” option which needs to be enabled and set to use disk as cache store.
To secure the Lightsail instance, I’m following some basic good practices and a plugin to help me set up some blocking rules.
- Lightsail instance is as close to stock as possible making sure there are no random packages installed from my side on the instance.
- Disable port 80, and if you’re using a reverse proxy CDN like Cloudflare, only allow Cloudflare IPs to your origin server.
- As with Lightsail, WordPress installation should be close to stock with minimal plugins.
- Wordfence WordPress plugin for
- 2FA authentication
- Banning incorrect login attempts, or login attempts using generic usernames like admin, administrator or root.
- reCAPTCHA on the login page (you’ll need API keys from Google)
- Disable xmlrpc if you’re not planning on using apps. Enable 2FA on it, or disable login via xmlrpc.
- Go through all the options that Wordfence has to offer and use whatever makes sense for your use case. I found them to be quite useful and intuitive.
- In general, keep stuff up to date.
That’s it for this article. If you have any questions or suggestions, please feel free to write to me. Thank you for reading.