Setting up a WordPress dev environment. AKA... Trying to run before I can walk

on your lamp.php include this:

environment.systemPackages = [ php' ];

as for permissions you should create a php script to crawl around the file system and see what is visible and what is not… maybe this will shed some light on the issue :thinking:

specifically what i mean by this is create a file called something like test.php at the root of one of your sites and in this file you should try to list out some paths on the file system and see if you can access them… then, when you access test.php from your web browser the script will be executed under the constrained systemd environment and you will see exactly what paths are available and what paths are not… try a bunch of paths like: /run, /run/media, /run/media/sergio, /run/media/sergio/vault, /run/media/sergio/vault/www, /run/media/sergio/vault/www/, and you can see where the phpfpm engine loses access… maybe this will give us some hints?

I think the server can read all the directories fine:

$dirs = [

foreach ( $dirs as $dir ) {
  if ( is_array( scandir($dir ) ) ){
    echo "<p> $dir is readable</p>";


Though I seem to have two mount points?

[sergio@samara:/run/media/sergio/vault/www/nerdpress]$ mount | grep vault
systemd-1 on /run/media/sergio/vault type autofs (rw,relatime,fd=294,pgrp=1,timeout=0,minproto=5,maxproto=5,direct,pipe_ino=13241) on /run/media/sergio/vault type nfs4 (rw,relatime,vers=4.2,rsize=1048576,wsize=1048576,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=,local_lock=none,addr=,x-systemd.automount,,x-systemd.mount-timeout=90)

interesting… let’s add the following configuration in addition to what you already have:

  services.phpfpm.pools."" = {
    settings = {
      "php_admin_value[error_log]" = "stderr";
      "php_admin_flag[log_errors]" = true;
      "catch_workers_output" = true;

now switch back to the directory structure giving you problems and watch the phpfpm log via sudo journalctl -f -u

hitting your sites should generate some error logs…

I’m not seeing anything show up on the command line, or was there a log created that I should be looking at?

[sergio@samara:~/.nixos]$ sudo journalctl -f -u
Jun 29 11:26:58 samara php-fpm[967]: [NOTICE] Terminating ...
Jun 29 11:26:58 samara systemd[1]: Stopping PHP FastCGI Process Manager service for pool
Jun 29 11:26:58 samara php-fpm[967]: [NOTICE] exiting, bye-bye!
Jun 29 11:26:58 samara systemd[1]: Deactivated successfully.
Jun 29 11:26:59 samara systemd[1]: Stopped PHP FastCGI Process Manager service for pool
Jun 29 11:27:01 samara systemd[1]: Starting PHP FastCGI Process Manager service for pool
Jun 29 11:27:01 samara php-fpm[32404]: [NOTICE] fpm is running, pid 32404
Jun 29 11:27:01 samara php-fpm[32404]: [NOTICE] ready to handle connections
Jun 29 11:27:01 samara php-fpm[32404]: [NOTICE] systemd monitor interval set to 10000ms
Jun 29 11:27:01 samara systemd[1]: Started PHP FastCGI Process Manager service for pool

This is my current lamp.nix:

{ config, pkgs, lib, ... }:
  # php 8.1 is the easiest option - if you need  php 7.x then we can discuss as an option
  php' = pkgs.php83.buildEnv {
    extensions = ({ enabled, all }: enabled ++ (with all; [
    # any customizations to your `php.ini` go here
    extraConfig = ''
      memory_limit = 1024M
      xdebug.mode = debug
      xdebug.start_with_request = yes
      xdebug.idekey = gdbp
  # webPath = "/var/www";
  webPath = "/run/media/sergio/vault/www";
  # php' = import ./php.nix;

  sites = [
  networking.hosts = {
    # convenient if you're going to work on multiple sites
    "" = [

  services.mysql.enable = true;
  services.mysql.package = pkgs.mariadb;
  services.mysql.ensureDatabases = [
    # list a database for every site you want and they will be automatically created
  services.mysql.ensureUsers = [
    # NOTE: it is important that `name` matches your `$USER` name, this allows us to avoid password authentication
    { name = "sergio";
      ensurePermissions = {
        "*.*" = "ALL PRIVILEGES";

  services.phpfpm.pools."" = {
    user = "sergio";
    group = "users";
    phpPackage = php';
    settings = {
      "listen.owner" =;
      "" =;
      "pm" = "dynamic";
      "pm.max_children" = 5;
      "pm.start_servers" = 2;
      "pm.min_spare_servers" = 1;
      "pm.max_spare_servers" = 5;
      "php_admin_value[error_log]" = "stderr";
      "php_admin_flag[log_errors]" = true;
      "catch_workers_output" = true;

  services.caddy.enable = true;

  services.caddy.virtualHosts."".extraConfig = ''
    root * ${webPath}/
    php_fastcgi unix/${"".socket}

  # automatically create a directory for each site you will work on with appropriate ownership+permissions
  systemd.tmpfiles.rules = [
    "d ${webPath}/ 0755 sergio users"
  ];"".serviceConfig = {
    PrivateDevices = lib.mkForce false;
    PrivateTmp = lib.mkForce false;
    ProtectSystem = lib.mkForce "off";
    ProtectHome = lib.mkForce false;

at this point in troubleshooting i would probably resort to systemd-run :man_shrugging:

at this point you have a systemd issue, though, not NixOS

maybe start a new thread and someone else has some ideas

Thanks for the time and energy! I’m currently wondering why the test.php file loaded fine, but not WordPress and MySQL… I’ll poke around at that a bit, since I do know those well. But will certainly move towards systemd-run if I don’t find anything.

I’ll report back either way. :smile:

:crossed_fingers: Hopefully something comes out of this one…

If not, I also may be looking at this setup the wrong way.

Do I really need the dev env files to be on an NFS share?

oh caddy is hardened too… add this and see if it does anything: = {
  PrivateDevices = lib.mkForce false;
  ProtectHome = lib.mkForce false;

It does seem like it is Caddy… Looks like there is some kind of permission problem?

If you’re running Caddy as a systemd service, reading files from /home will not work, because the caddy user does not have “executable” permission on the /home directory (necessary for traversal). It’s recommended that you place your files in /srv or /var/www/html instead.

How would I give the caddy user permission on the /mnt/vault/www directory? Though both /var/www and /mnt/vault/www have sergio:users permissions… I did just test and set permissions to 777 and nothing seemed to change.

Some progress(?) I mounted the NFS share in /var/www and set it to anongid=239 which is caddy’s user id. Then changed the group permissions to the caddy user on the files in the directory and now getting a 500 error instead…

Jul 03 14:06:20 samara caddy[198357]: {"level":"error","ts":1720040780.7734408,"logger":"http.log.error.log0","msg":
"stat /var/www/nerdpress: stale NFS file handle","request":{"remote_ip":"","remote_port":"47282","client_ip
Dnt":["1"],"User-Agent":["Mozilla/5.0 (X11; Linux x86_64; rv:127.0) Gecko/20100101 Firefox/127.0"],"Accept-Encoding"
:["gzip, deflate, br, zstd"],"Sec-Fetch-Dest":["document"],"Sec-Fetch-Mode":["navigate"],"Te":["trailers"],"Cookie":
race":"fileserver.(*FileServer).ServeHTTP (staticfiles.go:284)"}

did you cross post on caddy forums? they are super helpful over there… they’ve worked with some members of our community before and i believe everyone was pretty happy with the results

Some, weird, progress…

Looks like I can access WordPress, somewhat. But some files give me 500 errors and others don’t. Seems kinda random at this point. I got things to load by using .php URLs. Maybe something to do with redirects or the lack of .htaccess rules.

Looks like PHP files are loaded fine but not JS or CSS. This renders the site, “broken”, but gives me hope.


I’m using caddy for my local php dev environment.
I posted a working config here Local dev stack for php

this implies the phpfpm service has access to your files but the caddy service does not

what are the permissions on your mount?

Thanks! I’ll have a look later today. Not sure this will change my problem, since I can run what I have just fine if the files are local to the computer. It only has issues when loading them from an NFS mount.

-rw-rw-r-- 1 sergio caddy 3573 Jul 5 15:43 wp-config.php
drwxr-xr-x 1 sergio caddy 286 Jul 5 15:54 wp-content

Here is the mount:

  fileSystems."/mnt/www" = {
    device = "";
    fsType = "nfs";
    options = [ "nfsvers=4.2" "x-systemd.automount" "noauto" "nofail" "" "x-systemd.mount-timeout=90" ];
    label = "www-nfs";

NFS exportfs -v output from server:

/mnt/btr-vault/vault/www (sync,wdelay,hide,no_subtree_check,anonuid=1000,anongid=239,sec=sys,rw,secure,root_squash,all_squash)

mount output: on /var/www type nfs4 (rw,relatime,vers=4.2,rsize=1048576,wsize=1048576,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=,local_lock=none,addr=,x-systemd.automount,,x-systemd.mount-timeout=90)

I’ve been looking into that exact thing… How does caddy vs phpfpm access the files and how are their permissions/users set.

at this point i think you should try:

services.caddy.user = "sergio"; = "users";

also if that doesn’t work maybe you can PM me and we can setup a call to resolve this and introduce you to devenv