Skip to content

Commit

Permalink
nixos/nextcloud: fix nginx routing to store and nix apps
Browse files Browse the repository at this point in the history
Closes NixOS#277206

The bug mentioned above was a symptom of the issue fixed here: when
opening the `forms` app which is installed via `extraApps` (or the
app store) the site wouldn't work because `.mjs` files had the wrong
Content-Type.

The actual problem got fixed already[1], however this config was not
used for stuff from `/nix-apps` & `/store-apps` which had their own
location section with only a `root ;` statement.

In fact, this setup isn't strictly supported by Nextcloud upstream[2],
so to fix this for good, I decided to follow the upstream suggestion for
app directories outside the server root, i.e. linking them back into the
store path.

This means that the module generates a new derivation now with

* `services.nextcloud.package` linked into it via `lndir`.
* under `nix-apps` is a symlink to the link farm containing all apps
  from `services.nextcloud.extraApps`.
* under `store-apps` is a symlink to `/var/lib/nextcloud/store-apps`.
  Since this is only used in the NixOS module that also configures this
  location for imperatively installed apps, this seems an OK thing to
  do.

Successfully tested the change on a productive Nextcloud 28.0.1 with
several apps installed via `extraApps` (`forms`, `cospend`, `maps`,
`user_saml` and a few more).

[1] 292c74c
[2] https://docs.nextcloud.com/server/28/admin_manual/apps_management.html#using-custom-app-directories
  • Loading branch information
Ma27 committed Dec 29, 2023
1 parent 7412095 commit bae5e65
Showing 1 changed file with 53 additions and 23 deletions.
76 changes: 53 additions & 23 deletions nixos/modules/services/web-apps/nextcloud.nix
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,43 @@ let
catch_workers_output = "yes";
};

appStores = {
# default apps bundled with pkgs.nextcloudXX, e.g. files, contacts
apps = {
enabled = true;
writable = false;
};
# apps installed via cfg.extraApps
nix-apps = {
enabled = cfg.extraApps != { };
linkTarget = pkgs.linkFarm "nix-apps"
(mapAttrsToList (name: path: { inherit name path; }) cfg.extraApps);
writable = false;
};
# apps installed via the app store.
store-apps = {
enabled = cfg.appstoreEnable == null || cfg.appstoreEnable;
linkTarget = "${cfg.home}/store-apps";
writable = true;
};
};

webroot = pkgs.runCommand
"${cfg.package.name or "nextcloud"}-with-apps"
{ }
''
mkdir $out
ln -sfv "${cfg.package}"/* "$out"
${concatStrings
(mapAttrsToList (name: store: optionalString (store.enabled && store?linkTarget) ''
if [ -e "$out"/${name} ]; then
echo "Didn't expect ${name} already in $out!"
exit 1
fi
ln -sfTv ${store.linkTarget} "$out"/${name}
'') appStores)}
'';

inherit (cfg) datadir;

phpPackage = cfg.phpPackage.buildEnv {
Expand All @@ -45,7 +82,7 @@ let

occ = pkgs.writeScriptBin "nextcloud-occ" ''
#! ${pkgs.runtimeShell}
cd ${cfg.package}
cd ${webroot}
sudo=exec
if [[ "$USER" != nextcloud ]]; then
sudo='exec /run/wrappers/bin/sudo -u nextcloud --preserve-env=NEXTCLOUD_CONFIG_DIR --preserve-env=OC_PASS'
Expand Down Expand Up @@ -766,7 +803,7 @@ in {
# When upgrading the Nextcloud package, Nextcloud can report errors such as
# "The files of the app [all apps in /var/lib/nextcloud/apps] were not replaced correctly"
# Restarting phpfpm on Nextcloud package update fixes these issues (but this is a workaround).
phpfpm-nextcloud.restartTriggers = [ cfg.package ];
phpfpm-nextcloud.restartTriggers = [ webroot ];

nextcloud-setup = let
c = cfg.config;
Expand Down Expand Up @@ -800,6 +837,10 @@ in {

nextcloudGreaterOrEqualThan = req: versionAtLeast cfg.package.version req;

mkAppStoreConfig = name: { enabled, writable, ... }: optionalString enabled ''
[ 'path' => '${webroot}/${name}', 'url' => '/${name}', 'writable' => ${boolToString writable} ],
'';

overrideConfig = pkgs.writeText "nextcloud-config.php" ''
<?php
${optionalString requiresReadSecretFunction ''
Expand Down Expand Up @@ -828,9 +869,7 @@ in {
}
$CONFIG = [
'apps_paths' => [
${optionalString (cfg.extraApps != { }) "[ 'path' => '${cfg.home}/nix-apps', 'url' => '/nix-apps', 'writable' => false ],"}
[ 'path' => '${cfg.home}/apps', 'url' => '/apps', 'writable' => false ],
[ 'path' => '${cfg.home}/store-apps', 'url' => '/store-apps', 'writable' => true ],
${concatStrings (mapAttrsToList mkAppStoreConfig appStores)}
],
${optionalString (showAppStoreSetting) "'appstoreenabled' => ${renderedAppStoreSetting},"}
'datadirectory' => '${datadir}/data',
Expand Down Expand Up @@ -935,17 +974,16 @@ in {
exit 1
fi
ln -sf ${cfg.package}/apps ${cfg.home}/
# Install extra apps
ln -sfT \
${pkgs.linkFarm "nix-apps"
(mapAttrsToList (name: path: { inherit name path; }) cfg.extraApps)} \
${cfg.home}/nix-apps
${concatMapStrings (name: ''
if [ -d "${cfg.home}"/${name} ]; then
echo "Cleaning up ${name}; these are now bundled in the webroot store-path!"
rm -r "${cfg.home}"/${name}
fi
'') [ "nix-apps" "apps" ]}
# create nextcloud directories.
# if the directories exist already with wrong permissions, we fix that
for dir in ${datadir}/config ${datadir}/data ${cfg.home}/store-apps ${cfg.home}/nix-apps; do
for dir in ${datadir}/config ${datadir}/data ${cfg.home}/store-apps; do
if [ ! -e $dir ]; then
install -o nextcloud -g nextcloud -d $dir
elif [ $(stat -c "%G" $dir) != "nextcloud" ]; then
Expand Down Expand Up @@ -982,7 +1020,7 @@ in {
environment.NEXTCLOUD_CONFIG_DIR = "${datadir}/config";
serviceConfig.Type = "oneshot";
serviceConfig.User = "nextcloud";
serviceConfig.ExecStart = "${phpPackage}/bin/php -f ${cfg.package}/cron.php";
serviceConfig.ExecStart = "${phpPackage}/bin/php -f ${webroot}/cron.php";
};
nextcloud-update-plugins = mkIf cfg.autoUpdateApps.enable {
after = [ "nextcloud-setup.service" ];
Expand Down Expand Up @@ -1058,7 +1096,7 @@ in {
services.nginx.enable = mkDefault true;

services.nginx.virtualHosts.${cfg.hostName} = {
root = cfg.package;
root = webroot;
locations = {
"= /robots.txt" = {
priority = 100;
Expand All @@ -1075,14 +1113,6 @@ in {
}
'';
};
"~ ^/store-apps" = {
priority = 201;
extraConfig = "root ${cfg.home};";
};
"~ ^/nix-apps" = {
priority = 201;
extraConfig = "root ${cfg.home};";
};
"^~ /.well-known" = {
priority = 210;
extraConfig = ''
Expand Down

0 comments on commit bae5e65

Please sign in to comment.