Nix Flake development environment for WordPress
Following example provides a Nix Flake snippet which will spawn a virtual machine with WordPress running on NixOS locally. Custom plugin or theme sources can be mounted into the VM for development purpose.
Let’s start with the Flake-file itself. It can be created inside your theme or plugin directory which you want to work on.
{
description = "WordPress development shell";
inputs = {
nixpkgs.url = "nixpkgs/nixos-24.05";
nixos-shell.url = "github:Mic92/nixos-shell";
};
outputs = { self, nixpkgs, nixos-shell, ... }@inputs:
let
pkgs = nixpkgs.legacyPackages.x86_64-linux;
start =
pkgs.writeShellScriptBin "start" ''
set -e
export QEMU_NET_OPTS="hostfwd=tcp::8080-:80"
${pkgs.nixos-shell}/bin/nixos-shell --flake .
'';
in {
nixosConfigurations.vm = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
specialArgs.inputs = inputs;
modules = [
({ lib, config, pkgs, ... }: {
nixpkgs.overlays = [
(self: super: {
wordpress = super.wordpress.overrideAttrs (oldAttrs: rec {
postInstall = let
wpConfig = pkgs.writeTextFile {
name = "wp-config-localhost.php";
text = ''
<?php
$table_prefix = 'wp_';
require_once('/var/lib/wordpress/localhost/secret-keys.php');
define('DB_CHARSET', 'utf8');
define('DB_HOST', 'localhost:3306');
define('DB_NAME', 'wordpress');
define('DB_PASSWORD', "");
define('DB_USER', 'wordpress');
define('FS_METHOD', 'direct');
if ( !defined('ABSPATH') )
define('ABSPATH', dirname(__FILE__) . '/');
require_once(ABSPATH . 'wp-settings.php');
?>
'';
};
in ''
ln -s ${wpConfig} $out/share/wordpress/wp-config.php
rm -r $out/share/wordpress/wp-content
ln -s /var/lib/wordpress/localhost/wp-content $out/share/wordpress/wp-content
'';
});
})
];
services.wordpress = {
webserver = "nginx";
sites."localhost" = { };
};
services.nginx.virtualHosts."localhost".root = lib.mkForce "${pkgs.wordpress}/share/wordpress";
systemd.tmpfiles.rules = [
"d /var/lib/wordpress/localhost 0750 wordpress caddy - -"
"d /var/lib/wordpress/localhost/wp-content 0750 wordpress caddy - -"
"d /var/lib/wordpress/localhost/wp-content/plugins 0750 wordpress caddy - -"
"d /var/lib/wordpress/localhost/wp-content/themes 0750 wordpress caddy - -"
"d /var/lib/wordpress/localhost/wp-content/upgrade 0750 wordpress caddy - -"
"d /var/lib/wordpress/localhost/wp-content/uploads 0750 wordpress caddy - -"
];
nixos-shell.mounts.extraMounts = {
"/var/lib/wordpress/localhost/wp-content/themes/icynets-simplic" = {
target = /home/onny/projects/icynets-simplic;
cache = "none";
};
};
system.stateVersion = "24.05";
services.getty.autologinUser = "root";
documentation = {
info.enable = false;
man.enable = false;
nixos.enable = false;
};
nix = {
package = pkgs.nixFlakes;
registry.nixpkgs.flake = inputs.nixpkgs;
settings.experimental-features = [ "nix-command" "flakes" ];
};
})
nixos-shell.nixosModules.nixos-shell
];
};
packages = { inherit start; };
defaultPackage.x86_64-linux = start;
};
}
Add this flake.nix
file to your Git index and start tracking it.
Using a signle command to spawn a virtual machine and reach your local WordPress instance at http://localhost:8080
nix flake run
How does it work?
The Flake file consists of several parts which you might have to adapt depending on your setup
- Input-section: This part defines your Flake inputs. This is usefull in case you want to stick your development environment to a specific commit or version of the nixpkgs repository. Here we’re using latest stable version nixos-24.05.
- Start script: The following start script is a bash script which will get executed with
nix flake run
. In this script, nixos-shell is used to spawn a virtual machine. The lineQEMU_NET_OPTS="hostfwd=tcp::8080-:80"
tells Qemu to forward port 8080 on the host to the internal port 80. - nixpkgs overlay: Using a overlay, we’ll modify the default WordPress package used in NixOS. It’s a bit hacky, because normally plugins and themes for WordPress will get copied into the read-only Nix store. In the modification we move the
wp-content
directory to/var/lib/wordpress/HOSTNAME
so we can get write permissions. I haven’t figured out how to reuse the wp-config.php file of the native NixOS module, any help would be welcome :) - nixos-shell.mounts.extraMounts: This directive will mount my local project directory
/home/onny/projects/icynets-simplic
to thewp-content/themes
directory inside the VM.