nixos-config/nixos/machines/robi/nextcloud.nix
2023-03-12 17:50:01 +01:00

293 lines
9.1 KiB
Nix

{ pkgs, config, ... }:
# don't forget the database backup before upgrading
# -------------------------------------------------
# https://docs.nextcloud.com/server/stable/admin_manual/maintenance/backup.html
# https://docs.nextcloud.com/server/stable/admin_manual/maintenance/upgrade.html
#
# ! use lvm snapshots to do rollback !
let
hostInterface = "enp3s0";
hostAddress = "192.168.100.10";
containerAddress = "192.168.100.11";
nextcloudUid = 1000;
borg_backup_folder = "/media/syncthing/nextcloud_backup/robi";
in
{
# Host Setup
# ==========
# give containers internet access
networking.nat.enable = true;
networking.nat.internalInterfaces = [ "ve-nextcloud" ];
networking.nat.externalInterface = hostInterface;
# don't let networkmanager manger container network
networking.networkmanager.unmanaged = [ "interface-name:ve-*" ];
# open ports for logging
#networking.firewall.interfaces."ve-nextcloud".allowedTCPPorts =
# [ 5044 12304 12305 ];
#networking.firewall.interfaces."ve-nextcloud".allowedUDPPorts =
# [ 5044 12304 12305 ];
# host nginx
# ----------
networking.firewall.allowedTCPPorts = [ 80 443 ];
networking.firewall.allowedUDPPorts = [ 80 443 ];
services.nginx = {
enable = true;
recommendedProxySettings = true;
virtualHosts = {
"nextcloud.ingolf-wagner.de" = {
forceSSL = true;
enableACME = true;
locations = {
"/" = {
proxyPass = "http://${containerAddress}";
extraConfig = ''
sub_filter "http://nextcloud.ingolf-wagner.de" "https://nextcloud.ingolf-wagner.de";
# used for view/edit office file via Office Online Server
client_max_body_size 0;
proxy_buffering off; # to download files bigger than 1GB
'';
};
"= /.well-known/carddav" = {
priority = 210;
extraConfig = "return 301 $scheme://$host/remote.php/dav;";
};
"= /.well-known/caldav" = {
priority = 210;
extraConfig = "return 301 $scheme://$host/remote.php/dav;";
};
#"~ .(?:css|js|svg|gif)$" = {
# proxyPass = "http://${containerAddress}$request_uri";
# extraConfig = ''
# expires 6M; # Cache-Control policy borrowed from `.htaccess`
# access_log off; # Optional: Don't log access to assets
# sub_filter "http://nextcloud.ingolf-wagner.de" "https://nextcloud.ingolf-wagner.de";
# sub_filter "nextcloud.workhorse.private" "nextcloud.ingolf-wagner.de";
# # used for view/edit office file via Office Online Server
# client_max_body_size 0;
# '';
#};
#"~ .woff2?$" = {
# proxyPass = "http://${containerAddress}$request_uri";
# extraConfig = ''
# expires 7d; # Cache-Control policy borrowed from `.htaccess`
# access_log off; # Optional: Don't log access to assets
# sub_filter "http://nextcloud.ingolf-wagner.de" "https://nextcloud.ingolf-wagner.de";
# sub_filter "nextcloud.workhorse.private" "nextcloud.ingolf-wagner.de";
# # used for view/edit office file via Office Online Server
# client_max_body_size 0;
# '';
#};
};
};
};
};
sops.secrets.nextcloud_database_password.owner = "nextcloud";
sops.secrets.nextcloud_root_password.owner = "nextcloud";
users.users.nextcloud = {
isSystemUser = true;
uid = nextcloudUid;
group = "nextcloud";
};
users.groups.nextcloud = { };
# Container Setup
# ===============
#
# running:
# * nextcloud (php)
# * mysql
containers.nextcloud = {
# mount host folders
bindMounts = {
rootpassword = {
hostPath = "/run/secrets/nextcloud_root_password";
mountPoint = "/run/secrets/nextcloud_root_password";
isReadOnly = true;
};
databasepassword = {
hostPath = "/run/secrets/nextcloud_database_password";
mountPoint = "/run/secrets/nextcloud_database_password";
isReadOnly = true;
};
home = {
# make sure this folder exist on the host
hostPath = toString "/var/lib/nextcloud";
mountPoint = "/var/lib/nextcloud";
isReadOnly = false;
};
db = {
# make sure this folder exist on the host
hostPath = toString "/var/lib/nextcloud_mysql";
mountPoint = "/var/lib/mysql";
isReadOnly = false;
};
media = {
mountPoint = toString config.services.syncthing.folders.media.path;
hostPath = toString config.services.syncthing.folders.media.path;
isReadOnly = true;
};
};
# container network setup
# see also nating on host system.
privateNetwork = true;
hostAddress = hostAddress;
localAddress = containerAddress;
autoStart = true;
config = { config, pkgs, lib, ... }: {
system.stateVersion = "21.05";
users.users.nextcloud.uid = nextcloudUid;
services.nginx = {
# Use recommended settings
recommendedGzipSettings = lib.mkDefault true;
recommendedOptimisation = lib.mkDefault true;
recommendedProxySettings = lib.mkDefault true;
recommendedTlsSettings = lib.mkDefault true;
};
networking.firewall.allowedTCPPorts = [ 80 ];
networking.firewall.allowedUDPPorts = [ 80 ];
# nextcloud database
# ==================
#
# set user password:
# -----------------
# #> mysql
# mysql> ALTER USER 'nextcloud'@'localhost' IDENTIFIED BY 'nextcloud-password';
#
# recreate database:
# ------------------
# mysql> DROP DATABASE nextcloud;
# mysql> CREATE DATABASE nextcloud;
#
# migration:
# ----------
# nextcloud-occ db:convert-type --all-apps mysql nextcloud 127.0.0.1 nextcloud
#
# 4-byte stuff:
# -------------
# https://docs.nextcloud.com/server/18/admin_manual/configuration_database/mysql_4byte_support.html
# if you do this don't forget --default-character-set=utf8mb4 for mysqldump
services.mysql = {
enable = true;
package = pkgs.mysql;
# https://nixos.org/manual/nixos/stable/release-notes.html#sec-release-20.09-incompatibilities
ensureDatabases = [ "nextcloud" ];
ensureUsers = [{
name = "nextcloud";
ensurePermissions = { "nextcloud.*" = "ALL PRIVILEGES"; };
}];
settings.mysqld = {
innodb_large_prefix = true;
innodb_file_format = "barracuda";
innodb_file_per_table = 1;
innodb_read_only_compressed = 0;
};
};
# Backup database
# ---------------
services.mysqlBackup = {
enable = true;
databases = config.services.mysql.ensureDatabases;
singleTransaction = true;
location = "/var/lib/nextcloud/database_backups";
};
systemd.services."mysql-backup".serviceConfig = {
ExecStartPre = [ "+/run/current-system/sw/bin/nextcloud-occ maintenance:mode --on" ];
ExecStopPost = [ "+/run/current-system/sw/bin/nextcloud-occ maintenance:mode --off" ];
};
# in php
services.phpfpm = {
phpPackage = pkgs.php73;
phpOptions = ''
opcache.revalidate_freq = 10
'';
};
# nextcloud setup
services.nextcloud = {
enable = true;
package = pkgs.nextcloud25;
autoUpdateApps.enable = true;
#nginx.enable = true;
enableBrokenCiphersForSSE = false; # see https://github.com/NixOS/nixpkgs/pull/198470
hostName = "nextcloud.ingolf-wagner.de";
logLevel = 2;
https = true;
config = {
adminpassFile = "/run/secrets/nextcloud_root_password";
overwriteProtocol = "https";
trustedProxies = [ "144.76.13.147" hostAddress ];
dbtype = "mysql";
dbpassFile = "/run/secrets/nextcloud_database_password";
dbport = 3306;
defaultPhoneRegion = "DE";
};
};
};
};
# Backup Config
# -------------
#backup.dirs = [
# "/home/nextcloud/config"
# "/home/nextcloud/database_backups" # created by mysqlBackup
#];
# Backup Files
# ------------
services.borgbackup.jobs = {
"nextcloud-to-media" = {
repo = borg_backup_folder;
# make sure syncthing is capable of reading the files
postHook = ''
chown -R syncthing:syncthing ${borg_backup_folder}
'';
compression = "lz4";
paths = [
"/var/lib/nextcloud/data/tina/files"
"/var/lib/nextcloud/data/palo/files"
"/var/lib/nextcloud/data/palo-windows/files"
];
doInit = true;
encryption = {
mode = "repokey-blake2";
passCommand = "cat ${config.sops.secrets.backup_repository_passphrase.path}";
};
startAt = "0/3:00:00";
prune.keep = {
within = "2d"; # Keep all backups in the last 10 days.
daily = 10; # Keep 10 additional end of day archives
weekly = 8; # Keep 8 additional end of week archives.
month = 8; # Keep 8 additional end of month archives.
};
};
};
}