Building Your First Drupal Instance
Simple configuration
The easiest way to create a Drupal instance on NixOS is by enabling the Drupal service.
In a fresh NixOS installation, you may go to /etc/nixos/configuration.nix, and add the following nix code anywhere in the file.
The above code is functionally identical to writing the following.
Once you have saved your configuration, then you must run the following command to rebuild your system, enabling Drupal in the process.
This will make the following changes to your system:
- Install and configure
mariadbat port3306 - Create a database called
drupalwith the usernamedrupaland passworddrupal - Install and configure
php-fpm - Install and configure
nginx - Install and configure the latest stable Drupal core in nixpkgs (check the nixpkgs search tool to figure out which version will come with your system)
- Create a new NixOS generation you can roll back to later
- Create a state directory at
/var/lib/drupal/localhost, which holds a number of mutable files symlinked into the Drupal installation - Makes the Drupal installation available at
localhost
For more information about how nixos-rebuild functions, please read the official wiki.
Learn more about nixos-rebuild
Post-build operations
Drupal installation
If you connect to your server's localhost, you may then install Drupal core via the graphical user interface. Drupal core only comes with three pre-configured installation profiles, "Minimal", "Standard", and "Demo".
Selecting any will allow you to install Drupal in the filesystem and populate the preconfigured database.
Warning
The default database password and user are both set to drupal. If you are using the sample configuration above, you must enter this information at installation time.
This is fine for testing, however, it is strongly advised that you configure an alternate database password and user. Please see Recommended configuration > Configuring the databse for more information.
Using the state directory
When you build your Drupal website with NixOS, the majority of the files that are used to run Drupal get stored in an immutable file system called /nix/store. However, Drupal expects that some parts of itself should be editable at instillation time.
Therefore, all of your site's dynamic files get put into a directory called the state directory. Every website instances gets its own state directory. By default, all state directories are located at /var/lib/drupal/<hostname> where <hostname> is the name of your website specified in your configuration.
The default configuration serves your website from localhost, and creates a state directory at /var/lib/drupal/localhost.
If you elect to change your hostname, the state directory for that website will be located at a different location. Please refer to Post-build operations > Using alternate hostnames for more information.
A much deeper exploration of the state directory, its structure, and its functions can be found on the next page of this tutorial.
Learn more about the state directory
Recommended configuration
There are a few additional pieces of configuration that are generally recommended for most installations. Please review the following situations and decide for yourself which may be best suited for your use case.
Using alternate hostnames
The minimal default configuration places your website at the localhost hostname. However, you can create a Drupal website with a custom hostname by doing the following.
# Create a drupal website with a custom hostname
services.drupal = {
enable = true;
sites = {
"my-custom-hostname.com" = {
enable = true;
};
};
};
# Update /etc/hosts
networking.hosts = {
"127.0.0.1" = ["localhost" "my-custom-hostname.com"];
};
Note
This will also change the location of your state directory. Your new state directory will be located at /var/lib/drupal/my-custom-hostname.com/.
Configuring the database
The default database configuration interface uses the following default values
# Default database configuration. It is strongly recommended you change this configuration.
services.drupal.sites.<hostname>.database = {
name = "drupal";
user = "drupal";
password = "drupal";
tablePrefix = "dp_";
passwordFile = null;
};
It is strongly recommended that you alter some or all of these values before you build your first Drupal instance.
For security, you may also consider altering the following attributes.
# Default database prefix. Consider changing this to 4-5 random characters followed by a "_"
services.drupal.sites.<hostname>.database.tablePrefix = "dp_";
# Set a password file for unlocking the database
services.drupal.sites.<hostname>.database.passwordFile = /run/keys/database-password;
If you choose to create a password file for authenticating with the database, please refer to the following recommended method of creating that file using openssl.
sudo mkdir -p /run/keys
sudo touch /run/keys/database-password
sudo nix-shell -p openssl --run "openssl rand -base64 32 > /run/keys/database-password"
You must then provide the path of the password file at Drupal installation time.
Changing the webserver
By default, the Drupal service utilizes the nginx webserver. However, you can elect to use caddy instead using the following configuration.
This will change the webserver for all existing Drupal installations.
If you elect to use caddy, and want to have a regular user be able to access the state directory, change that user's permissions so "caddy" is included in the extraGroups attribute, like so.
# Enable a regular user called "stmgr" to access and manage the state directory.
user.user.stmgr.extraGroups = [ "caddy" ];
See Recommended configuration > Allow a regular user to access the state directory for more information.
Allow a regular user to access the state directory
By default, regular NixOS users are not allowed into the state directory. However, if you want to change this to make it easier to do manual management of your files, you may use the following configuration.
# Creates a user call stmgr with permissions to access and manage any directory under /var/lib/drupal
users.users.stmgr = {
isNormalUser = true;
description = "Drupal state manager";
# Choose only one of these depending on your configured webserver. "nginx" is the default webserver
extraGroups = [
"nginx"
"caddy"
# "wheel" # you may also consider giving this user sudo permissions
];
};
You will then need to reboot the system in order for the new user permissions to take effect.
Alternatively, you can simply add the "nginx" or "caddy" groups to the extraGroups attribute of any existing user to achieve the same effect.
Point to a custom webRoot directory
If your Drupal project has a webRoot, you may consider using the following attribute to tell NixOS where to find it.
This tells NixOS where to discover you public webroot files. By default, it is set to the empty string. Values for this attribute must start with a leading slash. This is primarily used to fix filepath calculations that would otherwise be broken on codebases that use a webroot.
Connect to the /config/sync directory
If you plan on using the Drupal configuration system to manage your system configuration, you may consider configuring the following attributes.
services.drupal.sites.<hostname>.configSyncDir = "/var/lib/drupal/<hostname/config/sync";
services.drupal.sites.<hostname>.configRoot = "/config";
configSyncDir is used to tell NixOS where you would like to store your Drupal configuration files. This filepath will be created for you at rebuild time, and it will also be added to the site's settings.php to tell Drupal where to find it. When you export your Drupal configuration files, they will be added to this directory.
configRoot is used to tell NixOS where to find the config directory in your project source code. It is set to the empty string by default. Values for this attribute must start with a leading slash. When NixOS fetches your source code, it can optionally use the value of this attribute to figure out where to find your site configuration files. These files will be cloned down into the location of the configSyncDir attribute at rebuild time. You could then direct Drupal to import any configuration changes via the UI or via Drush.
Sample recommended configuration
The following is a sample configuration with all of the recommended values pre-populated. This configuration will install Drupal core, and make it accessible at my-drupal-website.com. Likewise, it will create a user called drupal-mgr that can be used to manage the state directory.
services.drupal = {
enable = true;
sites = {
"my-drupal-website.com" = {
enable = true;
database = {
name = "my-drupal-website";
user = "7i&ybgA"; # Choose a random database username
tablePrefix = "g8s4j_"; # Choose a random table prefix
passwordFile = /run/keys/database-password; # Configure a password file location. Populate the contents of this file using openssl.
};
};
};
};
# Update /etc/hosts
networking.hosts = {
"127.0.0.1" = ["localhost" "my-drupal-website.com"];
};
# Create a user for managing the state directory
users.users.drupal-mgr = {
isNormalUser = true;
description = "Drupal state manager";
# Set and create an initial password using the mkpasswd command and paste the output here.
# See: https://wiki.nixos.org/wiki/User_management
# Plan on changing the user password after the first login.
initialHashedPassword = "";
extraGroups = [
"nginx"
# "wheel" # you may also consider giving this user sudo permissions, if required
];
};