feat: harbor

This commit is contained in:
2026-03-28 15:21:17 +01:00
parent cf289c8c48
commit fc166785ee
12 changed files with 809 additions and 1 deletions

View File

@@ -44,6 +44,7 @@
inputs.home-manager.flakeModules.home-manager
./hosts/comfy-station
./hosts/monolith
./hosts/harbor
(./home + "/jonas@comfy-station")
(./home + "/jonas@monolith")
(import-tree ./modules)

View File

@@ -0,0 +1,150 @@
{
config,
pkgs,
...
}: {
imports = [
./hardware-configuration.nix
./disko.nix
];
# Secret management
sops.age.keyFile = "/var/lib/sops-nix/key.txt";
sops.secrets."nextcloud-admin-pass" = {
sopsFile = ../../secrets/harbor/nextcloud.yaml;
owner = "nextcloud";
key = "admin-pass";
};
sops.secrets."wg-priv" = {
sopsFile = ../../secrets/harbor/wg.yaml;
key = "privateKey";
};
sops.secrets."gitea-db-pass" = {
sopsFile = ../../secrets/harbor/gitea.yaml;
owner = config.services.gitea.user;
key = "databasePassword";
};
sops.secrets."gotify-admin-pass" = {
sopsFile = ../../secrets/harbor/gotify.yaml;
owner = config.hive.gotify-instance.user;
key = "adminPassword";
};
# gc settings and binary caches
nix = {
settings = {
substituters = [
"https://aseipp-nix-cache.freetls.fastly.net"
"https://nix-community.cachix.org"
"https://cache.nixos.org/"
];
experimental-features = ["nix-command" "flakes"];
auto-optimise-store = true;
};
gc = {
automatic = true;
dates = "weekly";
options = "--delete-older-than 30d";
};
};
# user with ssh access
users.users.jonas = {
isNormalUser = true;
description = "Jonas";
extraGroups = ["wheel"];
openssh.authorizedKeys.keys = [
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCyCyYsMSiy7shcehlzJEbCyRiHk+cicFB35Bc2uc4PjjkCjswLh01fRAV2QcplrNkH/5F4GBTbOoZHHc7/AVLyUxgwDC9ffD2i7fevuGpfBFy9D30uz6jDekxXkmRmIlidXLdG1Fh4zwVejGlwdhUu/Zb7PonO/dktx3EFdf1SpnW+y75anN85zoGsld7KQk42wEd0zXtCgx4CKI6Vvt6heWCEiJ9wyw1sLpTJr4H8In236CUj1/r1qY9Gfa8n9NA0J9XCpcwSCEWGRKQNicoQIpnp5txrgzaUq4r6qBKHmImYXmSTVnDZ9dJLRYNu2lDvBtTXP4ztlR6Lpxs873fPg51qgaX9rRVMMo/gGjq8fOFWsDVaJZab9VY3hZYNCKIbWFqo4GKyCQs9Xfzr2AUACm09HWiYMTefwEypOzvUb4z+LF2B/0c5XmghLF/TOzLVgDXzAgWMH4mCnPh9EDLHTtoJaGNURler9VRV8yQyLH6oK9UpHZovCFs7HpFN+WPv2QVFfkK8aHg7tnklFsT78z154bjuspiEI/fFGmTxoQUGufmHlRy/9GQDusgNfe24ZEB2hHBVjKv29XdIfvFAhoPVpA6+O/N3feSlmVISaU+8QraVQEf/TuQjopDUWpJTmqSxKvQSTPwcyWDy6NtcJ85bGAu6jSUGC3ouH4Rb2Q== cardno:000609618602"
];
};
users.defaultUserShell = pkgs.zsh;
programs.zsh.enable = true;
services.openssh = {
enable = true;
settings.PasswordAuthentication = false;
settings.KbdInteractiveAuthentication = false;
};
# hive modules
hive.gitea-instance.enable = true;
hive.gitea-instance.nativeRunner = true;
hive.gitea-instance.instanceFQDN = "git.jroeger.de";
hive.gitea-instance.databasePasswordFile = config.sops.secrets.gitea-db-pass.path;
hive.gotify-instance.enable = true;
hive.gotify-instance.instanceFQDN = "gotify.jroeger.de";
hive.gotify-instance.adminPasswordSopsKey = config.sops.secrets.gotify-admin-pass.name;
hive.nextcloud-instance.enable = true;
hive.nextcloud-instance.ssl = true;
hive.nextcloud-instance.adminPasswordFile = config.sops.secrets.nextcloud-admin-pass.path;
hive.nextcloud-instance.instanceFQDN = "nextcloud.jroeger.de";
hive.minecraft-server.enable = true;
hive.borg-server.enable = true;
hive.borg-server.repositories.comfy-station.ssh_public_key = builtins.readFile (../../static/keys + "/borg-jonas@comfy-station.pub");
hive.wg.server.enable = true;
hive.wg.server.privateKeyFile = config.sops.secrets.wg-priv.path;
# This value determines the NixOS release from which the default
# settings for stateful data, like file locations and database versions
# on your system were taken. Its perfectly fine and recommended to leave
# this value at the release version of the first install of this system.
# Before changing this value read the documentation for this option
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
system.stateVersion = "25.11"; # Did you read the comment?
# VPS compat
boot.loader.grub.enable = true;
boot.loader.grub.device = "/dev/sda";
boot.loader.grub.version = 2;
boot.kernelParams = [
"net.ifnames=0" # ensure iface is called eth0
"ip=173.249.42.252::173.249.42.1:255.255.255.0:harbor:eth0:none:8.8.8.8"
];
networking.networkmanager.enable = true;
networking = {
# Static network configuration
hostName = "harbor";
domain = "jroeger.de";
defaultGateway = "173.249.42.1";
nameservers = ["8.8.8.8"];
interfaces.eth0.ipv4.addresses = [
{
address = "173.249.42.252";
prefixLength = 24;
}
];
};
# Temporary ssh server for disk unlock
boot.initrd = {
availableKernelModules = ["virtio_pci"];
network = {
enable = true;
ssh = {
enable = true;
port = 2222;
authorizedKeys = [
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCyCyYsMSiy7shcehlzJEbCyRiHk+cicFB35Bc2uc4PjjkCjswLh01fRAV2QcplrNkH/5F4GBTbOoZHHc7/AVLyUxgwDC9ffD2i7fevuGpfBFy9D30uz6jDekxXkmRmIlidXLdG1Fh4zwVejGlwdhUu/Zb7PonO/dktx3EFdf1SpnW+y75anN85zoGsld7KQk42wEd0zXtCgx4CKI6Vvt6heWCEiJ9wyw1sLpTJr4H8In236CUj1/r1qY9Gfa8n9NA0J9XCpcwSCEWGRKQNicoQIpnp5txrgzaUq4r6qBKHmImYXmSTVnDZ9dJLRYNu2lDvBtTXP4ztlR6Lpxs873fPg51qgaX9rRVMMo/gGjq8fOFWsDVaJZab9VY3hZYNCKIbWFqo4GKyCQs9Xfzr2AUACm09HWiYMTefwEypOzvUb4z+LF2B/0c5XmghLF/TOzLVgDXzAgWMH4mCnPh9EDLHTtoJaGNURler9VRV8yQyLH6oK9UpHZovCFs7HpFN+WPv2QVFfkK8aHg7tnklFsT78z154bjuspiEI/fFGmTxoQUGufmHlRy/9GQDusgNfe24ZEB2hHBVjKv29XdIfvFAhoPVpA6+O/N3feSlmVISaU+8QraVQEf/TuQjopDUWpJTmqSxKvQSTPwcyWDy6NtcJ85bGAu6jSUGC3ouH4Rb2Q== cardno:000609618602"
];
hostKeys = ["/etc/secrets/initrd/ssh_host_rsa_key"];
shell = "/bin/cryptsetup-askpass";
};
};
};
# Set your time zone.
time.timeZone = "Europe/Berlin";
# Select internationalisation properties.
i18n.defaultLocale = "en_US.UTF-8";
i18n.extraLocaleSettings = {
LC_ADDRESS = "de_DE.UTF-8";
LC_IDENTIFICATION = "de_DE.UTF-8";
LC_MEASUREMENT = "de_DE.UTF-8";
LC_MONETARY = "de_DE.UTF-8";
LC_NAME = "de_DE.UTF-8";
LC_NUMERIC = "de_DE.UTF-8";
LC_PAPER = "de_DE.UTF-8";
LC_TELEPHONE = "de_DE.UTF-8";
LC_TIME = "de_DE.UTF-8";
};
console.keyMap = "de";
}

