nixos-config/nixos/configs/workhorse/nextcloud.nix

363 lines
12 KiB
Nix

{ 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 <secrets/nextcloud/root_password>;
mountPoint =
"/run/secrets/nextcloud_root_password";
#toString <secrets/nextcloud/root_password>;
isReadOnly = true;
};
databasepassword = {
hostPath =
"/run/secrets/nextcloud_database_password";
#toString <secrets/nextcloud/database_password>;
mountPoint =
"/run/secrets/nextcloud_database_password";
#toString <secrets/nextcloud/database_password>;
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.
};
};
};
}