f8fdf2f704
This PR irons out the last issues with the backup contract and the Restic implementation. I could check it works backing up files to a local folder and to Backblaze on my server.
444 lines
16 KiB
Markdown
444 lines
16 KiB
Markdown
# Nextcloud Server Service {#services-nextcloud-server}
|
|
|
|
Defined in [`/modules/services/nextcloud-server.nix`](@REPO@/modules/services/nextcloud-server.nix).
|
|
|
|
This NixOS module is a service that sets up a [Nextcloud Server](https://nextcloud.com/).
|
|
|
|
## Features {#services-nextcloud-server-features}
|
|
|
|
- Declarative [Apps](#services-nextcloud-server-options-shb.nextcloud.apps) Configuration - no need
|
|
to configure those with the UI.
|
|
- [LDAP](#services-nextcloud-server-usage-ldap) app: enables app and sets up integration with an existing LDAP server.
|
|
- [OIDC](#services-nextcloud-server-usage-oidc) app: enables app and sets up integration with an existing OIDC server.
|
|
- [Preview Generator](#services-nextcloud-server-usage-previewgenerator) app: enables app and sets
|
|
up required cron job.
|
|
- [External Storage](#services-nextcloud-server-usage-externalstorage) app: enables app and
|
|
optionally configures one local mount.
|
|
- [Only Office](#services-nextcloud-server-usage-onlyoffice) app: enables app and sets up Only
|
|
Office service.
|
|
- Any other app through the
|
|
[shb.nextcloud.extraApps](#services-nextcloud-server-options-shb.nextcloud.extraApps) option.
|
|
- [Demo](./demo-nextcloud-server.html)
|
|
- Demo deploying a Nextcloud server with [Colmena](https://colmena.cli.rs/) and with proper
|
|
secrets management with [sops-nix](https://github.com/Mic92/sops-nix).
|
|
- Access through subdomain using reverse proxy.
|
|
- Access through HTTPS using reverse proxy.
|
|
- Automatic setup of PostgreSQL database.
|
|
- Automatic setup of Redis database for caching.
|
|
- Backup of the [`shb.nextcloud.dataDir`][1] through the [backup block](./blocks-backup.html).
|
|
- Monitoring of reverse proxy, PHP-FPM, and database backups through the [monitoring
|
|
block](./blocks-monitoring.html).
|
|
- [Integration Tests](@REPO@/test/services/nextcloud.nix)
|
|
- Tests system cron job is setup correctly.
|
|
- Tests initial admin user and password are setup correctly.
|
|
- Tests admin user can create and retrieve a file through WebDAV.
|
|
- Access to advanced options not exposed here thanks to how NixOS modules work.
|
|
|
|
[1]: ./services-nextcloud.html#services-nextcloud-server-options-shb.nextcloud.dataDir
|
|
|
|
## Usage {#services-nextcloud-server-usage}
|
|
|
|
### Secrets {#services-nextcloud-server-secrets}
|
|
|
|
All the secrets should be readable by the nextcloud user.
|
|
|
|
Secrets should not be stored in the nix store. If you're using
|
|
[sops-nix](https://github.com/Mic92/sops-nix) and assuming your secrets file is located at
|
|
`./secrets.yaml`, you can define a secret with:
|
|
|
|
```nix
|
|
sops.secrets."nextcloud/adminpass" = {
|
|
sopsFile = ./secrets.yaml;
|
|
mode = "0400";
|
|
owner = "nextcloud";
|
|
group = "nextcloud";
|
|
restartUnits = [ "phpfpm-nextcloud.service" ];
|
|
};
|
|
```
|
|
|
|
Then you can use that secret:
|
|
|
|
```nix
|
|
shb.nextcloud.adminPassFile = config.sops.secrets."nextcloud/adminpass".path;
|
|
```
|
|
|
|
### Nextcloud through HTTP {#services-nextcloud-server-usage-basic}
|
|
|
|
:::: {.note}
|
|
This section corresponds to the `basic` section of the [Nextcloud
|
|
demo](demo-nextcloud-server.html#demo-nextcloud-deploy-basic).
|
|
::::
|
|
|
|
This will set up a Nextcloud service that runs on the NixOS target machine, reachable at
|
|
`http://nextcloud.example.com`. If the `shb.ssl` block is [enabled](blocks-ssl.html#usage), the
|
|
instance will be reachable at `https://nextcloud.example.com`.
|
|
|
|
```nix
|
|
shb.nextcloud = {
|
|
enable = true;
|
|
domain = "example.com";
|
|
subdomain = "nextcloud";
|
|
dataDir = "/var/lib/nextcloud";
|
|
adminPassFile = <path/to/secret>;
|
|
};
|
|
```
|
|
|
|
After deploying, the Nextcloud server will be reachable at `http://nextcloud.example.com`.
|
|
|
|
### Mount Point {#services-nextcloud-server-mount-point}
|
|
|
|
If the `dataDir` exists in a mount point, it is highly recommended to make the various Nextcloud
|
|
services wait on the mount point before starting. Doing that is just a matter of setting the `mountPointServices` option.
|
|
|
|
Assuming a mount point on `/var`, the configuration would look like so:
|
|
|
|
```nix
|
|
fileSystems."/var".device = "...";
|
|
shb.nextcloud.mountPointServices = [ "var.mount" ];
|
|
```
|
|
|
|
### With LDAP Support {#services-nextcloud-server-usage-ldap}
|
|
|
|
:::: {.note}
|
|
This section corresponds to the `ldap` section of the [Nextcloud
|
|
demo](demo-nextcloud-server.html#demo-nextcloud-deploy-ldap).
|
|
::::
|
|
|
|
We will build upon the [Basic Configuration](#services-nextcloud-server-usage-basic) section, so
|
|
please read that first.
|
|
|
|
We will use the LDAP block provided by Self Host Blocks to setup a
|
|
[LLDAP](https://github.com/lldap/lldap) service.
|
|
|
|
```nix
|
|
shb.ldap = {
|
|
enable = true;
|
|
domain = "example.com";
|
|
subdomain = "ldap";
|
|
ldapPort = 3890;
|
|
webUIListenPort = 17170;
|
|
dcdomain = "dc=example,dc=com";
|
|
ldapUserPasswordFile = <path/to/ldapUserPasswordSecret>;
|
|
jwtSecretFile = <path/to/ldapJwtSecret>;
|
|
};
|
|
```
|
|
|
|
We also need to configure the `nextcloud` Self Host Blocks service to talk to the LDAP server we
|
|
just defined:
|
|
|
|
```nix
|
|
shb.nextcloud.apps.ldap
|
|
enable = true;
|
|
host = "127.0.0.1";
|
|
port = config.shb.ldap.ldapPort;
|
|
dcdomain = config.shb.ldap.dcdomain;
|
|
adminName = "admin";
|
|
adminPasswordFile = <path/to/ldapUserPasswordSecret>;
|
|
userGroup = "nextcloud_user";
|
|
};
|
|
```
|
|
|
|
The `shb.nextcloud.apps.ldap.adminPasswordFile` must be the same as the
|
|
`shb.ldap.ldapUserPasswordFile`. The other secret can be randomly generated with `nix run
|
|
nixpkgs#openssl -- rand -hex 64`.
|
|
|
|
And that's it. Now, go to the LDAP server at `http://ldap.example.com`, create the `nextcloud_user`
|
|
group, create a user and add it to the group. When that's done, go back to the Nextcloud server at
|
|
`http://nextcloud.example.com` and login with that user.
|
|
|
|
Note that we cannot create an admin user from the LDAP server, so you need to create a normal user
|
|
like above, login with it once so it is known to Nextcloud, then logout, login with the admin
|
|
Nextcloud user and promote that new user to admin level.
|
|
|
|
### With OIDC Support {#services-nextcloud-server-usage-oidc}
|
|
|
|
:::: {.note}
|
|
This section corresponds to the `sso` section of the [Nextcloud
|
|
demo](demo-nextcloud-server.html#demo-nextcloud-deploy-sso).
|
|
::::
|
|
|
|
We will build upon the [Basic Configuration](#services-nextcloud-server-usage-basic) and [With LDAP
|
|
Support](#services-nextcloud-server-usage-ldap) sections, so please read those first and setup the
|
|
LDAP app as described above.
|
|
|
|
Here though, we must setup SSL certificates because the SSO provider only works with the https
|
|
protocol. This is actually quite easy thanks to the [SSL block](blocks-ssl.html). For example, with
|
|
self-signed certificates:
|
|
|
|
```nix
|
|
shb.certs = {
|
|
cas.selfsigned.myca = {
|
|
name = "My CA";
|
|
};
|
|
certs.selfsigned = {
|
|
nextcloud = {
|
|
ca = config.shb.certs.cas.selfsigned.myca;
|
|
domain = "nextcloud.example.com";
|
|
};
|
|
auth = {
|
|
ca = config.shb.certs.cas.selfsigned.myca;
|
|
domain = "auth.example.com";
|
|
};
|
|
ldap = {
|
|
ca = config.shb.certs.cas.selfsigned.myca;
|
|
domain = "ldap.example.com";
|
|
};
|
|
};
|
|
};
|
|
```
|
|
|
|
We need to setup the SSO provider, here Authelia thanks to the corresponding SHB block:
|
|
|
|
```nix
|
|
shb.authelia = {
|
|
enable = true;
|
|
domain = "example.com";
|
|
subdomain = "auth";
|
|
ssl = config.shb.certs.certs.selfsigned.auth;
|
|
|
|
ldapEndpoint = "ldap://127.0.0.1:${builtins.toString config.shb.ldap.ldapPort}";
|
|
dcdomain = config.shb.ldap.dcdomain;
|
|
|
|
secrets = {
|
|
jwtSecretFile = <path/to/autheliaJwtSecret>;
|
|
ldapAdminPasswordFile = <path/to/ldapUserPasswordSecret>;
|
|
sessionSecretFile = <path/to/autheliaSessionSecret>;
|
|
storageEncryptionKeyFile = <path/to/autheliaStorageEncryptionKeySecret>;
|
|
identityProvidersOIDCHMACSecretFile = <path/to/providersOIDCHMACSecret>;
|
|
identityProvidersOIDCIssuerPrivateKeyFile = <path/to/providersOIDCIssuerSecret>;
|
|
};
|
|
};
|
|
```
|
|
|
|
The `shb.authelia.secrets.ldapAdminPasswordFile` must be the same as the
|
|
`shb.ldap.ldapUserPasswordFile` defined in the previous section. The secrets can be randomly
|
|
generated with `nix run nixpkgs#openssl -- rand -hex 64`.
|
|
|
|
Now, on the Nextcloud side, you need to add the following options:
|
|
|
|
```nix
|
|
shb.nextcloud.ssl = config.shb.certs.certs.selfsigned.nextcloud;
|
|
|
|
shb.nextcloud.apps.sso = {
|
|
enable = true;
|
|
endpoint = "https://${config.shb.authelia.subdomain}.${config.shb.authelia.domain}";
|
|
clientID = "nextcloud";
|
|
fallbackDefaultAuth = false;
|
|
|
|
secretFile = <path/to/oidcNextcloudSharedSecret>;
|
|
secretFileForAuthelia = <path/to/oidcNextcloudSharedSecret>;
|
|
};
|
|
```
|
|
|
|
Passing the `ssl` option will auto-configure nginx to force SSL connections with the given
|
|
certificate.
|
|
|
|
The `shb.nextcloud.apps.sso.secretFile` and `shb.nextcloud.apps.sso.secretFileForAuthelia` options
|
|
must have the same content. The former is a file that must be owned by the `nextcloud` user while
|
|
the latter must be owned by the `authelia` user. I want to avoid needing to define the same secret
|
|
twice with a future secrets SHB block.
|
|
|
|
### Tweak PHPFpm Config {#services-nextcloud-server-usage-phpfpm}
|
|
|
|
```nix
|
|
shb.nextcloud.phpFpmPoolSettings = {
|
|
"pm" = "dynamic";
|
|
"pm.max_children" = 800;
|
|
"pm.start_servers" = 300;
|
|
"pm.min_spare_servers" = 300;
|
|
"pm.max_spare_servers" = 500;
|
|
"pm.max_spawn_rate" = 50;
|
|
"pm.max_requests" = 50;
|
|
"pm.process_idle_timeout" = "20s";
|
|
};
|
|
```
|
|
|
|
### Tweak PostgreSQL Settings {#services-nextcloud-server-usage-postgres}
|
|
|
|
These settings will impact all databases.
|
|
|
|
```nix
|
|
shb.nextcloud.postgresSettings = {
|
|
max_connections = "100";
|
|
shared_buffers = "512MB";
|
|
effective_cache_size = "1536MB";
|
|
maintenance_work_mem = "128MB";
|
|
checkpoint_completion_target = "0.9";
|
|
wal_buffers = "16MB";
|
|
default_statistics_target = "100";
|
|
random_page_cost = "1.1";
|
|
effective_io_concurrency = "200";
|
|
work_mem = "2621kB";
|
|
huge_pages = "off";
|
|
min_wal_size = "1GB";
|
|
max_wal_size = "4GB";
|
|
};
|
|
```
|
|
|
|
### Backup {#services-nextcloud-server-usage-backup}
|
|
|
|
Backing up Nextcloud using the [Restic block](blocks-restic.html) is done like so:
|
|
|
|
```nix
|
|
shb.restic.instances."nextcloud" = config.shb.nextcloud.backup // {
|
|
enable = true;
|
|
};
|
|
```
|
|
|
|
The name `"nextcloud"` in the `instances` can be anything.
|
|
The `config.shb.nextcloud.backup` option provides what directories to backup.
|
|
You can define any number of Restic instances to backup Nextcloud multiple times.
|
|
|
|
### Enable Preview Generator App {#services-nextcloud-server-usage-previewgenerator}
|
|
|
|
The following snippet installs and enables the [Preview
|
|
Generator](https://apps.nextcloud.com/apps/previewgenerator) application as well as creates the
|
|
required cron job that generates previews every 10 minutes.
|
|
|
|
```nix
|
|
shb.nextcloud.apps.previewgenerator.enable = true;
|
|
```
|
|
|
|
Note that you still need to generate the previews for any pre-existing files with:
|
|
|
|
```bash
|
|
nextcloud-occ -vvv preview:generate-all
|
|
```
|
|
|
|
The default settings generates all possible sizes which is a waste since most are not used. SHB will
|
|
change the generation settings to optimize disk space and CPU usage as outlined in [this
|
|
article](http://web.archive.org/web/20200513043150/https://ownyourbits.com/2019/06/29/understanding-and-improving-nextcloud-previews/).
|
|
You can opt-out with:
|
|
|
|
```nix
|
|
shb.nextcloud.apps.previewgenerator.recommendedSettings = false;
|
|
```
|
|
|
|
### Enable External Storage App {#services-nextcloud-server-usage-externalstorage}
|
|
|
|
The following snippet installs and enables the [External
|
|
Storage](https://docs.nextcloud.com/server/28/go.php?to=admin-external-storage) application.
|
|
|
|
```nix
|
|
shb.nextcloud.apps.externalStorage.enable = true;
|
|
```
|
|
|
|
Optionally creates a local mount point with:
|
|
|
|
```nix
|
|
externalStorage = {
|
|
userLocalMount.rootDirectory = "/srv/nextcloud/$user";
|
|
userLocalMount.mountName = "home";
|
|
};
|
|
```
|
|
|
|
You can even make the external storage be at the root with:
|
|
|
|
```nix
|
|
externalStorage.userLocalMount.mountName = "/";
|
|
```
|
|
|
|
Recommended use of this app is to have the Nextcloud's `dataDir` on a SSD and the
|
|
`userLocalRooDirectory` on a HDD. Indeed, a SSD is much quicker than a spinning hard drive, which is
|
|
well suited for randomly accessing small files like thumbnails. On the other side, a spinning hard
|
|
drive can store more data which is well suited for storing user data.
|
|
|
|
### Enable OnlyOffice App {#services-nextcloud-server-usage-onlyoffice}
|
|
|
|
The following snippet installs and enables the [Only
|
|
Office](https://apps.nextcloud.com/apps/onlyoffice) application as well as sets up an Only Office
|
|
instance listening at `onlyoffice.example.com` that only listens on the local network.
|
|
|
|
```nix
|
|
shb.nextcloud.apps.onlyoffice = {
|
|
enable = true;
|
|
subdomain = "onlyoffice";
|
|
localNextworkIPRange = "192.168.1.1/24";
|
|
};
|
|
```
|
|
|
|
Also, you will need to explicitly allow the package `corefonts`:
|
|
|
|
```nix
|
|
nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (pkgs.lib.getName pkg) [
|
|
"corefonts"
|
|
];
|
|
```
|
|
|
|
### Enable Monitoring {#services-nextcloud-server-server-usage-monitoring}
|
|
|
|
Enable the [monitoring block](./blocks-monitoring.html). The metrics will automatically appear in
|
|
the corresponding dashboards.
|
|
|
|
### Enable Tracing {#services-nextcloud-server-server-usage-tracing}
|
|
|
|
You can enable tracing with:
|
|
|
|
```nix
|
|
shb.nextcloud.debug = true;
|
|
```
|
|
|
|
Traces will be located at `/var/log/xdebug`.
|
|
|
|
See [my blog
|
|
post](http://blog.tiserbox.com/posts/2023-08-12-what%27s-up-with-nextcloud-webdav-slowness.html) for
|
|
how to look at the traces.
|
|
|
|
### Appdata Location {#services-nextcloud-server-server-usage-appdata}
|
|
|
|
The appdata folder is a special folder located under the `shb.nextcloud.dataDir` directory. It is
|
|
named `appdata_<instanceid>` with the Nextcloud's instance ID as a suffix. You can find your current
|
|
instance ID with `nextcloud-occ config:system:get instanceid`. In there, you will find one subfolder
|
|
for every installed app that needs to store files.
|
|
|
|
For performance reasons, it is recommended to store this folder on a fast drive that is optimized
|
|
for randomized read and write access. The best would be either an SSD or an NVMe drive.
|
|
|
|
If you intentionally put Nextcloud's `shb.nextcloud.dataDir` folder on a HDD with spinning disks,
|
|
for example because they offer more disk space, then the appdata folder is also located on spinning
|
|
drives. You are thus faced with a conundrum. The only way to solve this is to bind mount a folder
|
|
from an SSD over the appdata folder. SHB does not provide (yet?) a declarative way to setup this but
|
|
this command should be enough:
|
|
|
|
```bash
|
|
mount /dev/sdd /srv/sdd
|
|
mkdir -p /srv/sdd/appdata_nextcloud
|
|
mount --bind /srv/sdd/appdata_nextcloud /var/lib/nextcloud/data/appdata_ocxvky2f5ix7
|
|
```
|
|
|
|
Note that you can re-generate a new appdata folder by issuing the command `occ config:system:delete
|
|
instanceid`.
|
|
|
|
## Demo {#services-nextcloud-server-demo}
|
|
|
|
Head over to the [Nextcloud demo](demo-nextcloud-server.html) for a demo that installs Nextcloud with or
|
|
without LDAP integration on a VM with minimal manual steps.
|
|
|
|
## Maintenance {#services-nextcloud-server-maintenance}
|
|
|
|
On the command line, the `occ` tool is called `nextcloud-occ`.
|
|
|
|
## Debug {#services-nextcloud-server-debug}
|
|
|
|
In case of an issue, check the logs for any systemd service mentioned in this section.
|
|
|
|
On startup, the oneshot systemd service `nextcloud-setup.service` starts. After it finishes, the
|
|
`phpfpm-nextcloud.service` starts to serve Nextcloud. The `nginx.service` is used as the reverse
|
|
proxy. `postgresql.service` run the database.
|
|
|
|
Nextcloud' configuration is found at `${shb.nextcloud.dataDir}/config/config.php`. Nginx'
|
|
configuration can be found with `systemctl cat nginx | grep -om 1 -e "[^ ]\+conf"`.
|
|
|
|
Enable verbose logging by setting the `shb.nextcloud.debug` boolean to `true`.
|
|
|
|
Access the database with `sudo -u nextcloud psql`.
|
|
|
|
Access Redis with `sudo -u nextcloud redis-cli -s /run/redis-nextcloud/redis.sock`.
|
|
|
|
## Options Reference {#services-nextcloud-server-options}
|
|
|
|
```{=include=} options
|
|
id-prefix: services-nextcloud-server-options-
|
|
list-id: selfhostblocks-service-nextcloud-options
|
|
source: @OPTIONS_JSON@
|
|
```
|