25
hosts/harbor/default.nix Normal file
View File

@@ -0,0 +1,25 @@
{
inputs,
self,
...
}: {
flake.nixosConfigurations.harbor = inputs.nixpkgs.lib.nixosSystem {
modules = [
({...}: {
nixpkgs.config.allowUnfree = true;
})
./configuration.nix
inputs.sops-nix.nixosModules.sops
inputs.disko.nixosModules.disko
self.nixosModules.nix-scripts
self.nixosModules.gitea-instance
self.nixosModules.gotify-instance
self.nixosModules.nextcloud-instance
self.nixosModules.minecraft-server
self.nixosModules.borg-server
self.nixosModules.wireguard-server
];
};
}

71
hosts/harbor/disko.nix Normal file
View File

@@ -0,0 +1,71 @@
let
btrfsopt = [
"compress=zstd"
"noatime"
"ssd"
"space_cache=v2"
"user_subvol_rm_allowed"
];
in {
disko.devices = {
disk = {
main = {
type = "disk";
device = "/dev/sda";
content = {
type = "gpt";
partitions = {
boot = {
name = "boot";
size = "1M";
type = "ef02";
};
esp = {
name = "esp";
size = "500M";
type = "ef00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
};
};
luks = {
size = "100%";
content = {
type = "luks";
name = "nixos";
passwordFile = "/tmp/pass";
additionalKeyFiles = ["/nixos-enc.key"];
extraFormatArgs = [
"--type luks1"
"--iter-time 3000"
];
settings = {
allowDiscards = true;
};
content = {
type = "btrfs";
subvolumes = {
"@root" = {
mountpoint = "/";
mountOptions = btrfsopt;
};
"@home" = {
mountpoint = "/home";
mountOptions = btrfsopt;
};
"@nix" = {
mountpoint = "/nix";
mountOptions = btrfsopt;
};
};
};
};
};
};
};
};
};
};
}

