Introduction🔗

I love Nextcloud. Not only does can it be a self-hosted "cloud" storage system, but also has a ton of useful apps to further enhance the experience, and makes it an actual alternative to the Google Suite of apps. Recently I have also been playing with NixOS. As I start to further learn Nix and NixOS, I am pretty confident I will write about its glory. In that future post, and here, one large negative will be mentioned: the lack of documentation/tutorials, especially compared to other distributions. There is the manual and unofficial wiki but much of it is surface-level and/or basic configuration. The manual has a Nextcloud sample configuration, but it even admits it is "very basic." There is more you must configure to get it to work. I owe a great thanks to the #nixos irc (on Freenode)/Matrix chat for helping me. Without further ado, time to install Nextcloud on NixOS!

Disclaimer🔗

This guide is how to install Nextcloud on NixOS. Nothing more and nothing less. It is up to you to take basic and general security measures on your server. Furthermore, while this process worked for me when I wrote it, I cannot guarantee it is the best or most up-to-date version. I am not liable for any damage, security vulnerabilities, or anything else that occurs. Anything I say here is provided as-is with no warranty whatsoever. Please, do not blindly trust what I, or any blog post, has to say. If you do notice something wrong or not a best practice, do let me know :) Not just for my sake, but anyone else who stumbles upon this.

Prerequisites🔗

DNS Record🔗

I'll use the domain name nextcloud.example.com. Point an A record to your server IP address for your subdomain.

Firewall🔗

Ports 80 and 443 need to be open in the NixOS firewall. Open them by putting this in your /etc/nixos/configuration.nix:

networking.firewall.allowedTCPPorts = [ 80 443 ];

Let's Encrypt🔗

We need to agree to Let's Encrypt's terms in order to generate a certificate. Add this to your /etc/nixos/configuration.nix:

security.acme = {
    acceptTerms = true;
    # Replace the email here!
    email = "email@example.com";
};

As the comment states, replace the email there!

Modularity🔗

If you want, you can put everything in the /etc/nixos/configuration.nix file, but NixOS supports modularity, so we should take advantage of it. Plus, it will make everything easier to manage. Therefore, let's make a nextcloud.nix file in the same directory. You can do this by running:

`sudo -i nano /etc/nixos/nextcloud.nix`

Then, in there

{config, pkgs, ...}:
{

}

Then, click Control+X, Control+Y, then Enter. Now that is setup, so we need to actually put stuff in the /etc/nixos/nextcloud.nix We'll actually add more in the next part :)

Configuration🔗

I have published a GitHub Gist with the configuration with the full configuration besides the prerequisites mentioned above. I have commented the code, so you can get a "TL;DR" through that. Do note, there are steps/commands to preform afterwards, so go to Post-Setup if you go this route.

If you want to see a more step-by-step configuration, keep reading :)

Note🔗

Everything here will go in between those two curly brackets we put in the "Modularity" section.

Nginx🔗

The first thing to setup is Nginx to make a reverse-proxy with HTTPS, so we can actually access our installation:

services.nginx = {
   enable = true;

 # Use recommended settings
    recommendedGzipSettings = true;
    recommendedOptimisation = true;
    recommendedProxySettings = true;
    recommendedTlsSettings = true;

 # Only allow PFS-enabled ciphers with AES256
    sslCiphers = "AES256+EECDH:AES256+EDH:!aNULL";

# Setup Nextcloud virtual host to listen on ports
 virtualHosts = {

     "nextcloud.example.com" = {
       ## Force HTTP redirect to HTTPS
       forceSSL = true;
       ## LetsEncrypt
       enableACME = true;
    };
  };
};

You may have noticed that there is no configuration besides the HTTPS/Let's Encrypt, not even an HTTP header, how will anything work!? Rest assured, Nextcloud specifically has an option (services.nextcloud.nginx.enable) to do the pretty complicated config for us. Speaking of, time to setup Nextcloud itself.

Nextcloud🔗

The NixOS Manual provides a "very basic" Nextcloud configuration, but it is just that: basic. Here is my recommended config:

