Installing wordpress on nixos results in database error

Hello, I’m very new to NixOS and I’m in the process of learning it. Yesterday, I tried to install wordpress with the code in this wiki page: wordpress wiki page on wordpress
I imported it as a module to configuration.nix and managed to install it. But when I go to https://localhost/wordpress I encounter with this error:
" Error establishing a database connection"
I just included the code in the wiki. In other distros, I’d install wordpress through xampp, then create a database through phpmyadmin and then pass the database credentials to wordpress. I didn’t do anything like that, I’m not even sure whether apache or mysql are enabled or where the database is created. Thus, I’m totally clueless about the situation.

It’s worth looking up the actual options yourself, since the wiki is usually a bit void of explanations and not always current. See services.wordpress.

The wordpress options don’t seem to have terribly detailed docs sadly. In your case, the interesting option is services.wordpress.<name>.database.createLocally, which tells nix to “Create the database and database user locally.”.

This means two things:

  1. If you don’t set that to true, you can do database setup yourself - which you could in turn do with services.mysql.enable, or another packaged database.
  2. If you do set that to true, the wordpress module should take care of database creation for you. Since that’s clearly not working, we’ll need to check upstream what it’s doing. You can do that by clicking the source link in the option listing.
    In this case that link is only present on services.wordpress, and we need to manually search for createLocal to find this: https://github.com/NixOS/nixpkgs/blob/386234e2a61e1e8acf94dfa3a3d3ca19a6776efb/nixos/modules/services/web-apps/wordpress.nix#L312.

Reading actual nix source like that may be a bit advanced for you at this point, so to summarize, if createLocal is set, this will automagically set up a mysql service with users for each “site”, using this option: services.mysql.ensureUsers and the name you set for the “site” (in this case webservice5).

Reading the description there, two important things jump out at me:

This authenticates the Unix user with the same name only, and that without the need for a password

In other words, setting passwordFile and host makes no sense with createLocally, and may cause issues. The wiki page must be outdated.

This option will never delete existing users or remove permissions, especially not when the value of this option is changed.

This means that if you already have a wordpress user on a mysql database, things will probably break.

I would probably firstly try to remove passwordFile and host from my configuration, and use this instead:

# Note the .sites - the upstream module says this is the new syntax,
# the old is only supported because of a hack at the very top of the module
services.wordpress.sites."webservice5" = {
    database.createLocally = true;  # name is set to `wordpress` by default
    themes = [ responsiveTheme ];
    plugins = [ akismetPlugin ];
    virtualHost = {
      adminAddr = "js@lastlog.de";
      serverAliases = [ "webservice5" "www.webservice5" ];
    };
  };

That might already fix it, but if not, well, you should also know how to get your logs to see what’s actually going wrong. All services in modern Linux distros will (or at least should) log to systemd, and therefore we’ll get access to them via journalctl.

To see your mysql logs, you can run journalctl --unit mysql, for wordpress it’s journalctl --unit phpfpm-wordpress-webservice5.service. You can see a list of all running services using systemctl status, if you don’t know the specific name of a service (you can also figure out the name by reading their upstream modules, but yes, reading those modules can be tricky).

journalctl is a useful tool to learn more about, but some of my favorite useful flags are -e, which will scroll to the bottom for you, -x, which will show service stop/starts so you don’t muddle logs of different invocations, and -f, which will work as if you ran tail -f on a normal text file and show you updates as they happen.

I’m not sure this really clears up a lot, but if you take my suggestion, and that doesn’t work, feel free to come back with some logs and we can pick up some debugging from there :slight_smile: If it does work, don’t hesitate to update the wiki entry.

2 Likes

I just removed localHost and passwordFile and it worked like a charm! thank you a lot!
But now I’ve run into another problem, I’m currently working on a wordpress theme and I need to enter the theme’s data with an xml file, I managed to install wordpress importer but when I tried to import the xml file, almost everything failed. Is it because wordpress is installed in /nix/store/ and that is read-only so wordpress could not import data in normal way. What can I do about this?

Maybe this helps? Searching for “documentroot” in NixOS options search:

https://search.nixos.org/options?channel=21.11&show=services.httpd.virtualHosts.%3Cname%3E.documentRoot&from=0&size=50&sort=relevance&type=packages&query=documentroot

Then you can put the root of your site in an other, writable area

Maybe this one fits better with pre cooked WordPress

https://search.nixos.org/options?channel=21.11&show=services.wordpress.sites.%3Cname%3E.virtualHost.documentRoot&from=0&size=50&sort=relevance&type=packages&query=documentroot

I tried several things here, but it did not work out as I hoped… maybe better at your side!

Thank you because of reply, I tried the second option but nothing changed. The place where I determined as the documentRoot was intact and import failed as usual.

It seems that adding documentRoot to the wordpress.nix, after already done a setup once, without it, does not change much… maybe it should have been done at a fresh new installation?


Is there something in the logfiles that would help?

I see there are also old fashioned log files in

/var/log/httpd/

for example

-rw-r–r-- 1 wwwrun wwwrun 75307 13 jan 21:00 access-localhost.log
-rw-r–r-- 1 wwwrun wwwrun 7086 13 jan 19:15 error-localhost.log
-rw-r–r-- 1 wwwrun wwwrun 3716 13 jan 19:43 error.log

Maybe you could do a

tail -f /var/log/httpd/yourlogfile.log

On them?

And watch there what happens, when you import your files

---------- some time later -----------

Or maybe you can package your theme also in a zip file, and then import it in the configuration, like the responsive theme is done in the wordpress.nix example, only then with a local zip file…

---------- more time later ----------

I did it like this with a local downloaded theme, you can do the same I guess with your own theme:

{ config, pkgs, ... }:

let

ownTheme = pkgs.stdenv.mkDerivation {
  name = "hello-elementor";
  src = /home/user/Downloads/hello-elementor.2.4.2.zip;
  # We need unzip to build this package
  buildInputs = [ pkgs.unzip ];
  # Installing simply means copying all files to the output directory
  installPhase = "mkdir -p $out; cp -R * $out/";
};

in
{
  services.wordpress.sites."localhost" = {
    database = {
      #host = "127.0.0.1";
      name = "wordpress";
      #passwordFile = pkgs.writeText "wordpress-insecure-dbpass" "wordpress";
      createLocally = true;
    };
    themes = [ ownTheme ];
    virtualHost = {
      adminAddr = "wp@wp.nl";
      serverAliases = [ "localhost" ];
    };
  };
}

That works!

Screenshot_20220114_025934

1 Like

Yeah, I would suggest packaging the theme, and specifying it declaratively, rather than trying to use an imperative import. The latter has a lot of downsides, especially on NixOS.