2024-04-20 13:42:06 +00:00
|
|
|
{
|
|
|
|
config,
|
|
|
|
pkgs,
|
|
|
|
lib,
|
|
|
|
...
|
|
|
|
}:
|
|
|
|
{
|
2022-10-02 20:54:26 +00:00
|
|
|
|
2023-07-04 22:20:43 +00:00
|
|
|
config = lib.mkIf config.services.nextcloud.enable {
|
2022-10-02 20:54:26 +00:00
|
|
|
|
|
|
|
services.nextcloud = {
|
2024-01-04 03:49:36 +00:00
|
|
|
package = pkgs.nextcloud28; # Required to specify
|
2023-08-02 11:32:54 +00:00
|
|
|
configureRedis = true;
|
2023-03-03 20:54:27 +00:00
|
|
|
datadir = "/data/nextcloud";
|
2023-08-02 11:32:54 +00:00
|
|
|
database.createLocally = true;
|
2022-10-02 20:54:26 +00:00
|
|
|
https = true;
|
|
|
|
hostName = "localhost";
|
2022-10-04 12:29:29 +00:00
|
|
|
maxUploadSize = "50G";
|
2022-10-02 20:54:26 +00:00
|
|
|
config = {
|
2022-10-16 03:18:58 +00:00
|
|
|
adminpassFile = config.secrets.nextcloud.dest;
|
2024-02-25 22:31:02 +00:00
|
|
|
dbtype = "pgsql";
|
2022-10-02 20:54:26 +00:00
|
|
|
};
|
2024-02-10 01:37:21 +00:00
|
|
|
settings = {
|
2024-01-04 03:49:36 +00:00
|
|
|
default_phone_region = "US";
|
2024-01-10 04:11:11 +00:00
|
|
|
# Allow access when hitting either of these hosts or IPs
|
2024-01-04 03:49:36 +00:00
|
|
|
trusted_domains = [ config.hostnames.content ];
|
|
|
|
trusted_proxies = [ "127.0.0.1" ];
|
2024-02-25 22:31:02 +00:00
|
|
|
maintenance_window_start = 4; # Run jobs at 4am UTC
|
2024-01-04 03:49:36 +00:00
|
|
|
};
|
2023-08-02 12:26:45 +00:00
|
|
|
extraAppsEnable = true;
|
|
|
|
extraApps = with config.services.nextcloud.package.packages.apps; {
|
|
|
|
inherit calendar contacts;
|
2024-01-10 04:11:11 +00:00
|
|
|
# These apps are defined and pinned by overlay in flake.
|
2023-08-03 02:26:35 +00:00
|
|
|
news = pkgs.nextcloudApps.news;
|
|
|
|
external = pkgs.nextcloudApps.external;
|
|
|
|
cookbook = pkgs.nextcloudApps.cookbook;
|
2024-01-21 02:12:57 +00:00
|
|
|
snappymail = pkgs.nextcloudApps.snappymail;
|
2023-08-02 12:26:45 +00:00
|
|
|
};
|
2024-01-13 13:35:50 +00:00
|
|
|
phpOptions = {
|
|
|
|
"opcache.interned_strings_buffer" = "16";
|
|
|
|
"output_buffering" = "0";
|
|
|
|
};
|
2022-10-02 20:54:26 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
# Don't let Nginx use main ports (using Caddy instead)
|
2023-07-30 03:51:01 +00:00
|
|
|
services.nginx.enable = false;
|
|
|
|
|
|
|
|
services.phpfpm.pools.nextcloud.settings = {
|
|
|
|
"listen.owner" = config.services.caddy.user;
|
|
|
|
"listen.group" = config.services.caddy.group;
|
|
|
|
};
|
|
|
|
users.users.caddy.extraGroups = [ "nextcloud" ];
|
2022-10-02 20:54:26 +00:00
|
|
|
|
2022-10-16 03:18:58 +00:00
|
|
|
# Point Caddy to Nginx
|
2024-04-20 13:42:06 +00:00
|
|
|
caddy.routes = [
|
|
|
|
{
|
|
|
|
match = [ { host = [ config.hostnames.content ]; } ];
|
|
|
|
handle = [
|
2023-07-30 03:51:01 +00:00
|
|
|
{
|
2024-04-20 13:42:06 +00:00
|
|
|
handler = "subroute";
|
|
|
|
routes = [
|
|
|
|
# Sets variables and headers
|
2023-07-30 03:51:01 +00:00
|
|
|
{
|
2024-04-20 13:42:06 +00:00
|
|
|
handle = [
|
|
|
|
{
|
|
|
|
handler = "vars";
|
|
|
|
# Grab the webroot out of the written config
|
|
|
|
# The webroot is a symlinked combined Nextcloud directory
|
|
|
|
root = config.services.nginx.virtualHosts.${config.services.nextcloud.hostName}.root;
|
|
|
|
}
|
|
|
|
{
|
|
|
|
handler = "headers";
|
|
|
|
response.set.Strict-Transport-Security = [ "max-age=31536000;" ];
|
|
|
|
}
|
|
|
|
];
|
2023-07-30 03:51:01 +00:00
|
|
|
}
|
2024-04-20 13:42:06 +00:00
|
|
|
# Reroute carddav and caldav traffic
|
2023-07-30 03:51:01 +00:00
|
|
|
{
|
2024-04-20 13:42:06 +00:00
|
|
|
match = [
|
|
|
|
{
|
|
|
|
path = [
|
|
|
|
"/.well-known/carddav"
|
|
|
|
"/.well-known/caldav"
|
|
|
|
];
|
|
|
|
}
|
|
|
|
];
|
|
|
|
handle = [
|
|
|
|
{
|
|
|
|
handler = "static_response";
|
|
|
|
headers = {
|
|
|
|
Location = [ "/remote.php/dav" ];
|
|
|
|
};
|
|
|
|
status_code = 301;
|
|
|
|
}
|
|
|
|
];
|
2023-07-30 03:51:01 +00:00
|
|
|
}
|
2024-04-20 13:42:06 +00:00
|
|
|
# Block traffic to sensitive files
|
|
|
|
{
|
|
|
|
match = [
|
|
|
|
{
|
|
|
|
path = [
|
|
|
|
"/.htaccess"
|
|
|
|
"/data/*"
|
|
|
|
"/config/*"
|
|
|
|
"/db_structure"
|
|
|
|
"/.xml"
|
|
|
|
"/README"
|
|
|
|
"/3rdparty/*"
|
|
|
|
"/lib/*"
|
|
|
|
"/templates/*"
|
|
|
|
"/occ"
|
|
|
|
"/console.php"
|
|
|
|
];
|
|
|
|
}
|
2023-07-30 03:51:01 +00:00
|
|
|
];
|
2024-04-20 13:42:06 +00:00
|
|
|
handle = [
|
|
|
|
{
|
|
|
|
handler = "static_response";
|
|
|
|
status_code = 404;
|
|
|
|
}
|
|
|
|
];
|
|
|
|
}
|
|
|
|
# Redirect index.php to the homepage
|
|
|
|
{
|
|
|
|
match = [
|
|
|
|
{
|
|
|
|
file = {
|
|
|
|
try_files = [ "{http.request.uri.path}/index.php" ];
|
|
|
|
};
|
|
|
|
not = [ { path = [ "*/" ]; } ];
|
|
|
|
}
|
|
|
|
];
|
|
|
|
handle = [
|
|
|
|
{
|
|
|
|
handler = "static_response";
|
|
|
|
headers = {
|
|
|
|
Location = [ "{http.request.orig_uri.path}/" ];
|
|
|
|
};
|
|
|
|
status_code = 308;
|
|
|
|
}
|
|
|
|
];
|
|
|
|
}
|
|
|
|
# Rewrite paths to be relative
|
|
|
|
{
|
|
|
|
match = [
|
|
|
|
{
|
|
|
|
file = {
|
|
|
|
split_path = [ ".php" ];
|
|
|
|
try_files = [
|
|
|
|
"{http.request.uri.path}"
|
|
|
|
"{http.request.uri.path}/index.php"
|
|
|
|
"index.php"
|
|
|
|
];
|
|
|
|
};
|
|
|
|
}
|
|
|
|
];
|
|
|
|
handle = [
|
|
|
|
{
|
|
|
|
handler = "rewrite";
|
|
|
|
uri = "{http.matchers.file.relative}";
|
|
|
|
}
|
|
|
|
];
|
|
|
|
}
|
|
|
|
# Send all PHP traffic to Nextcloud PHP service
|
|
|
|
{
|
|
|
|
match = [ { path = [ "*.php" ]; } ];
|
|
|
|
handle = [
|
|
|
|
{
|
|
|
|
handler = "reverse_proxy";
|
|
|
|
transport = {
|
|
|
|
protocol = "fastcgi";
|
|
|
|
split_path = [ ".php" ];
|
|
|
|
};
|
|
|
|
upstreams = [ { dial = "unix//run/phpfpm/nextcloud.sock"; } ];
|
|
|
|
}
|
|
|
|
];
|
|
|
|
}
|
|
|
|
# Finally, send the rest to the file server
|
|
|
|
{ handle = [ { handler = "file_server"; } ]; }
|
|
|
|
];
|
2023-07-30 03:51:01 +00:00
|
|
|
}
|
|
|
|
];
|
2024-04-20 13:42:06 +00:00
|
|
|
terminal = true;
|
|
|
|
}
|
|
|
|
];
|
2022-10-02 20:54:26 +00:00
|
|
|
|
2024-03-30 15:41:18 +00:00
|
|
|
# Configure Cloudflare DNS to point to this machine
|
|
|
|
services.cloudflare-dyndns.domains = [ config.hostnames.content ];
|
|
|
|
|
2022-10-08 15:52:05 +00:00
|
|
|
# Create credentials file for nextcloud
|
2022-10-16 03:18:58 +00:00
|
|
|
secrets.nextcloud = {
|
2023-03-01 04:54:48 +00:00
|
|
|
source = ../../../private/nextcloud.age;
|
2022-10-16 03:18:58 +00:00
|
|
|
dest = "${config.secretsDirectory}/nextcloud";
|
|
|
|
owner = "nextcloud";
|
|
|
|
group = "nextcloud";
|
|
|
|
permissions = "0440";
|
|
|
|
};
|
|
|
|
systemd.services.nextcloud-secret = {
|
2022-10-08 15:52:05 +00:00
|
|
|
requiredBy = [ "nextcloud-setup.service" ];
|
|
|
|
before = [ "nextcloud-setup.service" ];
|
|
|
|
};
|
|
|
|
|
2023-03-03 20:54:27 +00:00
|
|
|
# Grant user access to Nextcloud directories
|
|
|
|
users.users.${config.user}.extraGroups = [ "nextcloud" ];
|
|
|
|
|
2022-10-08 15:52:05 +00:00
|
|
|
# Open to groups, allowing for backups
|
2024-04-20 13:42:06 +00:00
|
|
|
systemd.services.phpfpm-nextcloud.serviceConfig.StateDirectoryMode = lib.mkForce "0770";
|
2022-10-08 15:52:05 +00:00
|
|
|
|
2023-07-16 01:04:52 +00:00
|
|
|
# Log metrics to prometheus
|
2023-07-30 03:51:01 +00:00
|
|
|
networking.hosts."127.0.0.1" = [ config.hostnames.content ];
|
2023-07-16 01:04:52 +00:00
|
|
|
services.prometheus.exporters.nextcloud = {
|
2023-07-16 13:50:58 +00:00
|
|
|
enable = config.prometheus.exporters.enable;
|
2023-07-16 01:04:52 +00:00
|
|
|
username = config.services.nextcloud.config.adminuser;
|
2023-07-30 03:51:01 +00:00
|
|
|
url = "https://${config.hostnames.content}";
|
2023-07-16 01:04:52 +00:00
|
|
|
passwordFile = config.services.nextcloud.config.adminpassFile;
|
|
|
|
};
|
2023-07-16 13:50:58 +00:00
|
|
|
prometheus.scrapeTargets = [
|
2024-04-20 13:42:06 +00:00
|
|
|
"127.0.0.1:${builtins.toString config.services.prometheus.exporters.nextcloud.port}"
|
2023-07-16 01:04:52 +00:00
|
|
|
];
|
|
|
|
# Allows nextcloud-exporter to read passwordFile
|
2023-07-16 13:50:58 +00:00
|
|
|
users.users.nextcloud-exporter.extraGroups =
|
|
|
|
lib.mkIf config.services.prometheus.exporters.nextcloud.enable
|
2024-04-20 13:42:06 +00:00
|
|
|
[ "nextcloud" ];
|
2022-10-02 20:54:26 +00:00
|
|
|
};
|
|
|
|
}
|