How to Configure Nextcloud on NixOS
Nextcloud provides a very polished experience when looking for a solution to self host your personal files, and replace tooling such as Google Drive or Dropbox. In this post I run through how I configured Nextcloud for use on NixOS.
Jacob Neplokh wrote an incredibly helpful blog post which forms the basis of this guide, I recommend having a read through for a more in depth explanation of everything. The NixOS Wiki also had some very helpful information.
There are several services that need to be configured to setup Nextcloud:
- Nextcloud
- Postgresql (optional but recommended)
- Redis (optional)
- Nginx
Nextcloud Setup
Nextcloud itself is relatively straightforward to setup, I found knowing all the additional services to be the tricky part. The module has a multitude of options to configure, for more information about each one take a look here.
Here is a look at my config - you'll note that secrets are managed with Agenix, which I've written about here:
# /etc/nixos/configuration.nix
{
services.nextcloud = {
enable = true;
# specify either a domain you own or localhost
hostName = "nextcloud.yourdomain.com";
autoUpdateApps.enable = true;
https = true;
# only specify caching if using redis or alternative service
caching.redis = true;
config = {
# only specify dbtype if using postgresql db
dbtype = "pgsql";
dbname = "nextcloud";
dbuser = "nextcloud";
# default directory for postgresql, ensures automatic setup of db
dbhost = "/run/postgresql";
adminuser = "admin";
# specified using agenix, provide path to file as alternative
adminpassFile = config.age.secrets.nextcloudPass.path;
# error thrown unless specified
defaultPhoneRegion = "AU";
};
# specify only if you want redis caching
extraOptions = {
redis = {
host = "127.0.0.1";
port = 31638;
dbindex = 0;
timeout = 1.5;
};
};
};
# only needed if using agenix for secret encryption
age.secrets = {
nextcloudPass = {
file = ../../secrets/nextcloudPass.age;
# allow default nextcloud user access to secret
owner = "nextcloud";
};
};
}
Postgresql Setup
It's highly recommended that you replace the default Sqlite database with Postgresql, here are the steps involved in making the change:
# /etc/nix/configuration.nix
{
services = {
postgresql = {
enable = true;
ensureDatabases = [ "nextcloud" ];
ensureUsers = [{
name = "nextcloud";
ensurePermissions."DATABASE nextcloud" = "ALL PRIVILEGES";
}];
};
# optional backup for postgresql db
postgresqlBackup = {
enable = true;
location = "/data/backup/nextclouddb";
databases = [ "nextcloud" ];
# time to start backup in systemd.time format
startAt = "*-*-* 23:15:00";
};
};
# ensure postgresql db is started with nextcloud
systemd = {
services."nextcloud-setup" = {
requires = [ "postgresql.service" ];
after = [ "postgresql.service" ];
};
};
}
As mentioned in the comments above, I've included an optional backup service, which will export the database to the specified location. Following this I backup the specified folder to using BorgBackup.
Redis Caching
This allows for caching of frequently used files in Nextcloud, which likely provides a more snappy user experience. Here's my configuration:
# etc/nixos/configuration.nix
{
services = {
redis.servers.nextcloud = {
enable = true;
port = 31638;
bind = "127.0.0.1";
};
};
}
Nginx Configuration
In order to login once Nextcloud is configured, HTTPS must be setup. My Nextcloud service is run behind a Tailscale VPN, so I had a couple of different options for configuring HTTPS:
- Having Tailscale do it with
tailscale cert
- Creating an A record to point an existing domain to my Tailscale IP, using my DNS provider, and configuring HTTPS via ACME
I opted for the second option, as such I also had to configure ACME to automatically generate my SSL certificate. NixOS has builtin tooling using a service called lego behind the scenes to create certificates. Here's my config:
# etc/nixos/configuration.nix
{
services.nginx = {
enable = true;
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedProxySettings = true;
recommendedTlsSettings = true;
# pulls in the hostname we set for nextcloud above (nextcloud.yourdomain.com)
virtualHosts.${config.services.nextcloud.hostName} = {
enableACME = true;
acmeRoot = null;
addSSL = true;
# directs traffic to the appropriate port for nextcloud
locations."/" = {
proxyPass = "http://localhost:8080";
proxyWebsockets = true;
};
};
};
security.acme = {
acceptTerms = true;
preliminarySelfsigned = false;
defaults = {
email = "acme@yourdomain.com";
dnsProvider = "cloudflare";
# API for authentication to DNA provider e.g.
# CF_API_KEY=<insert-global-key>
# CF_API_EMAIL=<insert-dns-account-email>
# specify file if not using agenix
credentialsFile = config.age.secrets.acmeCredentials.path;
};
};
# allow nginx to configure acme
users.users.nginx.extraGroups = [ "acme" ];
# if providing credentialsFile via agenix
age.secrets.acmeCredentials.file = ../../secrets/acmeCredentials.age;
}
I pieced together this setup thanks to the documentation in the NixOS Manual, I recommend giving it a read to understand what's going on here.
Conclusion
As you can see above, there are a few steps involved in properly configuring Nextcloud. Regarding Nextcloud apps, I found it easier to be able to install and manage these via Nextcloud itself.
I ended up putting all of the above config into its own module, for reference you can view it here.