Setting up a NixOS server on Linode to run Wordpress

After listening to:

… and needing to set up a new Wordpress server to replace my aging one, I thought this might be a good exercise to try Nix.

Linode has a nice writeup on how to install Nix. About half way through it, but this is proving to be a good exercise on how to use the low level aspects of the Linode platform (booting from ISO installer image, etc). The Linode platform seems very flexible. Here is a screen shot of the NixOS installer boot menu displayed in the Linode Glish terminal:

Stay tuned …

Finished install, and everything pretty much worked as advertised.

I really like being able to declaritively configure everything. Appears there are caddy packages, so working on that next …

Some notes on things learned today …

Wanted to symlink vi → nvim – turns out there is a config for that:

programs.neovim.enable = true;
programs.neovim.viAlias = true;

thanks @khem

I then explored installing the Caddy web server.

To date, I’ve been installing apps by adding to /etc/nixos/configuration.nix section as shown below:

  environment.systemPackages = with pkgs; [
    htop
    neovim
    inetutils
    mtr
    sysstat
    git
  ];

Then running nixos-rebuid switch. This puts binaries in locations like:

[root@nixos:/etc]# which nvim
/run/current-system/sw/bin/nvim

I’ve been reading you can also use nix-env to install stuff, so I tried:

[root@nixos:/etc]# nix-env --install caddy
Killed

It appears to be running the machine out of memory. According to this thread, this is common on low memory machines and you can do the following instead:

nix-env -iA nixos.caddy

That works, and now caddy is located in:

[root@nixos:/etc]# which caddy
/root/.nix-profile/bin/caddy

[root@nixos:/etc]# which nvim
/run/current-system/sw/bin/nvim

Contrasting the install location of caddy with nvim is interesting – it appears nix-env populates binaries for that user only.

So where did it store this configuration information about install caddy for the user? Perhaps /root/.nix-profile/manifest.nix?

I cloned the pkg repo so I could more easily search and then found a configuration for a caddy service:

[cbrake@ariel nixpkgs]$ find -name caddy*
./nixos/tests/caddy.nix
./nixos/modules/services/web-servers/caddy
./pkgs/servers/caddy

Its interesting this service is in the nixos/ directory, where the caddy service recipe is in the pkgs/ directory. This indicates you could install the caddy binary via nix on any OS, but to leverage the service configuration, you need to be running nixos – makes sense.

Now, to figure out how to use this …

with the following in my /etc/nixos/configuration.nix:

  services.caddy = {
    enable = true;
    config = ''
        localhost

        respond "Hello, world!"
    '';
  };

I can get a response on localhost:

However, getting errors when trying to fetch externally in browser.

After a few more fixes in the configuration, we’re up and running:

diff --git a/nixos/configuration.nix b/nixos/configuration.nix
index 8aa6bd8..10715c1 100644
--- a/nixos/configuration.nix
+++ b/nixos/configuration.nix
@@ -131,7 +131,7 @@
   # networking.firewall.allowedUDPPorts = [ ... ];
   # Or disable the firewall altogether.
   # networking.firewall.enable = false;
-  networking.firewall.allowedTCPPorts = [ 80 ];
+  networking.firewall.allowedTCPPorts = [ 80 443 ];
 
   # This value determines the NixOS release from which the default
   # settings for stateful data, like file locations and database versions
@@ -144,9 +144,9 @@
   services.caddy = {
     enable = true;
     config = ''
-       localhost
-
-       respond "Hello, world!"
+       web2.bec-systems.com {
+         respond "Hello, world!"
+       }
     '';
   };
 }

Looking at the journal, it appears Caddy got certs for web2.

> May 05 22:10:39 nixos caddy[1996124]: {"level":"info","ts":1651788639.4773624,"logger":"tls.obtain","msg":"certificate obtained successfully","identifier":"web2.bec-systems.com"}

Now, I can fetch a secure Hello, world remotely:

On to wordpress, mariadb, php, …

After a long delay, returning to this. Updated to Nixos 22.05 with the following commands:

nix-channel --add https://nixos.org/channels/nixos-18.09 nixos
nixos-rebuild --upgrade boot

Rebooted, and it came back up and Caddy still works!

Got wordpress working:

Here is the config:

  services.caddy = {
    enable = true;
    extraConfig = ''
        hello.bec-systems.com {
          respond "Hello, world!"
        }
    '';
  };

  services.wordpress = {
    webserver = "caddy";
  };

  services.wordpress.sites."web2.bec-systems.com" = {
    database.createLocally = true;  # name is set to `wordpress` by default

    virtualHost = {
      adminAddr = "cbrake@bec-systems.com";
      serverAliases = [ "web2.bec-systems.com" ];
    };
  };

  services.wordpress.sites."miles.bec-systems.com" = {
    database.createLocally = true;  # name is set to `wordpress` by default
    database.name = "wp_miles";

    virtualHost = {
      adminAddr = "miles@bec-systems.com";
      serverAliases = [ "miles.bec-systems.com" ];
    };
  };

Its pretty neat that with this bit of declarative config, we set up a database, PHP, wordpress, webserver, accounts, and who knows what else. Notice how easy it is to add a 2nd site …

Https is still not working yet as Nixos is generating the following Caddyfile:

[root@nixos:/home/cbrake]# more /nix/store/sa37k4v6qrrhhfz52pwkfyfx3l52rm7y-Caddyfile-formatted
{
        acme_ca https://acme-v02.api.letsencrypt.org/directory
        log {
                level ERROR
        }
}
hello.bec-systems.com {
        respond "Hello, world!"
}

http://miles.bec-systems.com {
        bind

        log {
                output file /var/log/caddy/access-http://miles.bec-systems.com.log
        }

        root * //nix/store/3z0hm7nxrrkjc0h2ff60bnh457cavvgr-wordpress-miles.bec-systems.com-5.9.3/share/wordpress
        file_server

        php_fastcgi unix//run/phpfpm/wordpress-miles.bec-systems.com.sock

        @uploads {
                path_regexp path /uploads\/(.*)\.php
        }
        rewrite @uploads /

        @wp-admin {
                path not ^\/wp-admin/*
        }
        rewrite @wp-admin {path}/index.php?{query}
}

http://web2.bec-systems.com {
        bind

        log {
                output file /var/log/caddy/access-http://web2.bec-systems.com.log
        }

        root * //nix/store/pzhi3vzh235c01rm7mkpb8iqidcsfrzp-wordpress-web2.bec-systems.com-5.9.3/share/wordpress
        file_server

        php_fastcgi unix//run/phpfpm/wordpress-web2.bec-systems.com.sock

        @uploads {
                path_regexp path /uploads\/(.*)\.php
        }
        rewrite @uploads /

        @wp-admin {
                path not ^\/wp-admin/*
        }
        rewrite @wp-admin {path}/index.php?{query}
}

Here is where the caddyfile is being generated:

Will need to figure out how to remove the http://

from the forum:

I’d say the main ethos to Nix/NixOS is “putting in effort now, in order to save putting in effort later”.

Credit vs debit cards :slight_smile: