{ pkgs, config, ... }: let hostAddress = "192.168.100.10"; containerAddress = "192.168.100.11"; #syncthingGid = config.users.groups.syncthing.gid; nextcloudUid = 1000; in { sops.secrets.nextcloud_database_password = { owner = "nextcloud"; }; sops.secrets.nextcloud_root_password = { owner = "nextcloud"; }; users.users.nextcloud = { isSystemUser = true; uid = nextcloudUid; }; containers.nextcloud = { # mount host folders bindMounts = { rootpassword = { hostPath = "/run/secrets/nextcloud_root_password"; #toString ; mountPoint = "/run/secrets/nextcloud_root_password"; #toString ; isReadOnly = true; }; databasepassword = { hostPath = "/run/secrets/nextcloud_database_password"; #toString ; mountPoint = "/run/secrets/nextcloud_database_password"; #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; }; 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, ... }: { 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; # 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.nextcloud22; #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 = 2; https = true; config = { adminpassFile = #config.sops.secrets.nextcloud_root_password.path; "/run/secrets/nextcloud_root_password"; overwriteProtocol = "https"; trustedProxies = [ "195.201.134.247" hostAddress ]; dbtype = "mysql"; dbpassFile = #config.sops.secrets.nextcloud_database_password.path; "/run/secrets/nextcloud_database_password"; dbport = 3306; }; }; #sops.secrets.nextcloud_database_password = {}; #sops.secrets.nextcloud_root_password = {}; environment.systemPackages = [ pkgs.smbclient ]; services.journalbeat = { enable = true; extraConfig = '' journalbeat.inputs: - paths: [] # Position to start reading from journal. Valid values: head, tail, cursor seek: cursor # Fallback position if no cursor data is available. cursor_seek_fallback: tail output.logstash: # Boolean flag to enable or disable the output module. enabled: true # Graylog host and the beats input hosts: ["${hostAddress}:5044"] # If enabled only a subset of events in a batch of events is transferred per # transaction. The number of events to be sent increases up to `bulk_max_size` # if no error is encountered. slow_start: true # The number of seconds to wait before trying to reconnect to Graylog # after a network error. After waiting backoff.init seconds, the Beat # tries to reconnect. If the attempt fails, the backoff timer is increased # exponentially up to backoff.max. After a successful connection, the backoff # timer is reset. The default is 1s. backoff.init: 1s # The maximum number of seconds to wait before attempting to connect to # Graylog after a network error. The default is 60s. backoff.max: 60s ''; }; }; }; # 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 = [ 5044 12304 12305 ]; networking.firewall.interfaces."ve-nextcloud".allowedUDPPorts = [ 5044 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/nextcloud ''; 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/InstantUpload" "/home/nextcloud/data/palo/files/Joplin" "/home/nextcloud/data/palo/files/Pictures" "/home/nextcloud/data/palo/files/Unterlagen" "/home/nextcloud/data/palo/files/Video" "/home/nextcloud/data/palo-windows/files/Kunstbuch" ]; 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. }; }; }; }