services.nextcloud = {
    enable = true;
    hostName = "nextcloud.example.com";
    # Enable built-in virtual host management
    # Takes care of somewhat complicated setup
    # See here: https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/web-apps/nextcloud.nix#L529
    nginx.enable = true;

    # Use HTTPS for links
    https = true;
    
    # Auto-update Nextcloud Apps
    autoUpdateApps.enable = true;
    # Set what time makes sense for you
    autoUpdateApps.startAt = "05:00:00";

    config = {
      # Further forces Nextcloud to use HTTPS
      overwriteProtocol = "https";

      # Nextcloud PostegreSQL database configuration, recommended over using SQLite
      dbtype = "pgsql";
      dbuser = "nextcloud";
      dbhost = "/run/postgresql"; # nextcloud will add /.s.PGSQL.5432 by itself
      dbname = "nextcloud";
      dbpassFile = "/var/nextcloud-db-pass";

      adminpassFile = "/var/nextcloud-admin-pass";
      adminuser = "admin";
 };
};

The changes I made are furthering HTTPS support and usage, auto-updating apps, and password file locations. The latter, password files, is extremely important. To properly set them up, we need to enable Nextcloud, but some further configuration is needed: setting up PostgreSQL.

PostgreSQL🔗

Nextcloud can use SQLite, but that is highly unrecommended. As you can see in the Nextcloud config, we'll use PostgreSQL instead. We create the database and user in the Nextcloud config, but we still need to enable PostgreSQL and ensue the database, user, and permissions always exist. Manual removal will be required to change it, preventing accidental loss. Here is the config:

services.postgresql = {
    enable = true;

    # Ensure the database, user, and permissions always exist
    ensureDatabases = [ "nextcloud" ];
    ensureUsers = [
     { name = "nextcloud";
       ensurePermissions."DATABASE nextcloud" = "ALL PRIVILEGES";
     }
    ];
};

Now, we have to make sure PostgreSQL is running before the Nextcloud setup. This is accomplished by this config:

systemd.services."nextcloud-setup" = {
    requires = ["postgresql.service"];
    after = ["postgresql.service"];
};

After adding that, we can finally run the setup with this command:

sudo nixos-rebuild switch

There should not be any errors and eventually the command will complete! Congrats! Wait, there is still some required configuration left.

Post-Setup🔗

Password Files🔗

In NixOS, configuration files are symlinked the read-only, but world-readable, /nix/store/. Therefore, we do not want to put the database or admin password in the /etc/nixos/nextcloud.nix file. Instead we will create the files under /var/ and change the permissions. First, let's change the permissions so only the owner can read/write by running:

umask 077

Next, let's create the file by running:

sudo -i nano /var/nextcloud-db-pass

And insert a randomly generated password (use your password manager!) and save the file. Finally, let's change ownership to the nextcloud user so it has access by running:

sudo -i chown nextcloud /var/nextcloud-db-pass

Now the same, but for the admin password file. Important: This will be the password you use to login! Same commands as before, but replace db with admin like so:

umask 077
sudo -i nano /var/nextcloud-admin-pass
sudo -i chown nextcloud /var/nextcloud-admin-pass

To apply the changes, let's rebuild again!:

sudo nixos-rebuild switch

Nextcloud Maintenance🔗

You should now be able to login to your Nextcloud. If you go to https://nextcloud.example.com/settings/admin/overview, you will most likely see some setup warnings regarding your database. The first is probably be about missing indices. Fix it by running this command

sudo -i nextcloud-occ db:add-missing-indices

The other issue regards some columns missing a conversion to big int. To fix this, we need to take the instance offline by putting it into maintenance mode:

sudo -i nextcloud-occ maintenance:mode --on

Now we can run:

sudo -i nextcloud-occ db:convert-filecache-bigint

And type "y" to confirm. Now take Nextcloud out of maintenance mode:

sudo -i nextcloud-occ maintenance:mode --off

and refresh the page. It should now say "All checks passed" with a green checkmark. Nextcloud is now up and running on NixOS!

Conclusion🔗

NixOS and Nextcloud are both excellent pieces of software. When trying to combine the two, I ran into many issues, that took some time, trial and error, and asking for help to fix. Hopefully the next person who wants to set it up will come across this post, and will be saved a lot of hassle. Should you notice anything wrong, incorrect, or does not work, contact me to let me know, and I'll update the post!