{ pkgs, config, ... }: let hostAddress = "192.168.100.10"; containerAddress = "192.168.100.11"; #syncthingGid = config.users.groups.syncthing.gid; in { containers.nextcloud = { # mount host folders bindMounts = { rootpassword = { hostPath = toString ; mountPoint = toString ; isReadOnly = true; }; databasepassword = { hostPath = toString ; mountPoint = toString ; isReadOnly = true; }; home = { # make sure this folder exist on the host hostPath = toString "/home/nextcloud"; mountPoint = "/var/lib/nextcloud"; isReadOnly = false; }; db = { # make sure this folder exist on the host hostPath = toString "/home/nextcloud_db"; mountPoint = "/var/lib/mysql"; isReadOnly = false; }; krops-lib = { mountPoint = toString ; hostPath = toString ; isReadOnly = true; }; modules = { mountPoint = toString ; hostPath = toString ; isReadOnly = true; }; # shared folders samples = { mountPoint = toString config.services.syncthing.declarative.folders.samples.path; hostPath = toString config.services.syncthing.declarative.folders.samples.path; isReadOnly = true; }; movies = { mountPoint = toString config.services.syncthing.declarative.folders.movies.path; hostPath = toString config.services.syncthing.declarative.folders.movies.path; isReadOnly = true; }; music = { mountPoint = toString config.services.syncthing.declarative.folders.music-library.path; hostPath = toString config.services.syncthing.declarative.folders.music-library.path; isReadOnly = true; }; series = { mountPoint = toString config.services.syncthing.declarative.folders.series.path; hostPath = toString config.services.syncthing.declarative.folders.series.path; isReadOnly = true; }; }; # container network setup # see also nating on host system. privateNetwork = true; hostAddress = hostAddress; localAddress = containerAddress; autoStart = true; config = { config, pkgs, lib, ... }: { imports = [ ]; services.nginx = { # Use recommended settings recommendedGzipSettings = lib.mkDefault true; recommendedOptimisation = lib.mkDefault true; recommendedProxySettings = lib.mkDefault true; recommendedTlsSettings = lib.mkDefault true; # for graylog logging commonHttpConfig = let access_log_sink = "${hostAddress}:12304"; error_log_sink = "${hostAddress}:12305"; in '' log_format graylog2_json escape=json '{ "timestamp": "$time_iso8601", ' '"facility": "nginx", ' '"src_addr": "$remote_addr", ' '"body_bytes_sent": $body_bytes_sent, ' '"request_time": $request_time, ' '"response_status": $status, ' '"request": "$request", ' '"request_method": "$request_method", ' '"host": "$host",' '"upstream_cache_status": "$upstream_cache_status",' '"upstream_addr": "$upstream_addr",' '"http_x_forwarded_for": "$http_x_forwarded_for",' '"http_referrer": "$http_referer", ' '"http_user_agent": "$http_user_agent" }'; access_log syslog:server=${access_log_sink} graylog2_json; error_log syslog:server=${error_log_sink}; ''; }; # don't forget the database backup before doing this # https://docs.nextcloud.com/server/stable/admin_manual/maintenance/backup.html # https://docs.nextcloud.com/server/stable/admin_manual/maintenance/upgrade.html # use snapshots in case of a rollback #nixpkgs.config.packageOverrides = super: { # nextcloud = super.nextcloud.overrideAttrs (old: rec { # name = "nextcloud-${version}"; # version = "18.0.1"; # src = super.fetchurl { # url = # "https://download.nextcloud.com/server/releases/nextcloud-18.0.1.tar.bz2"; # sha256 = "1h0rxpdssn1hc65k41zbvww9r4f79vbd9bixc9ri5n7hp0say3vp"; # }; # }); #}; 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; }; }; # 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; # nextcloud setup services.nextcloud = { enable = true; package = pkgs.nextcloud21; #package = pkgs.nextcloud.overrideAttrs (old: rec { # name = "nextcloud-${version}"; # version = "18.0.1"; # src = pkgs.fetchurl { # url = # "https://download.nextcloud.com/server/releases/nextcloud-18.0.1.tar.bz2"; # sha256 = "1h0rxpdssn1hc65k41zbvww9r4f79vbd9bixc9ri5n7hp0say3vp"; # }; #}); autoUpdateApps.enable = true; #nginx.enable = true; hostName = "nextcloud.ingolf-wagner.de"; #logLevel = 0; https = true; config = { adminpassFile = toString config.krops.userKeys."nextcloud_root".target; overwriteProtocol = "https"; trustedProxies = [ "195.201.134.247" hostAddress ]; dbtype = "mysql"; dbpassFile = toString config.krops.userKeys."nextcloud_database".target; dbport = 3306; }; }; # provide password file for database with proper rights krops.userKeys."nextcloud_database" = { user = "nextcloud"; source = toString ; requiredBy = [ "nginx.service" "nextcloud-setup.service" ]; }; krops.userKeys."nextcloud_root" = { user = "nextcloud"; source = toString ; requiredBy = [ "nginx.service" "nextcloud-setup.service" ]; }; environment.systemPackages = [ pkgs.smbclient ]; # send log to host systems graylog (use tinc or wireguard if host is not graylog) services.SystemdJournal2Gelf.enable = true; services.SystemdJournal2Gelf.graylogServer = "${hostAddress}:11201"; }; }; # give containers internet access networking.nat.enable = true; networking.nat.internalInterfaces = [ "ve-nextcloud" ]; networking.nat.externalInterface = "enp2s0f1"; # don't let networkmanager manger container network networking.networkmanager.unmanaged = [ "interface-name:ve-*" ]; # open ports for logging networking.firewall.interfaces."ve-nextcloud".allowedTCPPorts = [ 11201 12304 12305 ]; networking.firewall.interfaces."ve-nextcloud".allowedUDPPorts = [ 11201 12304 12305 ]; # host nginx setup services.nginx = { enable = true; recommendedProxySettings = true; virtualHosts = { "nextcloud.workhorse.private" = { serverAliases = [ "nextcloud.ingolf-wagner.de" ]; locations."/" = { proxyPass = "http://${containerAddress}"; extraConfig = '' # allow big uploads # ----------------- client_max_body_size 0; ''; }; }; }; }; # Backup Config # ------------- backup.dirs = [ "/home/nextcloud/config" "/home/nextcloud/database_backups" # created by mysqlBackup ]; # Backup Files # ------------ services.borgbackup.jobs = { "nextcloud-to-media" = { repo = "/media/syncthing/borg/nextcloud"; # make sure syncthing is capable of reading the files postHook = '' chown -R syncthing:syncthing /media/syncthing/borg ''; compression = "lz4"; paths = [ "/home/nextcloud/data/tina/files/Documents" "/home/nextcloud/data/tina/files/Pictures" "/home/nextcloud/data/tina/files/Joplin" "/home/nextcloud/data/tina/files/SofortUpload" "/home/nextcloud/data/palo/files/Joplin" "/home/nextcloud/data/palo/files/InstantUpload" "/home/nextcloud/data/palo-windows/files/Kunstbuch" ]; doInit = true; encryption = { mode = "repokey-blake2"; passCommand = "cat ${toString }"; }; 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. }; }; }; }