Files
2026-03-15 18:31:53 +01:00

274 lines
8.1 KiB
Nix

{ config, pkgs, lib, ... }:
let
appName = "nextcloud";
defaultPort = 80;
cfg = config.infrastructure.${appName};
in
{
options.infrastructure.${appName} = {
enable = lib.mkEnableOption "infrastructure.nextcloud";
package = lib.mkOption {
type = lib.types.package;
description = "Nextcloud package to use.";
default = pkgs.nextcloud31;
example = "pkgs.nextcloud30";
};
hostName = lib.mkOption {
type = lib.types.str;
description = "Hostname for Nextcloud.";
default = "localhost";
example = "cloud.example.com";
};
https = lib.mkOption {
type = lib.types.bool;
description = "Whether to use HTTPS.";
default = false;
};
# ==========================================================================
# Admin Configuration
# ==========================================================================
admin = {
user = lib.mkOption {
type = lib.types.str;
description = "Admin username.";
default = "admin";
};
passwordFile = lib.mkOption {
type = lib.types.path;
description = "Path to file containing admin password.";
};
};
# ==========================================================================
# Database Configuration
# ==========================================================================
database = {
type = lib.mkOption {
type = lib.types.enum [ "sqlite" "pgsql" "mysql" ];
description = "Database type to use.";
default = "pgsql";
};
name = lib.mkOption {
type = lib.types.str;
description = "Database name.";
default = "nextcloud";
};
user = lib.mkOption {
type = lib.types.str;
description = "Database user.";
default = "nextcloud";
};
host = lib.mkOption {
type = lib.types.str;
description = "Database host. Use socket path for local connections.";
default = "/run/postgresql";
example = "127.0.0.1";
};
createLocally = lib.mkOption {
type = lib.types.bool;
description = ''
Whether to create the database and user locally.
Only works for PostgreSQL and MySQL/MariaDB when using socket authentication.
'';
default = true;
};
};
# ==========================================================================
# Caching Configuration
# ==========================================================================
caching = {
redis = lib.mkOption {
type = lib.types.bool;
description = "Enable Redis for caching and file locking.";
default = false;
};
apcu = lib.mkOption {
type = lib.types.bool;
description = "Enable APCu for local caching.";
default = true;
};
memcached = lib.mkOption {
type = lib.types.bool;
description = "Enable Memcached for distributed caching.";
default = false;
};
};
# ==========================================================================
# PHP Configuration
# ==========================================================================
maxUploadSize = lib.mkOption {
type = lib.types.str;
description = "Maximum upload size.";
default = "512M";
example = "1G";
};
phpOptions = lib.mkOption {
type = lib.types.attrsOf lib.types.str;
description = "Additional PHP options.";
default = {};
example = {
"opcache.interned_strings_buffer" = "16";
"opcache.max_accelerated_files" = "10000";
};
};
# ==========================================================================
# Extra Configuration
# ==========================================================================
extraApps = lib.mkOption {
type = lib.types.attrsOf lib.types.package;
description = "Extra Nextcloud apps to install.";
default = {};
example = lib.literalExpression ''
with config.services.nextcloud.package.packages.apps; {
inherit calendar contacts notes;
}
'';
};
extraAppsEnable = lib.mkOption {
type = lib.types.bool;
description = "Automatically enable extra apps.";
default = true;
};
settings = lib.mkOption {
type = lib.types.attrsOf lib.types.anything;
description = ''
Additional Nextcloud configuration settings.
These are passed directly to services.nextcloud.settings.
'';
default = {};
example = {
default_phone_region = "US";
overwriteprotocol = "https";
};
};
};
config = lib.mkIf cfg.enable {
# ==========================================================================
# Nextcloud Service Configuration
# ==========================================================================
services.nextcloud = {
enable = true;
package = cfg.package;
hostName = cfg.hostName;
https = cfg.https;
# Admin configuration
config = {
adminuser = cfg.admin.user;
adminpassFile = cfg.admin.passwordFile;
# Database configuration
dbtype = cfg.database.type;
dbname = cfg.database.name;
dbuser = cfg.database.user;
dbhost = cfg.database.host;
};
# Database creation
database.createLocally = cfg.database.createLocally;
# Caching configuration
caching = {
redis = cfg.caching.redis;
apcu = cfg.caching.apcu;
memcached = cfg.caching.memcached;
};
# Configure Redis for file locking if enabled
configureRedis = cfg.caching.redis;
# PHP settings
maxUploadSize = cfg.maxUploadSize;
phpOptions = {
"opcache.enable" = "1";
"opcache.enable_cli" = "1";
"opcache.interned_strings_buffer" = "8";
"opcache.max_accelerated_files" = "10000";
"opcache.memory_consumption" = "128";
"opcache.save_comments" = "1";
"opcache.revalidate_freq" = "1";
} // cfg.phpOptions;
# Extra apps
extraApps = cfg.extraApps;
extraAppsEnable = cfg.extraAppsEnable;
# Additional settings
settings = {
default_phone_region = "US";
maintenance_window_start = 1;
} // cfg.settings;
};
# ==========================================================================
# Nginx Configuration (automatically enabled by Nextcloud module)
# ==========================================================================
services.nginx = {
enable = true;
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedProxySettings = true;
recommendedTlsSettings = true;
};
# ==========================================================================
# Service Dependencies
# ==========================================================================
# Ensure Nextcloud starts after its dependencies
systemd.services.nextcloud-setup = {
after = lib.mkMerge [
# Database dependencies
(lib.mkIf (cfg.database.type == "pgsql" && cfg.database.createLocally) [ "postgresql.service" ])
(lib.mkIf (cfg.database.type == "mysql" && cfg.database.createLocally) [ "mysql.service" ])
# Redis dependency
(lib.mkIf cfg.caching.redis [ "redis-nextcloud.service" ])
];
requires = lib.mkMerge [
(lib.mkIf (cfg.database.type == "pgsql" && cfg.database.createLocally) [ "postgresql.service" ])
(lib.mkIf (cfg.database.type == "mysql" && cfg.database.createLocally) [ "mysql.service" ])
];
};
# ==========================================================================
# Firewall Configuration
# ==========================================================================
networking.firewall.allowedTCPPorts = [ 80 443 ];
# ==========================================================================
# Utilities
# ==========================================================================
environment.systemPackages = with pkgs; [
curl
];
};
}