Nix Setup for Wordpress CMS
This repository contains everything necessary to test and deploy fully operational web servers for Wordpress CMS sites.
This setup uses the powerful Nix package management system and its accompanying toolset:
Note: Nix does not support Windows. If you're on Windows, you'll need to run this from within a Virtual Machine (VM).
With this setup, you can easily deploy your site to one or more servers with minimal effort. You can (and should) also deploy to local VirtualBox virtual machines. And, you can even use the Nix packages to install the site directly on your local host.
- Automatically builds a working server with Nginx, PHP-FPM, MySQL, and WordPress.
- Automatically configures TLS/SSL using Let's Encrypt.
- Configures PHP OpCache and a WordPress plugin to manage it.
- Configures Nginx Fastcgi-cache with a cache-purging module and a WordPress plugin to manage it.
- Installs and configures Google's PageSpeed Nginx module.
- Allows WordPress configuration (settings, versions, plugins, themes, etc.) to be managed entirely by Nix. This means:
- Upgrades and changes can be tracked in version control.
- Deployments are reproducible for testing (e.g. in VirtualBox or on a staging server).
- Security is enhanced by having most PHP files read-only.
- Highly configurable: most of these settings can be tweaked easily.
- First install Nix. It is not invasive and can be removed easily if you change your mind (using
rm -r /nix
). - Deployments are done with NixOps. You can install
nixops
withnix
by runningnix-env -i nixops
. However, you don't need to because this repository has adeploy/manage
script that you'll use which will runnixops
tasks for you. - Install VirtualBox in order to test your server deployments.
- If you plan to deploy to a real server, you will likely need to keep secrets in this repository. That will require installing git-crypt and setting it up. See
SETUP-SECRETS.md
for information on that.
This project requires that you build Linux binaries which can be deployed to a server (VirtualBox or otherwise). Since macOS cannot natively build Linux binaries, you will need a NixOS build slave running.
- Install Docker and then use this script to set up a NixOS build slave. For example:
*
source <(curl -fsSL https://raw.githubusercontent.com/LnL7/nix-docker/master/start-docker-nix-build-slave)
*deploy/manage vbox deploy
(or some other deployment command) - If you can't/don't want to install Docker, you can use NixOps to create a NixOS build slave via VirtualBox using this. Note that using Docker is almost certainly going to be easier so I recommend that way instead.
- Create unique WordPress keys for your site (must be in the same directory as
default-app-config.nix
):curl https://api.wordpress.org/secret-key/1.1/salt/ > wordpress-keys.php.secret
.
- Configure your site by editing
default-app-config.nix
.- For automatic install using WP-CLI:
- Configure the
autoInstall
section to useenable = true;
. - Copy
./wordpress-admin.keys.nix.sample
to./wordpress-admin.keys.nix
and replace...
with your credentials.
- Configure the
- For a traditional install where WordPress is entirely managed by the admin panel, use
freezeWordPress = false;
. - To have Nix manage themes but not plugins, you can use
freezeWordPress = true; freezeThemes = true; freezePlugins = false;
. - When WordPress is frozen (i.e. managed by Nix), use
wordpress.nix
to govern the installed version. - When plugins are frozen (i.e. managed by Nix), use
plugins.nix
to govern which plugins are installed. - When themes are frozen (i.e. managed by Nix), use
themes.nix
to govern which themes are installed.
- For automatic install using WP-CLI:
- More complex settings can be managed in
server/
.- For example, change PHP-FPM configuration in
server/php-fpm-config.nix
.
- For example, change PHP-FPM configuration in
Create a VirtualBox deployment:
deploy/manage vbox create '<server/logical.vbox.nix>' '<server/physical.vbox.nix>'
deploy/manage vbox deploy
Notes:
nixops
deployments can sometimes be finicky. If something hangs or fails, try running it again. It is a very deterministic system so this should not be a problem.- Run
deploy/manage --help
to see all options (this is justnixops
underneath).
You should then be able to open the IP of the VM in your browser and test it. If you don't know the IP, run deploy/manage vbox info
.
- If you're on macOS (Darwin), be sure you have a NixOS build slave set up as described above.
- If the state of your VirtualBox VM changes in a way that
nixops
didn't notice, your deployments may fail. Try runningdeploy/manage deploy -d vbox --check
(using the--check
flag) to tellnixops
to reassess the state of the machine. - Sometimes VirtualBox will give your machine a new IP. If this happens,
nixops
(i.e. themanage
script) may fail to connect to your machine via SSH. If this happens, remove the line with the old IP from your~/.ssh/known_hosts
file and try again with the--check
flag. - Sometimes
nixops
will fail to deploy because a VirtualBox disk from a previous deploy is still registered. To fix this, take the given disk UUID and runVBoxManage closemedium disk <disk UUID> --delete
.
With this setup you can deploy to any PaaS/IaaS service supported by nixops
. Right now this repository contains prewritten configurations for
- Google Cloud Compute's Google Compute Engine (GCE) - see
DEPLOY-GCE.md
. - DigitalOcean - see
DEPLOY-DIGITAL-OCEAN.md
.
We plan to add more (such as AWS) in the future. If you want to do it yourself and understand Nix, the work to add this configuration is minimal. Pull requests welcome!
NOTE: When SSL/TLS is enabled for production servers, the first deployment may take a long time (i.e. more than 20 minutes) to finish. A large chunk of first-deployment time will be spent generating new DH parameters for Nginx. This is normal!
This repository setup assumes you want to keep some things a secret. See SETUP-SECRETS.md
for a rundown of how that works.
All dependencies are fixed to a specific version of Nixpkgs which is configured in deploy/nixpkgs-version.nix
which contains instructions for upgrading. The nixpkgs version also governs the version of NixOps to use during deployments. This can be overridden in nixpkgs-version.sh
.
- The server setup is highly influenced by
- Special thanks to @khalwat