Why?
I currently have a Nextcloud service running on the host Nixos system with default settings. The problems come when Nextcloud has to manage it’s own database and that would interfere with other services. For example, installing WordPress and Nextcloud would throw and error in Nixos (using the default settings) because they both want to manage the same Mysql instance. So the best approach here would be to isolate the system with Systemd containers.
Somethings to look out for
- We need to create a new instance of Nextcloud in the container. (check out my previous post of creating a container isolated from home network).
- Back up and restore the Mysql from host instance to container instance.
- Bind mount the secrets (admin password) to the container with readonly.
- Bind mount the data directory to the Nextcloud instance with the correct permissions from user in container. This will probably be the least trivial.
Backup process
Put the Nextcloud instance to maintenance mode.
nextcloud-occ maintenance:mode --on
Backup mysql database.
mysqldump --single-transaction -u root nextcloud > nextcloud-sqlbkp_date +"%Y%m%d".bak
Create a container for Nextcloud. Create a temporary domain name
containers.nextcloud = {
autoStart = true;
privateNetwork = true;
hostAddress = "10.0.0.5";
localAddress = "10.0.0.6";
# pass decrypted secret into container
bindMounts."/run/secrets/nextcloud/adminpass" = {
hostPath = config.sops.secrets."nextcloud/adminpass".path;
isReadOnly = true;
};
config = {
config,
pkgs,
lib,
...
}: {
services.nextcloud = {
enable = true;
hostName = "nextcloud2.your-local-domain.com";
# https = true;
package = pkgs.nextcloud33;
# [...]
# Instead of using pkgs.nextcloud29Packages.apps or similar,
# we'll reference the package version specified in services.nextcloud.package
extraApps = {
inherit
(config.services.nextcloud.package.packages.apps)
calendar
contacts
mail
notes
onlyoffice
tasks
cospend
phonetrack
news
;
};
extraAppsEnable = true;
# datadir = "/mypool/nextcloud/";
database.createLocally = true;
configureRedis = true;
config = {
adminuser = "your-username";
dbtype = "mysql";
adminpassFile = "/run/secrets/nextcloud/adminpass";
};
#settings behind https nginx
settings = {
trusted_proxies = ["10.0.0.5"]; # The Host's container IP
overwriteprotocol = "https";
};
};
networking.firewall.allowedTCPPorts = [80];
system.stateVersion = "26.05"; # Required for running NixOS containers
};
};
Put the Nextcloud instance in the container in maintenance mode.
Transfer the database backup file into the container and rewrite the database using the Nextcloud “Backup and Restore” below:
https://docs.nextcloud.com/server/stable/admin_manual/maintenance/restore.html
Things getting Tricky
After the database restoration in the container instance, Nextcloud still needs access to data directory. We will then disable the Nextcloud instance running on the host operating system by commenting out the instance and run the rebuild. (This is where Nixos shines. No need to execute commands in the terminal. The config file will do everything for you).
# nixos-rebuild switch --flake ~/nixos-config#machine-name
After which we can mount the directory into the container directory and rewrite the folder’s permission to the Nextcloud user in the container.
containers.nextcloud = {
...
bindMounts."/mypool/nextcloud/" = {
hostPath = "/mypool/nextcloud/";
isReadOnly = false;
};
...
services.nextcloud = {
datadir = "/mypool/nextcloud/";
};
};
After you have checked everything is working, we can switch to our desired domain and have our reverse proxy Nginx point to the container instance. One the thing to note is that our Nginx is responsible for the HTTPS request and only communicate in HTTP with the container.
ββββββββββ βββββββββββββββ ββββββββββββ
β Client ββββ Nginx βββββNextcloud β
β Https β β Https - Httpβ βContainer β
ββββββββββ βββββββββββββββ βHttp β
ββββββββββββ
References
https://discourse.nixos.org/t/host-permissions-for-container-bindmount/30613
https://docs.nextcloud.com/server/stable/admin_manual/maintenance/restore.html