View File

@@ -0,0 +1,21 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{
config,
lib,
pkgs,
modulesPath,
...
}: {
imports = [
(modulesPath + "/profiles/qemu-guest.nix")
];
boot.initrd.availableKernelModules = ["ata_piix" "uhci_hcd" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod"];
boot.initrd.kernelModules = [];
boot.kernelModules = [];
boot.extraModulePackages = [];
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
}

View File

@@ -9,6 +9,7 @@
peers = import ./peers.nix {inherit lib;};
in {
options.hive.wg.server = {
enable = lib.mkEnableOption "Enable WireGuard server";
port = lib.mkOption {
type = lib.types.port;
default = 51820;
@@ -20,7 +21,7 @@
};
};
config = {
config = lib.mkIf cfg.enable {
# Firewall rule
networking.firewall.allowedUDPPorts = [cfg.port];

View File

@@ -0,0 +1,63 @@
{
flake.nixosModules.borg-server = {
lib,
config,
pkgs,
...
}: let
cfg = config.hive.borg-server;
in {
options.hive.borg-server = {
enable = lib.mkEnableOption "Enable the borg server";
package = lib.mkOption {
type = lib.types.package;
default = pkgs.borgbackup;
example = "pkgs.borgbackup";
description = "The borg package to use";
};
borg_user = lib.mkOption {
type = lib.types.str;
example = "borg";
default = "borg";
description = "The user for the borg repository home.";
};
repositories_path = lib.mkOption {
type = lib.types.path;
example = "/var/lib/borg-repositories";
default = "/var/lib/borg-repositories";
description = "The user for the borg repository home.";
};
repositories = lib.mkOption {
type = lib.types.attrsOf (lib.types.submodule {
options = {
name = lib.mkOption {
type = lib.types.nullOr (lib.types.strMatching "^[a-zA-Z0-9._-]+$");
default = null;
example = "borg-repo";
description = "The name of the borg repository. If null, use key of attrset";
};
ssh_public_key = lib.mkOption {
type = lib.types.singleLineStr;
example = "ssh-rsa AAAA...";
description = "The path to the public key for the borg repository.";
};
};
});
};
};
config = lib.mkIf cfg.enable {
users.users.${cfg.borg_user} = {
isNormalUser = true;
description = "Borg user";
home = cfg.repositories_path;
createHome = true;
extraGroups = ["borg"];
openssh.authorizedKeys.keys =
lib.attrsets.mapAttrsToList
(key: repo: "command=\"${cfg.package}/bin/borg serve --restrict-to-path=${cfg.repositories_path}/${lib.defaultTo key repo.name}\",restrict ${repo.ssh_public_key}")
cfg.repositories;
};
};
};
}

View File

@@ -0,0 +1,125 @@
{
flake.nixosModules.gitea-instance = {
config,
lib,
...
}: let
cfg = config.hive.gitea-instance;
in {
options.hive.gitea-instance = {
enable = lib.mkEnableOption "Enable the Gitea instance";
instanceFQDN = lib.mkOption {
type = lib.types.singleLineStr;
example = "git.example.com";
description = "Fully qualified domain name of the Gitea instance";
};
databasePasswordFile = lib.mkOption {
type = lib.types.path;
example = "/etc/gitea-db-pass.txt";
description = "Path to the file containing the Gitea database password";
};
nativeRunner = lib.mkOption {
type = lib.types.bool;
description = "Install a gitea act_runner using the native nix store";
default = false;
};
};
config = lib.mkIf cfg.enable {
# Gitea instance
services.gitea = {
enable = true;
lfs.enable = true;
appName = "Git yourself some Tea!";
database = {
name = "gitea";
type = "postgres";
passwordFile = cfg.databasePasswordFile;
};
settings = {
server.PROTOCOL = "http+unix";
server.ROOT_URL = "https://${cfg.instanceFQDN}/";
server.DOMAIN = cfg.instanceFQDN;
service.DISABLE_REGISTRATION = true;
};
};
# Fallback server with only 403
services.nginx.virtualHosts.${config.networking.domain} = lib.mkDefault {
default = true;
locations."/".return = 403;
forceSSL = true;
enableACME = true;
};
# Virtual host for gitea
services.nginx.virtualHosts."${cfg.instanceFQDN}" = {
forceSSL = true;
enableACME = true;
locations."/" = {
proxyPass = "http://unix:/run/gitea/gitea.sock";
};
};
# Database setup
services.postgresql = {
enable = true;
ensureDatabases = [config.services.gitea.user];
ensureUsers = [
{
name = config.services.gitea.database.user;
ensureDBOwnership = true;
}
];
};
# act_runner
services.gitea-actions-runner = lib.mkIf cfg.nativeRunner {
instances.nixos-host = {
enable = true;
name = "nixos-host-runner";
url = "https://${cfg.instanceFQDN}";
tokenFile = "/var/lib/gitea-registration/nixos-host";
labels = ["nixos:host"];
settings = {
runner = {
capacity = 1;
};
};
};
};
systemd.services.gitea-runner-nixos-host = lib.mkIf cfg.nativeRunner {
after = ["gitea-runner-gen-token.service"];
requires = ["gitea-runner-gen-token.service"];
serviceConfig.Environment = ''
PATH=/run/current-system/sw/bin:/usr/bin:/bin
'';
};
systemd.services.gitea-runner-gen-token = lib.mkIf cfg.nativeRunner {
wantedBy = ["multi-user.target"];
after = ["gitea.service"];
environment = {
GITEA_CUSTOM = "/var/lib/gitea/custom";
GITEA_WORK_DIR = "/var/lib/gitea";
};
script = ''
set -euo pipefail
token=$(${config.services.gitea.package}/bin/gitea actions generate-runner-token)
echo "TOKEN=$token" > /var/lib/gitea-registration/nixos-host
'';
unitConfig.ConditionPathExists = ["!/var/lib/gitea-registration/nixos-host"];
serviceConfig = {
User = "gitea";
Group = "gitea";
StateDirectory = "gitea-registration";
Type = "oneshot";
RemainAfterExit = true;
};
};
};
};
}

View File

@@ -0,0 +1,133 @@
{
flake.nixosModules.gotify-instance = {
config,
lib,
...
}: let
cfg = config.hive.gotify-instance;
server-config = {
server = {
listenaddr = "localhost";
port = 54545;
ssl.enabled = false;
ssl.redirecttohttps = false;
cors.alloworigins = ["${cfg.instanceFQDN}"];
stream.allowedorigins = ["${cfg.instanceFQDN}"];
};
database = {
dialect = "postgres";
connection = "host=/run/postgresql dbname=${cfg.user} user=${cfg.user}";
};
defaultuser = {
name = "admin";
pass = config.sops.placeholder.${cfg.adminPasswordSopsKey};
};
registration = false;
};
server-config-yaml = lib.generators.toYAML {} server-config;
in {
options.hive.gotify-instance = {
enable = lib.mkEnableOption "Enable the Gotify instance";
instanceFQDN = lib.mkOption {
type = lib.types.singleLineStr;
example = "gotify.example.com";
description = "Fully qualified domain name of the Gotify instance";
};
user = lib.mkOption {
type = lib.types.singleLineStr;
default = "gotify";
description = "The user to run the service as";
};
group = lib.mkOption {
type = lib.types.singleLineStr;
default = "gotify";
description = "The group to run the service as";
};
adminPasswordSopsKey = lib.mkOption {
type = lib.types.singleLineStr;
description = "The SOPS key for the default admin user";
};
};
config = lib.mkIf cfg.enable {
services.gotify.enable = true;
# Config setup
sops.templates."gotify-server-config.yml" = {
owner = cfg.user;
content = server-config-yaml;
};
environment.etc."gotify/config.yml".source = config.sops.templates."gotify-server-config.yml".path;
# User setup
users.users = lib.mkIf (cfg.user == "gotify") {
gotify = {
description = "Gotify service";
useDefaultShell = true;
group = cfg.group;
isSystemUser = true;
};
};
users.groups = lib.mkIf (cfg.group == "gotify") {
gotify = {};
};
# Configure gotify to run as the specified user (for postgres authentication)
systemd.services.gotify-server = {
serviceConfig = {
DynamicUser = lib.mkForce false;
User = cfg.user;
RuntimeDirectory = "gotify";
};
};
# Fallback server with only 403
services.nginx.virtualHosts.${config.networking.domain} = lib.mkDefault {
default = true;
locations."/".return = 403;
forceSSL = true;
enableACME = true;
};
# Virtual host for gotify
services.nginx.virtualHosts."${cfg.instanceFQDN}" = {
forceSSL = true;
enableACME = true;
locations."/" = {
proxyPass = "http://${server-config.server.listenaddr}:${toString server-config.server.port}";
extraConfig = ''
# Ensuring it can use websockets
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
proxy_redirect http:// $scheme://;
# The proxy must preserve the host because gotify verifies the host with the origin
# for WebSocket connections
proxy_set_header Host $host;
# These sets the timeout so that the websocket can stay alive
proxy_connect_timeout 1m;
proxy_send_timeout 1m;
proxy_read_timeout 1m;
'';
};
};
# Database setup
services.postgresql = {
enable = true;
ensureDatabases = [cfg.user];
ensureUsers = [
{
name = cfg.user;
ensureDBOwnership = true;
}
];
};
};
};
}

View File

@@ -0,0 +1,36 @@
{
url ? null,
hash ? null,
pkgs,
lib,
...
}: let
modpack = pkgs.fetchzip {
inherit url hash;
stripRoot = false;
};
variablesStr = builtins.readFile "${modpack}/variables.txt";
variableLines =
builtins.filter (l: l != "" && (lib.strings.elemAt (lib.stringToCharacters l) 0) != "#")
(lib.strings.splitString "\n" variablesStr);
stripQuotes = s:
if builtins.match "^\".*\"$" s != null
then builtins.substring 1 (builtins.stringLength s - 2) s
else s;
parseLine = line: let
parts = lib.strings.splitString "=" line;
in {
name = builtins.elemAt parts 0;
value = stripQuotes (builtins.concatStringsSep "=" (builtins.tail parts));
};
variables = builtins.listToAttrs (map parseLine variableLines);
in {
inherit variables;
root = modpack;
mods = "${modpack}/mods";
config = "${modpack}/config";
}

View File

@@ -0,0 +1,46 @@
{
flake.nixosModules.minecraft-server = {
config,
pkgs,
lib,
...
}: let
cfg = config.hive.minecraft-server;
modpack = pkgs.callPackage ./_loadCurseForge.nix {
url = "https://mediafilez.forgecdn.net/files/7765/203/BMC3_Server_Pack_v44.zip";
hash = "sha256-doqPzo9fhYM9ng/3RO6OPqhKA2ibfoaKx3Es7M0lpuU=";
};
mcVersion = modpack.variables.MINECRAFT_VERSION;
loader = lib.toLower modpack.variables.MODLOADER;
loaderVersion = modpack.variables.MODLOADER_VERSION;
serverVersion = lib.replaceStrings ["."] ["_"] "${loader}-${mcVersion}";
in {
options.hive.minecraft-server = {
enable = lib.mkEnableOption "Enable BMC3 server";
};
config = lib.mkIf cfg.enable {
services.minecraft-servers = {
enable = true;
eula = true;
openFirewall = true;
servers.bmc3 = lib.optionalAttrs cfg.enable {
enable = true;
autoStart = false;
package = pkgs."${loader}Servers".${serverVersion}.override {inherit loaderVersion;};
jvmOpts = modpack.variables.JAVA_ARGS;
symlinks = {
"mods" = "${modpack.root}/mods";
};
serverProperties = {
motd = "Woher kommt der Stein?";
white-list = true;
};
};
};
};
};
}

View File

@@ -0,0 +1,136 @@
{
flake.nixosModules.nextcloud-instance = {
config,
lib,
pkgs,
...
}: let
cfg = config.hive.nextcloud-instance;
in {
options.hive.nextcloud-instance = {
enable = lib.mkEnableOption "Enable the Nextcloud instance";
instanceFQDN = lib.mkOption {
type = lib.types.str;
example = "nextcloud.example.com";
description = "Fully qualified domain name of the Nextcloud instance";
};
ssl = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Use SSL and auto-update certificates";
};
adminPasswordFile = lib.mkOption {
type = lib.types.path;
example = "/etc/nc-admin-pass.txt";
description = "Path to the file containing the Nextcloud admin password";
};
};
config = lib.mkIf cfg.enable {
services.nextcloud = {
# Instance
enable = true;
package = pkgs.nextcloud33;
hostName = cfg.instanceFQDN;
https = cfg.ssl;
configureRedis = true;
# DB
config.dbtype = "pgsql";
config.dbhost = "/run/postgresql";
config.adminpassFile = cfg.adminPasswordFile;
#Mail
settings = {
mail_smtpmode = "sendmail";
mail_sendmailmode = "pipe";
};
# Apps
extraAppsEnable = true;
extraApps = {
inherit
(config.services.nextcloud.package.packages.apps)
calendar
contacts
tasks
;
drop_account = pkgs.fetchNextcloudApp {
sha256 = "sha256-J+bZVNIb/MokuTYQu8RBKdnZFakh180pa1pW5KHlC80=";
url = "https://packages.framasoft.org/projects/nextcloud-apps/drop-account/drop_account-3.0.0.tar.gz";
license = "agpl3Only";
};
};
# Raise Upload limit
maxUploadSize = "20G";
# Preview settings (video may be a security risk)
settings = {
enable_previews = true;
enabledPreviewProviders = [
"OC\\Preview\\BMP"
"OC\\Preview\\GIF"
"OC\\Preview\\JPEG"
"OC\\Preview\\Krita"
"OC\\Preview\\MarkDown"
"OC\\Preview\\MP3"
"OC\\Preview\\OpenDocument"
"OC\\Preview\\PNG"
"OC\\Preview\\TXT"
"OC\\Preview\\XBitmap"
"OC\\Preview\\Movie"
"OC\\Preview\\MP4"
"OC\\Preview\\AVI"
"OC\\Preview\\MKV"
];
preview_ffmpeg_path = "${pkgs.ffmpeg}/bin/ffmpeg";
};
};
# Fallback server with only 403
services.nginx.virtualHosts.${config.networking.domain} = lib.mkDefault {
default = true;
locations."/".return = 403;
forceSSL = cfg.ssl;
enableACME = cfg.ssl;
};
# Webserver setup with optional SSL
services.nginx.virtualHosts.${cfg.instanceFQDN} =
if cfg.ssl
then {
forceSSL = true;
enableACME = true;
}
else {
listen = [
{
addr = "0.0.0.0";
port = 80;
}
];
};
security.acme = lib.mkIf cfg.ssl {
acceptTerms = true;
defaults.email = "jonas.roeger+acme@gmail.com";
};
networking.firewall.allowedTCPPorts = [80] ++ lib.optional cfg.ssl 443;
# DB setup
services.postgresql = {
enable = true;
ensureDatabases = ["nextcloud"];
ensureUsers = [
{
name = "nextcloud";
ensureDBOwnership = true;
}
];
};
};
};
}