From 8e0775d85cda2f7759e0bcc2aba19845e7198557 Mon Sep 17 00:00:00 2001 From: Ingolf Wagner Date: Thu, 30 Dec 2021 23:08:31 +0100 Subject: [PATCH] setup nextcloud --- nixos/configs/robi/hetzner.nix | 1 + nixos/configs/robi/nextcloud.nix | 346 +++++++++++++++++++------------ 2 files changed, 218 insertions(+), 129 deletions(-) diff --git a/nixos/configs/robi/hetzner.nix b/nixos/configs/robi/hetzner.nix index 6c15294..a57c447 100644 --- a/nixos/configs/robi/hetzner.nix +++ b/nixos/configs/robi/hetzner.nix @@ -88,6 +88,7 @@ in # Initial empty root password for easy login: users.users.root.initialHashedPassword = ""; services.openssh.permitRootLogin = "prohibit-password"; + services.openssh.passwordAuthentication = false; users.users.root.openssh.authorizedKeys.keys = [ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC6uza62+Go9sBFs3XZE2OkugBv9PJ7Yv8ebCskE5WYPcahMZIKkQw+zkGI8EGzOPJhQEv2xk+XBf2VOzj0Fto4nh8X5+Llb1nM+YxQPk1SVlwbNAlhh24L1w2vKtBtMy277MF4EP+caGceYP6gki5+DzlPUSdFSAEFFWgN1WPkiyUii15Xi3QuCMR8F18dbwVUYbT11vwNhdiAXWphrQG+yPguALBGR+21JM6fffOln3BhoDUp2poVc5Qe2EBuUbRUV3/fOU4HwWVKZ7KCFvLZBSVFutXCj5HuNWJ5T3RuuxJSmY5lYuFZx9gD+n+DAEJt30iXWcaJlmUqQB5awcB1S2d9pJ141V4vjiCMKUJHIdspFrI23rFNYD9k2ZXDA8VOnQE33BzmgF9xOVh6qr4G0oEpsNqJoKybVTUeSyl4+ifzdQANouvySgLJV/pcqaxX1srSDIUlcM2vDMWAs3ryCa0aAlmAVZIHgRhh6wa+IXW8gIYt+5biPWUuihJ4zGBEwkyVXXf2xsecMWCAGPWPDL0/fBfY9krNfC5M2sqxey2ShFIq+R/wMdaI7yVjUCF2QIUNiIdFbJL6bDrDyHnEXJJN+rAo23jUoTZZRv7Jq3DB/A5H7a73VCcblZyUmwMSlpg3wos7pdw5Ctta3zQPoxoAKGS1uZ+yTeZbPMmdbw==" diff --git a/nixos/configs/robi/nextcloud.nix b/nixos/configs/robi/nextcloud.nix index 37c27ce..5a9e8f2 100644 --- a/nixos/configs/robi/nextcloud.nix +++ b/nixos/configs/robi/nextcloud.nix @@ -1,64 +1,206 @@ -{ pkgs, config, lib, ... }: +{ 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; + 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; + ''; + }; + "= /.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; }; - #networking.firewall.allowedTCPPorts = [ 80 443 ]; - #networking.firewall.allowedUDPPorts = [ 80 443 ]; - # host nginx setup - services.nginx = { - enable = true; - recommendedGzipSettings = lib.mkDefault true; - recommendedOptimisation = lib.mkDefault true; - recommendedTlsSettings = lib.mkDefault true; - recommendedProxySettings = true; - #sslCiphers = "AES256+EECDH:AES256+EDH:!aNULL"; + # Container Setup + # =============== + # + # running: + # * nextcloud (php) + # * mysql + containers.nextcloud = { - #virtualHosts = { - # "nextcloud.ingolf-wagner.de" = { - # forceSSL = true; - # enableACME = true; - # }; - #}; - }; + # 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; + }; + 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; - # 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 - containers.nextcloudmysql = { autoStart = true; - forwardPorts = [{ - containerPort = 3336; - hostPort = 3336; - protocol = "tcp"; - }]; 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; + }; + + + 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; @@ -77,96 +219,42 @@ in # Backup database # --------------- - #services.mysqlBackup = { - # enable = true; - # databases = config.services.mysql.ensureDatabases; - # singleTransaction = true; - # location = "/var/lib/nextcloud/database_backups"; - #}; + 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" ]; + }; - #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; + autoUpdateApps.enable = true; + #nginx.enable = true; + 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; + }; + }; }; }; - - # in php - services.phpfpm.phpPackage = pkgs.php73; - - # nextcloud setup - services.nextcloud = { - enable = false; - hostName = "nextcloud.ingolf-wagner.de"; - package = pkgs.nextcloud22; - autoUpdateApps.enable = true; - autoUpdateApps.startAt = "05:00:00"; - logLevel = 2; - https = true; - config = { - adminpassFile = config.sops.secrets.nextcloud_root_password.path; - overwriteProtocol = "https"; - dbtype = "mysql"; - dbpassFile = config.sops.secrets.nextcloud_database_password.path; - dbport = 3306; - }; - }; - - sops.secrets.nextcloud_database_password.owner = "nextcloud"; - sops.secrets.nextcloud_root_password.owner = "nextcloud"; - - - #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 ]; - - # Backup Config # ------------- #backup.dirs = [