Files
nixconfig/modules/server/containers/apps/nextcloud.nix
2026-05-10 18:29:53 +02:00

192 lines
9.4 KiB
Nix

{ config, containerCfg, pkgs, lib, builder, name,... }:
let
version = "31";
serverCfg = config.syscfg.server;
in {
paths = [{
path="${serverCfg.dataPath}/nextcloud/www";
owner = "33:33";
mode = "0755";
}{
path="${serverCfg.dataPath}/nextcloud/data";
owner = "33:33";
mode = "0755";
backup = true;
}];
containers = {
server = builder.mkContainer {
subdomain = containerCfg.subdomain;
image = "nextcloud:${version}";
port = containerCfg.port;
ip = containerCfg.ip;
secret = name;
extraEnv = {
REDIS_HOST = builder.host;
POSTGRES_HOST = builder.host;
POSTGRES_USER = "nextcloud_user";
POSTGRES_DB = "nextcloud_db";
AUTHENTIK_POSTGRESQL__SSLMODE = "disable";
"NEXTCLOUD_TRUSTED_DOMAINS " = "${containerCfg.subdomain}.${serverCfg.hostDomain}";
"SMTP_HOST" = serverCfg.mailServer;
"SMTP_NAME" = "mail_user";
"SMTP_PASSWORD" = "mail_password";
"MAIL_FROM_ADDRESS" = "${containerCfg.subdomain}@${serverCfg.hostDomain}";
"MAIL_DOMAIN" = serverCfg.mailDomain;
"TRUSTED_PROXIES" = "10.10.0.0/16 192.168.0.0/16";
};
extraLabels = {
"traefik.http.routers.${containerCfg.subdomain}.middlewares" = "sts_headers,${containerCfg.subdomain}-caldav";
"traefik.http.middlewares.${containerCfg.subdomain}-caldav.redirectregex.permanent" = "true";
"traefik.http.middlewares.${containerCfg.subdomain}-caldav.redirectregex.regex" = "https://(.*)/.well-known/(?:card|cal)dav";
"traefik.http.middlewares.${containerCfg.subdomain}-caldav.redirectregex.replacement" = "https://$1/remote.php/dav";
"traefik.http.middlewares.sts_headers.headers.stsSeconds" = "15552000";
"traefik.http.middlewares.sts_headers.headers.stsIncludeSubdomains" = "true";
};
extraOptions = [
"--tmpfs=/tmp:rw,noexec,nosuid,size=512m"
];
overrides = {
ports = if containerCfg.pubPort!=null && containerCfg.port!=null then [ "${toString containerCfg.pubPort}:${toString containerCfg.port}" ] else [];
volumes = [
"${serverCfg.dataPath}/nextcloud/www:/var/www/html"
"${serverCfg.dataPath}/nextcloud/data:/var/www/html/data"
];
};
};
};
setup = {
trigger="server";
script = pkgs.writeShellScript "setup" ''
# Define the command wrapper
OCC="${pkgs.podman}/bin/podman --events-backend=none exec -u www-data nextcloud-server php occ"
echo "Waiting for Nextcloud container to start..."
until $OCC status > /dev/null 2>&1; do
sleep 2
done
INSTALLED=$($OCC status --output=json | grep -o '"installed":false')
if [ -z "$INSTALLED" ]; then
echo "Running first-time setup..."
# $OCC maintenance:install \
# --admin-user "admin" \
# --admin-pass "adminpassword"
echo "Applying Settings..."
$OCC config:system:set default_phone_region --value="CH"
$OCC config:system:set overwriteprotocol --value="https"
$OCC config:app:set core backgroundjobs_mode --value="cron"
$OCC config:system:set maintenance_window_start --type=integer --value=1
$OCC config:system:set default_language --value="en"
$OCC config:system:set default_locale --value="en_CH"
echo "Applying Apps..."
$OCC app:disable activity || true
$OCC app:disable app_api || true
$OCC app:disable comments || true
$OCC app:disable firstrunwizard || true
$OCC config:system:set show_first_run_wizard --type=bool --value=false
$OCC app:disable nextcloud_announcements || true
$OCC app:disable oauth2 || true
$OCC app:disable recommendations || true
$OCC app:disable sharebymail || true
$OCC app:disable support || true
$OCC app:disable survey_client || true
$OCC app:disable updatenotification || true
$OCC app:disable user_status || true
$OCC app:install calendar || true
$OCC app:install calendar || true
$OCC app:install contacts || true
$OCC app:install camerarawpreviews || true
$OCC app:install cospend || true
$OCC app:install deck || true
$OCC app:install files_markdown || true
$OCC app:install forms || true
$OCC app:install groupfolders || true
$OCC app:install ownpad || true
$OCC app:install previewgenerator || true
$OCC app:install richdocuments || true
${lib.optionalString (serverCfg.containers ? collabora == false) ''$OCC app:install richdocumentscode || true''}
# $OCC app:install side_menu || true
$OCC app:install spreed || true
${lib.optionalString (serverCfg.containers ? authentik) ''$OCC app:install user_saml || true''}
echo "Applying Apps Settings..."
$OCC config:system:set enabledPreviewProviders --value='["OC\\Preview\\Movie", "OC\\Preview\\PNG", "OC\\Preview\\JPEG", "OC\\Preview\\GIF", "OC\\Preview\\HEIC", "OC\\Preview\\RAW"]' --type=json
$OCC config:app:set cospend allow_federation --value="yes"
${lib.optionalString (serverCfg.containers ? ethercalc) ''
$OCC config:app:set ownpad ownpad_ethercalc_enable --value="yes"
$OCC config:app:set ownpad ownpad_ethercalc_host --value="https:\/\/${serverCfg.containers.ethercalc.subdomain}.${serverCfg.hostDomain}"
''}
${lib.optionalString (serverCfg.containers ? etherpad) ''
$OCC config:app:set ownpad ownpad_etherpad_enable --value="yes"
$OCC config:app:set ownpad ownpad_etherpad_host --value="https:\/\/${serverCfg.containers.etherpad.subdomain}.${serverCfg.hostDomain}"
''}
${lib.optionalString (serverCfg.containers ? collabora) ''
$OCC config:app:set richdocuments wopi_url --value="https://${serverCfg.containers.collabora.subdomain}.${serverCfg.hostDomain}/"
$OCC config:app:set richdocuments public_wopi_url --value="https://${serverCfg.containers.collabora.subdomain}.${serverCfg.hostDomain}"
$OCC config:app:set richdocuments wopi_allowlist --value="10.0.0.0/8"
''}
${lib.optionalString (serverCfg.containers ? authentik) ''
$OCC saml:config:set --general-idp0_display_name="authentik"
$OCC saml:config:set --general-uid_mapping="http://schemas.goauthentik.io/2021/02/saml/username"
$OCC saml:config:set --idp-entityId="https://${serverCfg.containers.authentik.subdomain}.${serverCfg.hostDomain}"
$OCC saml:config:set --idp-singleSignOnService.url="https://${serverCfg.containers.authentik.subdomain}.${serverCfg.hostDomain}/application/saml/${containerCfg.subdomain}/sso/binding/redirect/"
$OCC saml:config:set --idp-singleLogoutService.url="https://${serverCfg.containers.authentik.subdomain}.${serverCfg.hostDomain}/application/saml/${containerCfg.subdomain}/slo/binding/redirect/"
$OCC saml:config:set --idp-x509cert="MII..."
$OCC saml:config:set --saml-attribute-mapping-displayName_mapping="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"
$OCC saml:config:set --saml-attribute-mapping-email_mapping="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"
$OCC saml:config:set --saml-attribute-mapping-group_mapping="http://schemas.xmlsoap.org/claims/Group"
$OCC saml:config:set --general-group_provisioning="0"
$OCC config:app:set user_saml general-require_provisioning_groups --value="0"
# $OCC saml:config:set --general-allowed_groups="cloud,admin"
''}
# configure side_menu ...
FOLDERS=$($OCC teamfolders:list --format=json)
${builtins.concatStringsSep "\n" (map (name: ''
if ! echo "$FOLDERS" | grep -q '"name":"${name}"'; then
$OCC teamfolders:create "${name}"
fi
'') containerCfg.extra.teamFolders or [])}
SERVERS=$($OCC federation:list-servers --format=json)
${builtins.concatStringsSep "\n" (map (domain: ''
if ! echo "$SERVERS" | grep -q "${domain}"; then
$OCC federation:add-server "https://${domain}"
fi
'') containerCfg.extra.federatedServers or [])}
$OCC config:app:set systemtags allow_user_creating --value="no"
echo "Applying Theme..."
$OCC config:app:set theming url --value="https://${containerCfg.subdomain}.${serverCfg.hostDomain}"
${lib.optionalString (containerCfg.extra ? name) ''$OCC config:app:set theming name --value="${containerCfg.extra.name}"''}
${lib.optionalString (containerCfg.extra ? slogan) ''$OCC config:app:set theming slogan --value="${containerCfg.extra.slogan}"''}
$OCC config:app:set theming background_color --value="${serverCfg.colorScheme.palette.base0C}"
$OCC config:app:set theming primary_color --value="${serverCfg.colorScheme.palette.base0C}"
#$OCC theming:config logo {serverCfg.colorScheme.logo}
#$OCC theming:config logoheader {serverCfg.colorScheme.logo}
#$OCC theming:config background {serverCfg.colorScheme.bg}
else
echo "Nextcloud is already installed. Skipping setup."
fi
echo "Maintenance..."
$OCC app:update --all
$OCC maintenance:repair --include-expensive --no-interaction
$OCC db:add-missing-indices --no-interaction
echo "Completed Setup"
'';
};
cron = [ "*/5 * * * * root ${pkgs.podman}/bin/podman --events-backend=none exec -u www-data nextcloud-server php -f /var/www/html/cron.php" ];
}