Merge branch 'master' into 2305
This commit is contained in:
commit
5434e0daea
|
@ -1,9 +0,0 @@
|
|||
{ ... }:
|
||||
{
|
||||
imports = [
|
||||
./bluetooth
|
||||
./dvd
|
||||
./nvidia
|
||||
];
|
||||
}
|
||||
|
|
@ -30,7 +30,6 @@
|
|||
(setq sendmail-program "msmtp")
|
||||
|
||||
(require 'mu4e)
|
||||
(require 'org-mu4e)
|
||||
|
||||
(setq mu4e-completing-read-function (quote ivy-completing-read))
|
||||
(setq mail-user-agent 'mu4e-user-agent)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
(use-package lsp-nix
|
||||
:after (lsp-mode)
|
||||
:demand t
|
||||
:ensure nil
|
||||
:custom
|
||||
(lsp-nix-nil-formatter ["nixpkgs-fmt"]))
|
||||
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
{ custom, hostname, inputs, system ? "x86_64-linux", home-module ? "headless", username ? "andreas" }:
|
||||
let
|
||||
overlay-unstable = final: prev: {
|
||||
unstable = import custom.inputs.nixpkgs-unstable {
|
||||
unstable = import inputs.nixpkgs-unstable {
|
||||
inherit system;
|
||||
config.allowUnfree = true;
|
||||
};
|
||||
};
|
||||
|
||||
pkgs = import custom.inputs.nixpkgs {
|
||||
pkgs = import inputs.nixpkgs {
|
||||
inherit system;
|
||||
config = {
|
||||
allowUnfree = true;
|
||||
|
@ -28,33 +28,32 @@ let
|
|||
];
|
||||
};
|
||||
in
|
||||
custom.inputs.nixpkgs.lib.nixosSystem
|
||||
inputs.nixpkgs.lib.nixosSystem
|
||||
{
|
||||
inherit system pkgs;
|
||||
specialArgs = { inherit custom inputs; };
|
||||
specialArgs = { inherit inputs; };
|
||||
modules = (
|
||||
[
|
||||
# System configuration for this host
|
||||
(import "${custom.inputs.self}/systems/${hostname}" {
|
||||
(import "${inputs.self}/systems/${hostname}" {
|
||||
inherit hostname;
|
||||
})
|
||||
|
||||
# Common configuration
|
||||
(import "${custom.inputs.self}/modules/default.nix" { inherit custom; })
|
||||
"${custom.inputs.self}/hardware/default.nix"
|
||||
"${inputs.self}/modules"
|
||||
|
||||
custom.inputs.agenix.nixosModules.age
|
||||
inputs.agenix.nixosModules.age
|
||||
{
|
||||
environment.systemPackages = [ custom.inputs.agenix.packages.${system}.default ];
|
||||
environment.systemPackages = [ inputs.agenix.packages.${system}.default ];
|
||||
az-username = username;
|
||||
}
|
||||
|
||||
custom.inputs.home-manager.nixosModules.home-manager
|
||||
inputs.home-manager.nixosModules.home-manager
|
||||
{
|
||||
home-manager.useGlobalPkgs = true;
|
||||
home-manager.useUserPackages = true;
|
||||
home-manager.users.andreas.imports = [
|
||||
(import "${custom.inputs.self}/home-manager/${home-module}.nix" { inherit custom system; })
|
||||
(import "${inputs.self}/home-manager/${home-module}.nix" { inherit custom system; })
|
||||
];
|
||||
}
|
||||
]);
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
{ custom, hostname, inputs, system ? "aarch64-linux", home-module ? "headless", username ? "andreas" }:
|
||||
let
|
||||
overlay-unstable = final: prev: {
|
||||
unstable = import custom.inputs.nixpkgs-unstable {
|
||||
unstable = import inputs.nixpkgs-unstable {
|
||||
inherit system;
|
||||
config.allowUnfree = true;
|
||||
};
|
||||
};
|
||||
|
||||
pkgs = import custom.inputs.nixpkgs {
|
||||
pkgs = import inputs.nixpkgs {
|
||||
inherit system;
|
||||
config = {
|
||||
allowUnfree = true;
|
||||
|
@ -25,31 +25,30 @@ let
|
|||
};
|
||||
in
|
||||
|
||||
custom.inputs.nixpkgs.lib.nixosSystem {
|
||||
inputs.nixpkgs.lib.nixosSystem {
|
||||
inherit pkgs system;
|
||||
specialArgs = { inherit custom inputs; };
|
||||
specialArgs = { inherit inputs; };
|
||||
modules = (
|
||||
[
|
||||
# System configuration for this host
|
||||
(import "${custom.inputs.self}/systems/${hostname}"
|
||||
(import "${inputs.self}/systems/${hostname}"
|
||||
{ inherit hostname; })
|
||||
|
||||
# Common configuration
|
||||
"${custom.inputs.self}/modules/default.nix"
|
||||
"${custom.inputs.self}/hardware/default.nix"
|
||||
"${inputs.self}/modules"
|
||||
|
||||
custom.inputs.agenix.nixosModules.age
|
||||
inputs.agenix.nixosModules.age
|
||||
{
|
||||
environment.systemPackages = [ custom.inputs.agenix.packages.${system}.default ];
|
||||
environment.systemPackages = [ inputs.agenix.packages.${system}.default ];
|
||||
az-username = username;
|
||||
}
|
||||
|
||||
custom.inputs.home-manager.nixosModules.home-manager
|
||||
inputs.home-manager.nixosModules.home-manager
|
||||
{
|
||||
home-manager.useGlobalPkgs = true;
|
||||
home-manager.useUserPackages = true;
|
||||
home-manager.users.${username}.imports = [
|
||||
(import "${custom.inputs.self}/home-manager/${home-module}.nix" { inherit custom system; })
|
||||
(import "${inputs.self}/home-manager/${home-module}.nix" { inherit custom system; })
|
||||
];
|
||||
}
|
||||
]);
|
||||
|
|
|
@ -2,29 +2,42 @@
|
|||
{
|
||||
imports = [
|
||||
./common
|
||||
./common-x86
|
||||
./data-share
|
||||
./docker
|
||||
./email
|
||||
./eog
|
||||
./hunspell
|
||||
./libimobiledevice
|
||||
./lockscreen
|
||||
./logs-share
|
||||
./log-to-ram
|
||||
./makemkv
|
||||
./nix-direnv
|
||||
./pipewire
|
||||
./rdp
|
||||
./restic-client-desktop
|
||||
./scripts
|
||||
./steam
|
||||
./syslog
|
||||
./telegram-notifications
|
||||
./tlp
|
||||
./tmux
|
||||
./username
|
||||
./virtualbox-guest
|
||||
./hardware/bluetooth
|
||||
./hardware/dvd
|
||||
./hardware/nvidia
|
||||
./profiles/desktop
|
||||
./programs/email
|
||||
./programs/eog
|
||||
./programs/hunspell
|
||||
./programs/libimobiledevice
|
||||
./programs/lockscreen
|
||||
./programs/makemkv
|
||||
./programs/nix-direnv
|
||||
./programs/scripts
|
||||
./programs/steam
|
||||
./programs/tmux
|
||||
./services/common-x86
|
||||
./services/data-share
|
||||
./services/docker
|
||||
./services/docker-mailserver
|
||||
./services/gitea
|
||||
./services/grav
|
||||
./services/haproxy
|
||||
./services/heimdall
|
||||
./services/logs-share
|
||||
./services/log-to-ram
|
||||
./services/mariadb-for-containers
|
||||
./services/media-share
|
||||
./services/nextcloud
|
||||
./services/nginx-acme-base
|
||||
./services/pipewire
|
||||
./services/rclone-webdav
|
||||
./services/rdp
|
||||
./services/restic-client-desktop
|
||||
./services/syslog
|
||||
./services/telegram-notifications
|
||||
./services/tlp
|
||||
./services/virtualbox-guest
|
||||
./username
|
||||
];
|
||||
}
|
||||
|
|
|
@ -1,83 +0,0 @@
|
|||
{ config, inputs, pkgs, ... }:
|
||||
let
|
||||
version = "12.1.0";
|
||||
mailserver-setup = (pkgs.writeScriptBin "mailserver-setup"
|
||||
"${builtins.readFile (pkgs.fetchurl {
|
||||
url = "https://raw.githubusercontent.com/docker-mailserver/docker-mailserver/v${version}/setup.sh";
|
||||
sha256 = "sha256-i5RaupuYo3Bh99/FKbxXKFITO3Ko3LrWPvTD6xPBXzY";
|
||||
})
|
||||
}").overrideAttrs (old: {
|
||||
buildCommand = "${old.buildCommand}\n patchShebangs $out";
|
||||
});
|
||||
in
|
||||
{
|
||||
services.az-telegram-notifications.enable = true;
|
||||
|
||||
age.secrets.dkim2liCh = {
|
||||
file = "${inputs.self}/scrts/dkim_2li.ch.age";
|
||||
mode = "600";
|
||||
owner = "113";
|
||||
group = "115";
|
||||
};
|
||||
age.secrets.dkimZweiliCh = {
|
||||
file = "${inputs.self}/scrts/dkim_zweili.ch.age";
|
||||
mode = "600";
|
||||
owner = "113";
|
||||
group = "115";
|
||||
};
|
||||
|
||||
environment.etc = {
|
||||
"dkim/2li.ch.private" = {
|
||||
enable = true;
|
||||
source = config.age.secrets.dkim2liCh.path;
|
||||
};
|
||||
"dkim/zweili.ch.private" = {
|
||||
enable = true;
|
||||
source = config.age.secrets.dkimZweiliCh.path;
|
||||
};
|
||||
};
|
||||
|
||||
environment.systemPackages = [
|
||||
mailserver-setup
|
||||
];
|
||||
|
||||
services.az-docker.enable = true;
|
||||
|
||||
virtualisation.oci-containers = {
|
||||
backend = "docker";
|
||||
containers."mailserver" = {
|
||||
# https://hub.docker.com/r/mailserver/docker-mailserver/tags
|
||||
image = "docker.io/mailserver/docker-mailserver:${version}";
|
||||
autoStart = true;
|
||||
environmentFiles = [
|
||||
./mailserver.env
|
||||
];
|
||||
ports = [
|
||||
"25:25"
|
||||
"143:143"
|
||||
"465:465"
|
||||
"587:587"
|
||||
"993:993"
|
||||
"11334:11334"
|
||||
];
|
||||
volumes = [
|
||||
"/etc/localtime:/etc/localtime:ro"
|
||||
"/etc/dkim:/etc/dkim:ro"
|
||||
"/etc/static:/etc/static:ro"
|
||||
"/run/agenix:/run/agenix:ro"
|
||||
"/var/lib/acme/mail.zweili.org:/etc/letsencrypt/live/mail.zweili.org:ro"
|
||||
"/var/lib/redis:/var/lib/redis"
|
||||
];
|
||||
extraOptions = [
|
||||
''--mount=type=volume,source=maildata,target=/var/mail,volume-driver=local,volume-opt=type=nfs,volume-opt=device=:/server_data/docker-mailserver/maildata,"volume-opt=o=addr=10.7.89.108,rw,nfsvers=4.0,nolock,hard,noatime"''
|
||||
''--mount=type=volume,source=mailstate,target=/var/mail-state,volume-driver=local,volume-opt=type=nfs,volume-opt=device=:/server_data/docker-mailserver/mailstate,"volume-opt=o=addr=10.7.89.108,rw,nfsvers=4.0,nolock,hard,noatime"''
|
||||
''--mount=type=volume,source=maillogs,target=/var/log/mail,volume-driver=local,volume-opt=type=nfs,volume-opt=device=:/server_data/docker-mailserver/maillogs,"volume-opt=o=addr=10.7.89.108,rw,nfsvers=4.0,nolock,hard,noatime"''
|
||||
''--mount=type=volume,source=config,target=/tmp/docker-mailserver,volume-driver=local,volume-opt=type=nfs,volume-opt=device=:/server_data/docker-mailserver/config,"volume-opt=o=addr=10.7.89.108,rw,nfsvers=4.0,nolock,hard,noatime"''
|
||||
"--add-host=host.docker.internal:host-gateway"
|
||||
"--cap-add=NET_ADMIN"
|
||||
"--cap-add=SYS_PTRACE"
|
||||
"--log-opt=tag='mailserver'"
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
{ domain }: { config, inputs, ... }:
|
||||
{
|
||||
age.secrets.giteaEnv.file = "${inputs.self}/scrts/gitea_env.age";
|
||||
|
||||
services.az-docker.enable = true;
|
||||
|
||||
virtualisation.oci-containers = {
|
||||
backend = "docker";
|
||||
containers."gitea" = {
|
||||
# https://blog.gitea.io/
|
||||
# https://hub.docker.com/r/gitea/gitea/tags
|
||||
image = "gitea/gitea:1.19.3";
|
||||
autoStart = true;
|
||||
environment = {
|
||||
PUID = "1000";
|
||||
PGID = "100";
|
||||
DB_TYPE = "mysql";
|
||||
DB_HOST = "host.docker.internal:3306";
|
||||
DB_NAME = "giteadb";
|
||||
DB_USER = "gitea";
|
||||
ROOT_URL = "${domain}";
|
||||
INSTALL_LOCK = "true";
|
||||
DISABLE_REGISTRATION = "true";
|
||||
};
|
||||
environmentFiles = [ config.age.secrets.giteaEnv.path ];
|
||||
ports = [
|
||||
"2222:22"
|
||||
"8080:3000"
|
||||
];
|
||||
volumes = [
|
||||
"/etc/timezone:/etc/timezone:ro"
|
||||
"/etc/localtime:/etc/localtime:ro"
|
||||
];
|
||||
extraOptions = [
|
||||
''--mount=type=volume,source=gitea_data,target=/data,volume-driver=local,volume-opt=type=nfs,volume-opt=device=:/server_data/gitea/data,"volume-opt=o=addr=10.7.89.108,rw,nfsvers=4.0,nolock,hard,noatime"''
|
||||
"--add-host=host.docker.internal:host-gateway"
|
||||
"--log-opt=tag='gitea'"
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
{ ... }:
|
||||
{
|
||||
services.az-docker.enable = true;
|
||||
|
||||
virtualisation.oci-containers = {
|
||||
backend = "docker";
|
||||
containers."grav" = {
|
||||
# https://fleet.linuxserver.io/image?name=linuxserver/grav
|
||||
image = "lscr.io/linuxserver/grav:1.7.41";
|
||||
autoStart = true;
|
||||
environment = {
|
||||
TZ = "Europe/Zurich";
|
||||
PUID = "100";
|
||||
PGID = "101";
|
||||
};
|
||||
ports = [
|
||||
"8080:80"
|
||||
];
|
||||
volumes = [
|
||||
"/etc/timezone:/etc/timezone:ro"
|
||||
"/etc/localtime:/etc/localtime:ro"
|
||||
];
|
||||
extraOptions = [
|
||||
''--mount=type=volume,source=grav,target=/config,volume-driver=local,volume-opt=type=nfs,volume-opt=device=:/server_data/grav,"volume-opt=o=addr=10.7.89.108,rw,nfsvers=4.0,nolock,hard,noatime"''
|
||||
"--log-opt=tag='grav'"
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -1,77 +0,0 @@
|
|||
{ ... }:
|
||||
{
|
||||
networking = {
|
||||
enableIPv6 = false;
|
||||
firewall.allowedTCPPorts = [ 80 443 1936 ];
|
||||
};
|
||||
services.haproxy = {
|
||||
enable = true;
|
||||
config = ''
|
||||
defaults
|
||||
log stdout format raw local0 info
|
||||
option tcplog
|
||||
timeout connect 5s
|
||||
timeout client 30s
|
||||
timeout server 30s
|
||||
|
||||
listen haproxy-monitoring
|
||||
bind *:1936
|
||||
mode http
|
||||
stats enable
|
||||
stats hide-version
|
||||
stats realm Haproxy\ Statistics
|
||||
stats uri /
|
||||
stats auth admin:password
|
||||
|
||||
frontend http
|
||||
bind *:80
|
||||
mode http
|
||||
redirect scheme https code 301 if { hdr(host) -i mail.zweili.org ! {ssl_fc }
|
||||
redirect scheme https code 301 if { hdr(host) -i git.2li.ch } !{ ssl_fc }
|
||||
redirect scheme https code 301 if { hdr(host) -i heimdall.2li.ch } !{ ssl_fc }
|
||||
redirect scheme https code 301 if { hdr(host) -i nextcloud.2li.ch } !{ ssl_fc }
|
||||
redirect scheme https code 301 if { hdr(host) -i ttrss.2li.ch } !{ ssl_fc }
|
||||
redirect scheme https code 301 if { hdr(host) -i webmail.2li.ch } !{ ssl_fc }
|
||||
redirect scheme https code 301 if { hdr(host) -i rss-bridge.2li.ch } !{ ssl_fc }
|
||||
redirect scheme https code 301 if { hdr(host) -i www.2li.ch } !{ ssl_fc }
|
||||
redirect scheme https code 301 if { hdr_dom(host) -i 2li.ch } !{ ssl_fc }
|
||||
|
||||
frontend https
|
||||
# Listen on port 443
|
||||
bind *:443
|
||||
mode tcp
|
||||
|
||||
tcp-request inspect-delay 5s
|
||||
tcp-request content accept if { req_ssl_hello_type 1 }
|
||||
|
||||
# Figure out which backend (= VM) to use
|
||||
use_backend git_server if { req_ssl_sni -i git.2li.ch }
|
||||
use_backend proxy if { req_ssl_sni -i heimdall.2li.ch }
|
||||
use_backend mail_server if { req_ssl_sni -i mail.zweili.org }
|
||||
use_backend nextcloud_server if { req_ssl_sni -i nextcloud.2li.ch }
|
||||
use_backend ttrss_server if { req_ssl_sni -i ttrss.2li.ch }
|
||||
use_backend ttrss_server if { req_ssl_sni -i rss-bridge.2li.ch }
|
||||
use_backend proxy if { req_ssl_sni -i www.2li.ch }
|
||||
use_backend proxy if { req_ssl_sni -i 2li.ch }
|
||||
|
||||
backend grav_server
|
||||
mode tcp
|
||||
server server1 10.7.89.102:443 check
|
||||
backend git_server
|
||||
mode tcp
|
||||
server server1 10.7.89.109:443 check
|
||||
backend nextcloud_server
|
||||
mode tcp
|
||||
server server1 10.7.89.103:443 check
|
||||
backend ttrss_server
|
||||
mode tcp
|
||||
server server1 10.7.89.115:443 check
|
||||
backend mail_server
|
||||
mode tcp
|
||||
server server1 10.7.89.123:443 check
|
||||
backend proxy
|
||||
mode tcp
|
||||
server server1 127.0.0.1:4433 check
|
||||
'';
|
||||
};
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
{ ... }:
|
||||
{
|
||||
services.az-docker.enable = true;
|
||||
|
||||
virtualisation.oci-containers = {
|
||||
backend = "docker";
|
||||
containers."heimdall" = {
|
||||
# https://fleet.linuxserver.io/image?name=linuxserver/heimdall
|
||||
image = "linuxserver/heimdall:2.5.6";
|
||||
autoStart = true;
|
||||
environment = {
|
||||
TZ = "Europe/Zurich";
|
||||
PUID = "1000";
|
||||
PGID = "100";
|
||||
};
|
||||
ports = [
|
||||
"8081:80"
|
||||
];
|
||||
volumes = [
|
||||
"/etc/localtime:/etc/localtime:ro"
|
||||
];
|
||||
extraOptions = [
|
||||
''--mount=type=volume,source=heimdall,target=/config,volume-driver=local,volume-opt=type=nfs,volume-opt=device=:/server_data/heimdall,"volume-opt=o=addr=10.7.89.108,rw,nfsvers=4.0,nolock,hard,noatime"''
|
||||
"--log-opt=tag='heimdall'"
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
{ pkgs, ... }:
|
||||
{
|
||||
services.mysql = {
|
||||
enable = true;
|
||||
package = pkgs.mariadb;
|
||||
settings = {
|
||||
mysqld = {
|
||||
bind-address = "172.17.0.1";
|
||||
};
|
||||
};
|
||||
};
|
||||
networking.firewall.extraCommands = "iptables -A INPUT -p tcp --destination-port 3306 -s 172.16.0.0/12 -j ACCEPT";
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
{ ... }:
|
||||
{
|
||||
fileSystems."/mnt/media" = {
|
||||
device = "10.7.89.108:media";
|
||||
fsType = "nfs";
|
||||
options = [ "noatime" "hard" "nfsvers=4.0" ];
|
||||
};
|
||||
}
|
|
@ -1,106 +0,0 @@
|
|||
{ domain }: { config, inputs, pkgs, ... }:
|
||||
let
|
||||
nextcloudEnvironment = {
|
||||
MYSQL_DATABASE = "nextcloud";
|
||||
MYSQL_USER = "nextcloud";
|
||||
MYSQL_HOST = "172.17.0.1";
|
||||
NEXTCLOUD_TRUSTED_DOMAINS = "${domain} ${config.networking.hostName}.2li.local 10.7.89.103";
|
||||
REDIS_HOST = "redis";
|
||||
SMTP_HOST = "mail.infomaniak.com";
|
||||
SMTP_SECURE = "ssl";
|
||||
SMTP_PORT = "465";
|
||||
};
|
||||
networkName = "nextcloud";
|
||||
# https://github.com/Nebucatnetzer/nextcloud-smb
|
||||
nextcloudImage = "ghcr.io/nebucatnetzer/nextcloud-smb/nextcloud-smb:26.0.1@sha256:f8773310c341d52104df01cd7c0c59ed4e502bcc5fa7b8304cb1f595680125e1";
|
||||
nextcloudService = "${config.virtualisation.oci-containers.backend}-nextcloud";
|
||||
cronService = "${config.virtualisation.oci-containers.backend}-cron";
|
||||
in
|
||||
{
|
||||
age.secrets.nextcloudEnv.file = "${inputs.self}/scrts/nextcloud_env.age";
|
||||
|
||||
services.mysql.settings = {
|
||||
mysqld = {
|
||||
innodb_file_per_table = 1;
|
||||
innodb_buffer_pool_size = "2G";
|
||||
read_rnd_buffer_size = "4M";
|
||||
sort_buffer_size = "4M";
|
||||
};
|
||||
};
|
||||
|
||||
services.az-docker.enable = true;
|
||||
|
||||
virtualisation.oci-containers = {
|
||||
backend = "docker";
|
||||
containers."nextcloud" = {
|
||||
image = nextcloudImage;
|
||||
autoStart = true;
|
||||
environment = nextcloudEnvironment;
|
||||
environmentFiles = [ config.age.secrets.nextcloudEnv.path ];
|
||||
volumes = [
|
||||
"${inputs.self}/modules/nextcloud/custom-php.ini:/usr/local/etc/php/conf.d/zzz-custom.ini"
|
||||
"/etc/localtime:/etc/localtime:ro"
|
||||
];
|
||||
dependsOn = [ "redis" ];
|
||||
extraOptions = [
|
||||
''--mount=type=volume,source=nextcloud_data,target=/var/www/html,volume-driver=local,volume-opt=type=nfs,volume-opt=device=:/server_data/nextcloud/data,"volume-opt=o=addr=10.7.89.108,rw,nfsvers=4.0,nolock,hard,noatime"''
|
||||
"--add-host=host.docker.internal:host-gateway"
|
||||
"--net=${networkName}"
|
||||
"--log-opt=tag='nextcloud'"
|
||||
];
|
||||
};
|
||||
containers."nginx" = {
|
||||
image = "nginx:1.22.1";
|
||||
autoStart = true;
|
||||
ports = [
|
||||
"8080:80"
|
||||
];
|
||||
volumes = [
|
||||
"${inputs.self}/modules/nextcloud/nginx.conf:/etc/nginx/nginx.conf:ro"
|
||||
"/etc/localtime:/etc/localtime:ro"
|
||||
];
|
||||
extraOptions = [
|
||||
''--mount=type=volume,source=nextcloud_data,target=/var/www/html,volume-driver=local,volume-opt=type=nfs,volume-opt=device=:/server_data/nextcloud/data,"volume-opt=o=addr=10.7.89.108,ro,nfsvers=4.0,nolock,hard,noatime"''
|
||||
"--net=${networkName}"
|
||||
"--log-opt=tag='nextcloud-nginx'"
|
||||
];
|
||||
};
|
||||
containers."cron" = {
|
||||
image = nextcloudImage;
|
||||
autoStart = true;
|
||||
environment = nextcloudEnvironment;
|
||||
environmentFiles = [ config.age.secrets.nextcloudEnv.path ];
|
||||
entrypoint = "/cron.sh";
|
||||
dependsOn = [ "redis" ];
|
||||
volumes = [
|
||||
"/etc/localtime:/etc/localtime:ro"
|
||||
];
|
||||
extraOptions = [
|
||||
''--mount=type=volume,source=nextcloud_data,target=/var/www/html,volume-driver=local,volume-opt=type=nfs,volume-opt=device=:/server_data/nextcloud/data,"volume-opt=o=addr=10.7.89.108,rw,nfsvers=4.0,nolock,hard,noatime"''
|
||||
"--add-host=host.docker.internal:host-gateway"
|
||||
"--net=nextcloud"
|
||||
"--log-opt=tag='nextcloud-cron'"
|
||||
];
|
||||
};
|
||||
containers."redis" = {
|
||||
image = "redis:alpine";
|
||||
autoStart = true;
|
||||
volumes = [
|
||||
"/etc/localtime:/etc/localtime:ro"
|
||||
];
|
||||
extraOptions = [
|
||||
"--net=${networkName}"
|
||||
"--log-opt=tag='redis'"
|
||||
];
|
||||
};
|
||||
};
|
||||
system.activationScripts.makeDockerNetwork = ''
|
||||
${pkgs.docker}/bin/docker network ls | ${pkgs.gnugrep}/bin/grep ${networkName} || ${pkgs.docker}/bin/docker network create ${networkName}
|
||||
'';
|
||||
|
||||
environment.shellAliases = {
|
||||
occ = ''${pkgs.docker}/bin/docker exec -u www-data nextcloud php occ'';
|
||||
};
|
||||
systemd.services.${nextcloudService}.after = [ "mysql.service" "nginx.service" ];
|
||||
systemd.services.${cronService}.after = [ "mysql.service" ];
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
{ ... }:
|
||||
{
|
||||
networking.firewall.allowedTCPPorts = [
|
||||
80
|
||||
443
|
||||
];
|
||||
security.acme = {
|
||||
acceptTerms = true;
|
||||
defaults.email = "admin+acme@zweili.ch";
|
||||
};
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
commonHttpConfig = ''
|
||||
# Add HSTS header with preloading to HTTPS requests.
|
||||
# Adding this header to HTTP requests is discouraged
|
||||
map $scheme $hsts_header {
|
||||
https "max-age=63072000; includeSubdomains; preload";
|
||||
}
|
||||
add_header Strict-Transport-Security $hsts_header;
|
||||
|
||||
# Enable CSP for your services.
|
||||
#add_header Content-Security-Policy "script-src 'self'; object-src 'none'; base-uri 'none';" always;
|
||||
|
||||
# Minimize information leaked to other domains
|
||||
add_header 'Referrer-Policy' 'origin-when-cross-origin';
|
||||
|
||||
# Prevent injection of code in other mime types (XSS Attacks)
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
|
||||
# Enable XSS protection of the browser.
|
||||
# May be unnecessary when CSP is configured properly (see above)
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
|
||||
# This might create errors
|
||||
proxy_cookie_path / "/; secure; HttpOnly; SameSite=strict";
|
||||
'';
|
||||
recommendedOptimisation = true;
|
||||
recommendedTlsSettings = true;
|
||||
};
|
||||
}
|
|
@ -1,27 +1,27 @@
|
|||
{ dataDir, documentRoot ? "/var/www/html", domain, port ? "9000", }:
|
||||
{ inputs, pkgs, ... }:
|
||||
{
|
||||
imports = [
|
||||
"${inputs.self}/modules/nginx-acme-base"
|
||||
];
|
||||
services.nginx = {
|
||||
appendHttpConfig = ''
|
||||
index index.php;
|
||||
'';
|
||||
virtualHosts."${domain}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
root = dataDir;
|
||||
locations = {
|
||||
"~ \\.php$" = {
|
||||
extraConfig = ''
|
||||
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
|
||||
include ${pkgs.nginx}/conf/fastcgi_params;
|
||||
include ${pkgs.nginx}/conf/fastcgi.conf;
|
||||
fastcgi_param SCRIPT_FILENAME ${documentRoot}$fastcgi_script_name;
|
||||
fastcgi_index index.php;
|
||||
fastcgi_pass 127.0.0.1:${port};
|
||||
'';
|
||||
services = {
|
||||
az-acme-base.enable = true;
|
||||
nginx = {
|
||||
appendHttpConfig = ''
|
||||
index index.php;
|
||||
'';
|
||||
virtualHosts."${domain}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
root = dataDir;
|
||||
locations = {
|
||||
"~ \\.php$" = {
|
||||
extraConfig = ''
|
||||
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
|
||||
include ${pkgs.nginx}/conf/fastcgi_params;
|
||||
include ${pkgs.nginx}/conf/fastcgi.conf;
|
||||
fastcgi_param SCRIPT_FILENAME ${documentRoot}$fastcgi_script_name;
|
||||
fastcgi_index index.php;
|
||||
fastcgi_pass 127.0.0.1:${port};
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
{ domain, port ? "8080" }: { inputs, ... }: {
|
||||
imports = [
|
||||
"${inputs.self}/modules/nginx-acme-base"
|
||||
];
|
||||
services.nginx = {
|
||||
appendHttpConfig = ''
|
||||
# Disable embedding as a frame
|
||||
add_header X-Frame-Options DENY;
|
||||
'';
|
||||
recommendedProxySettings = true;
|
||||
virtualHosts."${domain}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://127.0.0.1:${port}";
|
||||
proxyWebsockets = true; # needed if you need to use WebSocket
|
||||
services = {
|
||||
az-acme-base.enable = true;
|
||||
nginx = {
|
||||
appendHttpConfig = ''
|
||||
# Disable embedding as a frame
|
||||
add_header X-Frame-Options DENY;
|
||||
'';
|
||||
recommendedProxySettings = true;
|
||||
virtualHosts."${domain}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://127.0.0.1:${port}";
|
||||
proxyWebsockets = true; # needed if you need to use WebSocket
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
{ pkgs, ... }: {
|
||||
programs.nix-ld = {
|
||||
enable = true;
|
||||
libraries = with pkgs; [
|
||||
stdenv.cc.cc
|
||||
curl
|
||||
openssl
|
||||
zlib
|
||||
];
|
||||
};
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
{ config, pkgs, inputs, ... }:
|
||||
let
|
||||
pathToMonitor = "/home/${config.az-username}/10_documents/";
|
||||
syncNotes = pkgs.writeShellScriptBin "monitor-notes" ''
|
||||
${pkgs.rclone}/bin/rclone bisync -P --remove-empty-dirs --max-delete=10 --exclude=/99_archive/** nextcloud:10_documents ${pathToMonitor}
|
||||
'';
|
||||
in
|
||||
{
|
||||
services.az-telegram-notifications.enable = true;
|
||||
|
||||
age.secrets.webdavSecrets = {
|
||||
file = "${inputs.self}/scrts/webdav_andreas.age";
|
||||
path = "/home/${config.az-username}/.config/rclone/rclone.conf";
|
||||
mode = "600";
|
||||
owner = "${config.az-username}";
|
||||
group = "users";
|
||||
};
|
||||
|
||||
systemd.timers."rclone-webdav-sync" = {
|
||||
wantedBy = [ "timers.target" ];
|
||||
partOf = [ "rclone-webdav-sync.service" ];
|
||||
timerConfig = {
|
||||
OnStartupSec = "5min";
|
||||
OnUnitActiveSec = "5min";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services."rclone-webdav-sync" = {
|
||||
after = [ "network-online.target" ];
|
||||
serviceConfig = {
|
||||
User = config.az-username;
|
||||
Type = "oneshot";
|
||||
};
|
||||
onFailure = [ "unit-status-telegram@%n.service" ];
|
||||
script = "${syncNotes}/bin/monitor-notes";
|
||||
};
|
||||
|
||||
systemd.services."rclone-webdav-monitor" = {
|
||||
requires = [ "network-online.target" ];
|
||||
after = [ "network-online.target" ];
|
||||
serviceConfig = {
|
||||
User = config.az-username;
|
||||
};
|
||||
onFailure = [ "unit-status-telegram@%n.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
script = ''
|
||||
${pkgs.inotify-tools}/bin/inotifywait -m -r -e create,modify,delete,move "${pathToMonitor}" |
|
||||
while read -r directory event file; do
|
||||
sleep 10
|
||||
${syncNotes}/bin/monitor-notes
|
||||
done
|
||||
'';
|
||||
};
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
{ config, inputs, lib, pkgs, ... }:
|
||||
let
|
||||
cfg = config.services.az-mailserver;
|
||||
version = "12.1.0";
|
||||
mailserver-setup = (pkgs.writeScriptBin "mailserver-setup"
|
||||
"${builtins.readFile (pkgs.fetchurl {
|
||||
url = "https://raw.githubusercontent.com/docker-mailserver/docker-mailserver/v${version}/setup.sh";
|
||||
sha256 = "sha256-i5RaupuYo3Bh99/FKbxXKFITO3Ko3LrWPvTD6xPBXzY";
|
||||
})
|
||||
}").overrideAttrs (old: {
|
||||
buildCommand = "${old.buildCommand}\n patchShebangs $out";
|
||||
});
|
||||
in
|
||||
{
|
||||
options = {
|
||||
services.az-mailserver.enable = lib.mkEnableOption "Enable docker-mailserver";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
services.az-telegram-notifications.enable = true;
|
||||
|
||||
age.secrets.dkim2liCh = {
|
||||
file = "${inputs.self}/scrts/dkim_2li.ch.age";
|
||||
mode = "600";
|
||||
owner = "113";
|
||||
group = "115";
|
||||
};
|
||||
age.secrets.dkimZweiliCh = {
|
||||
file = "${inputs.self}/scrts/dkim_zweili.ch.age";
|
||||
mode = "600";
|
||||
owner = "113";
|
||||
group = "115";
|
||||
};
|
||||
|
||||
environment.etc = {
|
||||
"dkim/2li.ch.private" = {
|
||||
enable = true;
|
||||
source = config.age.secrets.dkim2liCh.path;
|
||||
};
|
||||
"dkim/zweili.ch.private" = {
|
||||
enable = true;
|
||||
source = config.age.secrets.dkimZweiliCh.path;
|
||||
};
|
||||
};
|
||||
|
||||
environment.systemPackages = [
|
||||
mailserver-setup
|
||||
];
|
||||
|
||||
services.az-docker.enable = true;
|
||||
|
||||
virtualisation.oci-containers = {
|
||||
backend = "docker";
|
||||
containers."mailserver" = {
|
||||
# https://hub.docker.com/r/mailserver/docker-mailserver/tags
|
||||
image = "docker.io/mailserver/docker-mailserver:${version}";
|
||||
autoStart = true;
|
||||
environmentFiles = [
|
||||
./mailserver.env
|
||||
];
|
||||
ports = [
|
||||
"25:25"
|
||||
"143:143"
|
||||
"465:465"
|
||||
"587:587"
|
||||
"993:993"
|
||||
"11334:11334"
|
||||
];
|
||||
volumes = [
|
||||
"/etc/localtime:/etc/localtime:ro"
|
||||
"/etc/dkim:/etc/dkim:ro"
|
||||
"/etc/static:/etc/static:ro"
|
||||
"/run/agenix:/run/agenix:ro"
|
||||
"/var/lib/acme/mail.zweili.org:/etc/letsencrypt/live/mail.zweili.org:ro"
|
||||
"/var/lib/redis:/var/lib/redis"
|
||||
];
|
||||
extraOptions = [
|
||||
''--mount=type=volume,source=maildata,target=/var/mail,volume-driver=local,volume-opt=type=nfs,volume-opt=device=:/server_data/docker-mailserver/maildata,"volume-opt=o=addr=10.7.89.108,rw,nfsvers=4.0,nolock,hard,noatime"''
|
||||
''--mount=type=volume,source=mailstate,target=/var/mail-state,volume-driver=local,volume-opt=type=nfs,volume-opt=device=:/server_data/docker-mailserver/mailstate,"volume-opt=o=addr=10.7.89.108,rw,nfsvers=4.0,nolock,hard,noatime"''
|
||||
''--mount=type=volume,source=maillogs,target=/var/log/mail,volume-driver=local,volume-opt=type=nfs,volume-opt=device=:/server_data/docker-mailserver/maillogs,"volume-opt=o=addr=10.7.89.108,rw,nfsvers=4.0,nolock,hard,noatime"''
|
||||
''--mount=type=volume,source=config,target=/tmp/docker-mailserver,volume-driver=local,volume-opt=type=nfs,volume-opt=device=:/server_data/docker-mailserver/config,"volume-opt=o=addr=10.7.89.108,rw,nfsvers=4.0,nolock,hard,noatime"''
|
||||
"--add-host=host.docker.internal:host-gateway"
|
||||
"--cap-add=NET_ADMIN"
|
||||
"--cap-add=SYS_PTRACE"
|
||||
"--log-opt=tag='mailserver'"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
{ config, inputs, lib, ... }:
|
||||
let
|
||||
cfg = config.services.az-gitea;
|
||||
in
|
||||
{
|
||||
options = {
|
||||
services.az-gitea.enable = lib.mkEnableOption "Enable Gitea in Docker.";
|
||||
services.az-gitea.domain = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "The domain Gitea is being run from.";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
age.secrets.giteaEnv.file = "${inputs.self}/scrts/gitea_env.age";
|
||||
|
||||
services = {
|
||||
az-docker.enable = true;
|
||||
az-mariadb-for-containers.enable = true;
|
||||
};
|
||||
|
||||
virtualisation.oci-containers = {
|
||||
backend = "docker";
|
||||
containers."gitea" = {
|
||||
# https://blog.gitea.io/
|
||||
# https://hub.docker.com/r/gitea/gitea/tags
|
||||
image = "gitea/gitea:1.19.3";
|
||||
autoStart = true;
|
||||
environment = {
|
||||
PUID = "1000";
|
||||
PGID = "100";
|
||||
DB_TYPE = "mysql";
|
||||
DB_HOST = "host.docker.internal:3306";
|
||||
DB_NAME = "giteadb";
|
||||
DB_USER = "gitea";
|
||||
ROOT_URL = "${cfg.domain}";
|
||||
INSTALL_LOCK = "true";
|
||||
DISABLE_REGISTRATION = "true";
|
||||
};
|
||||
environmentFiles = [ config.age.secrets.giteaEnv.path ];
|
||||
ports = [
|
||||
"2222:22"
|
||||
"8080:3000"
|
||||
];
|
||||
volumes = [
|
||||
"/etc/timezone:/etc/timezone:ro"
|
||||
"/etc/localtime:/etc/localtime:ro"
|
||||
];
|
||||
extraOptions = [
|
||||
''--mount=type=volume,source=gitea_data,target=/data,volume-driver=local,volume-opt=type=nfs,volume-opt=device=:/server_data/gitea/data,"volume-opt=o=addr=10.7.89.108,rw,nfsvers=4.0,nolock,hard,noatime"''
|
||||
"--add-host=host.docker.internal:host-gateway"
|
||||
"--log-opt=tag='gitea'"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
{ config, lib, ... }:
|
||||
let
|
||||
cfg = config.services.az-grav;
|
||||
in
|
||||
{
|
||||
options = {
|
||||
services.az-grav.enable = lib.mkEnableOption "Enable Grav.";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
services.az-docker.enable = true;
|
||||
|
||||
virtualisation.oci-containers = {
|
||||
backend = "docker";
|
||||
containers."grav" = {
|
||||
# https://fleet.linuxserver.io/image?name=linuxserver/grav
|
||||
image = "lscr.io/linuxserver/grav:1.7.41";
|
||||
autoStart = true;
|
||||
environment = {
|
||||
TZ = "Europe/Zurich";
|
||||
PUID = "100";
|
||||
PGID = "101";
|
||||
};
|
||||
ports = [
|
||||
"8080:80"
|
||||
];
|
||||
volumes = [
|
||||
"/etc/timezone:/etc/timezone:ro"
|
||||
"/etc/localtime:/etc/localtime:ro"
|
||||
];
|
||||
extraOptions = [
|
||||
''--mount=type=volume,source=grav,target=/config,volume-driver=local,volume-opt=type=nfs,volume-opt=device=:/server_data/grav,"volume-opt=o=addr=10.7.89.108,rw,nfsvers=4.0,nolock,hard,noatime"''
|
||||
"--log-opt=tag='grav'"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
{ config, lib, ... }:
|
||||
let
|
||||
cfg = config.services.az-haproxy;
|
||||
in
|
||||
{
|
||||
options = {
|
||||
services.az-haproxy.enable = lib.mkEnableOption "Enable HAProxy";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
networking = {
|
||||
enableIPv6 = false;
|
||||
firewall.allowedTCPPorts = [ 80 443 1936 ];
|
||||
};
|
||||
services.haproxy = {
|
||||
enable = true;
|
||||
config = ''
|
||||
defaults
|
||||
log stdout format raw local0 info
|
||||
option tcplog
|
||||
timeout connect 5s
|
||||
timeout client 30s
|
||||
timeout server 30s
|
||||
|
||||
listen haproxy-monitoring
|
||||
bind *:1936
|
||||
mode http
|
||||
stats enable
|
||||
stats hide-version
|
||||
stats realm Haproxy\ Statistics
|
||||
stats uri /
|
||||
stats auth admin:password
|
||||
|
||||
frontend http
|
||||
bind *:80
|
||||
mode http
|
||||
redirect scheme https code 301 if { hdr(host) -i mail.zweili.org ! {ssl_fc }
|
||||
redirect scheme https code 301 if { hdr(host) -i git.2li.ch } !{ ssl_fc }
|
||||
redirect scheme https code 301 if { hdr(host) -i heimdall.2li.ch } !{ ssl_fc }
|
||||
redirect scheme https code 301 if { hdr(host) -i nextcloud.2li.ch } !{ ssl_fc }
|
||||
redirect scheme https code 301 if { hdr(host) -i ttrss.2li.ch } !{ ssl_fc }
|
||||
redirect scheme https code 301 if { hdr(host) -i webmail.2li.ch } !{ ssl_fc }
|
||||
redirect scheme https code 301 if { hdr(host) -i rss-bridge.2li.ch } !{ ssl_fc }
|
||||
redirect scheme https code 301 if { hdr(host) -i www.2li.ch } !{ ssl_fc }
|
||||
redirect scheme https code 301 if { hdr_dom(host) -i 2li.ch } !{ ssl_fc }
|
||||
|
||||
frontend https
|
||||
# Listen on port 443
|
||||
bind *:443
|
||||
mode tcp
|
||||
|
||||
tcp-request inspect-delay 5s
|
||||
tcp-request content accept if { req_ssl_hello_type 1 }
|
||||
|
||||
# Figure out which backend (= VM) to use
|
||||
use_backend git_server if { req_ssl_sni -i git.2li.ch }
|
||||
use_backend proxy if { req_ssl_sni -i heimdall.2li.ch }
|
||||
use_backend mail_server if { req_ssl_sni -i mail.zweili.org }
|
||||
use_backend nextcloud_server if { req_ssl_sni -i nextcloud.2li.ch }
|
||||
use_backend ttrss_server if { req_ssl_sni -i ttrss.2li.ch }
|
||||
use_backend ttrss_server if { req_ssl_sni -i rss-bridge.2li.ch }
|
||||
use_backend proxy if { req_ssl_sni -i www.2li.ch }
|
||||
use_backend proxy if { req_ssl_sni -i 2li.ch }
|
||||
|
||||
backend grav_server
|
||||
mode tcp
|
||||
server server1 10.7.89.102:443 check
|
||||
backend git_server
|
||||
mode tcp
|
||||
server server1 10.7.89.109:443 check
|
||||
backend nextcloud_server
|
||||
mode tcp
|
||||
server server1 10.7.89.103:443 check
|
||||
backend ttrss_server
|
||||
mode tcp
|
||||
server server1 10.7.89.115:443 check
|
||||
backend mail_server
|
||||
mode tcp
|
||||
server server1 10.7.89.123:443 check
|
||||
backend proxy
|
||||
mode tcp
|
||||
server server1 127.0.0.1:4433 check
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
{ config, lib, ... }:
|
||||
let
|
||||
cfg = config.services.az-heimdall;
|
||||
in
|
||||
{
|
||||
options = {
|
||||
services.az-heimdall.enable = lib.mkEnableOption "Enable Heimdall";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
services.az-docker.enable = true;
|
||||
|
||||
virtualisation.oci-containers = {
|
||||
backend = "docker";
|
||||
containers."heimdall" = {
|
||||
# https://fleet.linuxserver.io/image?name=linuxserver/heimdall
|
||||
image = "linuxserver/heimdall:2.5.6";
|
||||
autoStart = true;
|
||||
environment = {
|
||||
TZ = "Europe/Zurich";
|
||||
PUID = "1000";
|
||||
PGID = "100";
|
||||
};
|
||||
ports = [
|
||||
"8081:80"
|
||||
];
|
||||
volumes = [
|
||||
"/etc/localtime:/etc/localtime:ro"
|
||||
];
|
||||
extraOptions = [
|
||||
''--mount=type=volume,source=heimdall,target=/config,volume-driver=local,volume-opt=type=nfs,volume-opt=device=:/server_data/heimdall,"volume-opt=o=addr=10.7.89.108,rw,nfsvers=4.0,nolock,hard,noatime"''
|
||||
"--log-opt=tag='heimdall'"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
let
|
||||
cfg = config.services.az-mariadb-for-containers;
|
||||
in
|
||||
{
|
||||
options = {
|
||||
services.az-mariadb-for-containers.enable = lib.mkEnableOption "Enable MariaDB configured for container clients.";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
services.mysql = {
|
||||
enable = true;
|
||||
package = pkgs.mariadb;
|
||||
settings = {
|
||||
mysqld = {
|
||||
bind-address = "172.17.0.1";
|
||||
};
|
||||
};
|
||||
};
|
||||
networking.firewall.extraCommands = "iptables -A INPUT -p tcp --destination-port 3306 -s 172.16.0.0/12 -j ACCEPT";
|
||||
};
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
{ config, lib, ... }:
|
||||
let
|
||||
cfg = config.services.az-media-share;
|
||||
in
|
||||
{
|
||||
options = {
|
||||
services.az-media-share.enable = lib.mkEnableOption "Mount the NFS share for with my media.";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
fileSystems."/mnt/media" = {
|
||||
device = "10.7.89.108:media";
|
||||
fsType = "nfs";
|
||||
options = [ "noatime" "hard" "nfsvers=4.0" ];
|
||||
};
|
||||
};
|
||||
}
|
|
@ -0,0 +1,139 @@
|
|||
{ config, inputs, lib, pkgs, ... }:
|
||||
let
|
||||
cfg = config.services.az-nextcloud;
|
||||
nextcloudEnvironment = {
|
||||
MYSQL_DATABASE = "nextcloud";
|
||||
MYSQL_USER = "nextcloud";
|
||||
MYSQL_HOST = "172.17.0.1";
|
||||
NEXTCLOUD_TRUSTED_DOMAINS = "${cfg.domain} ${config.networking.hostName}.2li.local 10.7.89.103";
|
||||
REDIS_HOST = "redis";
|
||||
SMTP_HOST = "mail.infomaniak.com";
|
||||
SMTP_SECURE = "ssl";
|
||||
SMTP_PORT = "465";
|
||||
};
|
||||
networkName = "nextcloud";
|
||||
# https://github.com/Nebucatnetzer/nextcloud-smb
|
||||
nextcloudImage = "ghcr.io/nebucatnetzer/nextcloud-smb/nextcloud-smb:26.0.1@sha256:f8773310c341d52104df01cd7c0c59ed4e502bcc5fa7b8304cb1f595680125e1";
|
||||
nextcloudService = "${config.virtualisation.oci-containers.backend}-nextcloud";
|
||||
cronService = "${config.virtualisation.oci-containers.backend}-cron";
|
||||
in
|
||||
{
|
||||
options = {
|
||||
services.az-nextcloud.enable = lib.mkEnableOption "Enable Nextcloud running in a container.";
|
||||
services.az-nextcloud.domain = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "The domain Nextcloud is being run from.";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
age.secrets.nextcloudEnv.file = "${inputs.self}/scrts/nextcloud_env.age";
|
||||
|
||||
services = {
|
||||
az-acme-base.enable = true;
|
||||
az-docker.enable = true;
|
||||
az-mariadb-for-containers.enable = true;
|
||||
mysql.settings = {
|
||||
mysqld = {
|
||||
innodb_file_per_table = 1;
|
||||
innodb_buffer_pool_size = "2G";
|
||||
read_rnd_buffer_size = "4M";
|
||||
sort_buffer_size = "4M";
|
||||
};
|
||||
};
|
||||
nginx = {
|
||||
appendHttpConfig = ''
|
||||
# Allow embedding from same domain
|
||||
add_header X-Frame-Options SAMEORIGIN;
|
||||
'';
|
||||
clientMaxBodySize = "20G";
|
||||
virtualHosts."${cfg.domain}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://127.0.0.1:8080";
|
||||
proxyWebsockets = true; # needed if you need to use WebSocket
|
||||
};
|
||||
extraConfig = ''
|
||||
# Required for large downloads
|
||||
proxy_buffering off;
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
virtualisation.oci-containers = {
|
||||
backend = "docker";
|
||||
containers."nextcloud" = {
|
||||
image = nextcloudImage;
|
||||
autoStart = true;
|
||||
environment = nextcloudEnvironment;
|
||||
environmentFiles = [ config.age.secrets.nextcloudEnv.path ];
|
||||
volumes = [
|
||||
"${inputs.self}/modules/nextcloud/custom-php.ini:/usr/local/etc/php/conf.d/zzz-custom.ini"
|
||||
"/etc/localtime:/etc/localtime:ro"
|
||||
];
|
||||
dependsOn = [ "redis" ];
|
||||
extraOptions = [
|
||||
''--mount=type=volume,source=nextcloud_data,target=/var/www/html,volume-driver=local,volume-opt=type=nfs,volume-opt=device=:/server_data/nextcloud/data,"volume-opt=o=addr=10.7.89.108,rw,nfsvers=4.0,nolock,hard,noatime"''
|
||||
"--add-host=host.docker.internal:host-gateway"
|
||||
"--net=${networkName}"
|
||||
"--log-opt=tag='nextcloud'"
|
||||
];
|
||||
};
|
||||
containers."nginx" = {
|
||||
image = "nginx:1.22.1";
|
||||
autoStart = true;
|
||||
ports = [
|
||||
"8080:80"
|
||||
];
|
||||
volumes = [
|
||||
"${inputs.self}/modules/nextcloud/nginx.conf:/etc/nginx/nginx.conf:ro"
|
||||
"/etc/localtime:/etc/localtime:ro"
|
||||
];
|
||||
extraOptions = [
|
||||
''--mount=type=volume,source=nextcloud_data,target=/var/www/html,volume-driver=local,volume-opt=type=nfs,volume-opt=device=:/server_data/nextcloud/data,"volume-opt=o=addr=10.7.89.108,ro,nfsvers=4.0,nolock,hard,noatime"''
|
||||
"--net=${networkName}"
|
||||
"--log-opt=tag='nextcloud-nginx'"
|
||||
];
|
||||
};
|
||||
containers."cron" = {
|
||||
image = nextcloudImage;
|
||||
autoStart = true;
|
||||
environment = nextcloudEnvironment;
|
||||
environmentFiles = [ config.age.secrets.nextcloudEnv.path ];
|
||||
entrypoint = "/cron.sh";
|
||||
dependsOn = [ "redis" ];
|
||||
volumes = [
|
||||
"/etc/localtime:/etc/localtime:ro"
|
||||
];
|
||||
extraOptions = [
|
||||
''--mount=type=volume,source=nextcloud_data,target=/var/www/html,volume-driver=local,volume-opt=type=nfs,volume-opt=device=:/server_data/nextcloud/data,"volume-opt=o=addr=10.7.89.108,rw,nfsvers=4.0,nolock,hard,noatime"''
|
||||
"--add-host=host.docker.internal:host-gateway"
|
||||
"--net=nextcloud"
|
||||
"--log-opt=tag='nextcloud-cron'"
|
||||
];
|
||||
};
|
||||
containers."redis" = {
|
||||
image = "redis:alpine";
|
||||
autoStart = true;
|
||||
volumes = [
|
||||
"/etc/localtime:/etc/localtime:ro"
|
||||
];
|
||||
extraOptions = [
|
||||
"--net=${networkName}"
|
||||
"--log-opt=tag='redis'"
|
||||
];
|
||||
};
|
||||
};
|
||||
system.activationScripts.makeDockerNetwork = ''
|
||||
${pkgs.docker}/bin/docker network ls | ${pkgs.gnugrep}/bin/grep ${networkName} || ${pkgs.docker}/bin/docker network create ${networkName}
|
||||
'';
|
||||
|
||||
environment.shellAliases = {
|
||||
occ = ''${pkgs.docker}/bin/docker exec -u www-data nextcloud php occ'';
|
||||
};
|
||||
systemd.services.${nextcloudService}.after = [ "mysql.service" "nginx.service" ];
|
||||
systemd.services.${cronService}.after = [ "mysql.service" ];
|
||||
};
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
{ config, lib, ... }:
|
||||
let
|
||||
cfg = config.services.az-acme-base;
|
||||
in
|
||||
{
|
||||
options = {
|
||||
services.az-acme-base.enable = lib.mkEnableOption "All the common options I need for ACME certs.";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
networking.firewall.allowedTCPPorts = [
|
||||
80
|
||||
443
|
||||
];
|
||||
security.acme = {
|
||||
acceptTerms = true;
|
||||
defaults.email = "admin+acme@zweili.ch";
|
||||
};
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
commonHttpConfig = ''
|
||||
# Add HSTS header with preloading to HTTPS requests.
|
||||
# Adding this header to HTTP requests is discouraged
|
||||
map $scheme $hsts_header {
|
||||
https "max-age=63072000; includeSubdomains; preload";
|
||||
}
|
||||
add_header Strict-Transport-Security $hsts_header;
|
||||
|
||||
# Enable CSP for your services.
|
||||
#add_header Content-Security-Policy "script-src 'self'; object-src 'none'; base-uri 'none';" always;
|
||||
|
||||
# Minimize information leaked to other domains
|
||||
add_header 'Referrer-Policy' 'origin-when-cross-origin';
|
||||
|
||||
# Prevent injection of code in other mime types (XSS Attacks)
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
|
||||
# Enable XSS protection of the browser.
|
||||
# May be unnecessary when CSP is configured properly (see above)
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
|
||||
# This might create errors
|
||||
proxy_cookie_path / "/; secure; HttpOnly; SameSite=strict";
|
||||
'';
|
||||
recommendedOptimisation = true;
|
||||
recommendedTlsSettings = true;
|
||||
};
|
||||
};
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
{ config, inputs, lib, pkgs, ... }:
|
||||
let
|
||||
cfg = config.services.az-rclone-webdav;
|
||||
pathToMonitor = "/home/${config.az-username}/10_documents/";
|
||||
syncNotes = pkgs.writeShellScriptBin "monitor-notes" ''
|
||||
${pkgs.rclone}/bin/rclone bisync -P --remove-empty-dirs --max-delete=10 --exclude=/99_archive/** nextcloud:10_documents ${pathToMonitor}
|
||||
'';
|
||||
in
|
||||
{
|
||||
options = {
|
||||
services.az-rclone-webdav.enable = lib.mkEnableOption "Sync my notes with rclone over webdav.";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
services.az-telegram-notifications.enable = true;
|
||||
|
||||
age.secrets.webdavSecrets = {
|
||||
file = "${inputs.self}/scrts/webdav_andreas.age";
|
||||
path = "/home/${config.az-username}/.config/rclone/rclone.conf";
|
||||
mode = "600";
|
||||
owner = "${config.az-username}";
|
||||
group = "users";
|
||||
};
|
||||
|
||||
systemd.timers."rclone-webdav-sync" = {
|
||||
wantedBy = [ "timers.target" ];
|
||||
partOf = [ "rclone-webdav-sync.service" ];
|
||||
timerConfig = {
|
||||
OnStartupSec = "5min";
|
||||
OnUnitActiveSec = "5min";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services."rclone-webdav-sync" = {
|
||||
after = [ "network-online.target" ];
|
||||
serviceConfig = {
|
||||
User = config.az-username;
|
||||
Type = "oneshot";
|
||||
};
|
||||
onFailure = [ "unit-status-telegram@%n.service" ];
|
||||
script = "${syncNotes}/bin/monitor-notes";
|
||||
};
|
||||
|
||||
systemd.services."rclone-webdav-monitor" = {
|
||||
requires = [ "network-online.target" ];
|
||||
after = [ "network-online.target" ];
|
||||
serviceConfig = {
|
||||
User = config.az-username;
|
||||
};
|
||||
onFailure = [ "unit-status-telegram@%n.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
script = ''
|
||||
${pkgs.inotify-tools}/bin/inotifywait -m -r -e create,modify,delete,move "${pathToMonitor}" |
|
||||
while read -r directory event file; do
|
||||
sleep 10
|
||||
${syncNotes}/bin/monitor-notes
|
||||
done
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
|
@ -2,11 +2,22 @@
|
|||
set -e
|
||||
|
||||
hosts=($(echo `nix eval .#nixosConfigurations --apply 'pkgs: builtins.concatStringsSep " " (builtins.attrNames pkgs)'` | xargs ))
|
||||
skip=(
|
||||
"desktop-vm"
|
||||
"gwyn"
|
||||
"loki-test"
|
||||
"test-raspi"
|
||||
"staubfinger"
|
||||
)
|
||||
|
||||
|
||||
for host in "${hosts[@]}"
|
||||
do
|
||||
if [[ " ${skip[*]} " =~ " ${host} " ]];then
|
||||
continue
|
||||
fi
|
||||
echo $host
|
||||
nix build -j auto --dry-run .#nixosConfigurations.${host}.config.system.build.toplevel
|
||||
nixos-rebuild dry-build --flake .#${host}
|
||||
echo
|
||||
echo
|
||||
done
|
||||
|
|
|
@ -15,9 +15,11 @@ in
|
|||
(import "${inputs.self}/modules/nginx-proxy" {
|
||||
inherit domain;
|
||||
})
|
||||
(import "${inputs.self}/modules/gitea" {
|
||||
inherit domain;
|
||||
})
|
||||
"${inputs.self}/modules/mariadb"
|
||||
];
|
||||
services = {
|
||||
az-gitea = {
|
||||
enable = true;
|
||||
domain = domain;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -12,7 +12,9 @@
|
|||
(import "${inputs.self}/modules/nginx-proxy" {
|
||||
domain = "mail.zweili.org";
|
||||
})
|
||||
"${inputs.self}/modules/docker-mailserver"
|
||||
];
|
||||
services = {
|
||||
az-mailserver.enable = true;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
ip = "10.7.89.150";
|
||||
inherit hostname;
|
||||
})
|
||||
"${inputs.self}/modules/rclone-webdav"
|
||||
(import "${inputs.self}/modules/restic-client-server" {
|
||||
path = "/home/andreas";
|
||||
tag = "management";
|
||||
|
@ -25,6 +24,7 @@
|
|||
az-data-share.enable = true;
|
||||
az-docker.enable = true;
|
||||
az-logs-share.enable = true;
|
||||
az-rclone-webdav.enable = true;
|
||||
};
|
||||
# Enable dictionaries
|
||||
programs = {
|
||||
|
|
|
@ -1,41 +1,20 @@
|
|||
{ hostname }: { inputs, pkgs, ... }:
|
||||
let
|
||||
domain = "nextcloud.2li.ch";
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
(import "${inputs.self}/systems/raspi4" {
|
||||
ip = "10.7.89.103";
|
||||
inherit hostname;
|
||||
})
|
||||
"${inputs.self}/modules/mariadb"
|
||||
(import "${inputs.self}/modules/nextcloud" {
|
||||
inherit domain;
|
||||
})
|
||||
"${inputs.self}/modules/nginx-acme-base"
|
||||
(import "${inputs.self}/modules/restic-client-server-mysql" {
|
||||
path = "/home/andreas";
|
||||
time = "01:30";
|
||||
})
|
||||
];
|
||||
|
||||
services.nginx = {
|
||||
appendHttpConfig = ''
|
||||
# Allow embedding from same domain
|
||||
add_header X-Frame-Options SAMEORIGIN;
|
||||
'';
|
||||
clientMaxBodySize = "20G";
|
||||
virtualHosts."${domain}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://127.0.0.1:8080";
|
||||
proxyWebsockets = true; # needed if you need to use WebSocket
|
||||
};
|
||||
extraConfig = ''
|
||||
# Required for large downloads
|
||||
proxy_buffering off;
|
||||
'';
|
||||
services = {
|
||||
az-nextcloud = {
|
||||
enable = true;
|
||||
domain = "nextcloud.2li.ch";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -10,7 +10,9 @@
|
|||
tag = "plex";
|
||||
time = "02:30";
|
||||
})
|
||||
"${inputs.self}/modules/media-share"
|
||||
"${inputs.self}/modules/plex"
|
||||
];
|
||||
services = {
|
||||
az-media-share.enable = true;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -9,54 +9,56 @@
|
|||
path = "/home/andreas";
|
||||
time = "00:00";
|
||||
})
|
||||
"${inputs.self}/modules/nginx-acme-base"
|
||||
"${inputs.self}/modules/grav"
|
||||
"${inputs.self}/modules/haproxy"
|
||||
"${inputs.self}/modules/heimdall"
|
||||
];
|
||||
|
||||
services.nginx = {
|
||||
commonHttpConfig = ''
|
||||
# Add HSTS header with preloading to HTTPS requests.
|
||||
# Adding this header to HTTP requests is discouraged
|
||||
# Enable CSP for your services.
|
||||
#add_header Content-Security-Policy "script-src 'self'; object-src 'none'; base-uri 'none';" always;
|
||||
services = {
|
||||
az-acme-base.enable = true;
|
||||
az-grav.enable = true;
|
||||
az-haproxy.enable = true;
|
||||
az-heimdall.enable = true;
|
||||
nginx = {
|
||||
commonHttpConfig = ''
|
||||
# Add HSTS header with preloading to HTTPS requests.
|
||||
# Adding this header to HTTP requests is discouraged
|
||||
# Enable CSP for your services.
|
||||
#add_header Content-Security-Policy "script-src 'self'; object-src 'none'; base-uri 'none';" always;
|
||||
|
||||
# Minimize information leaked to other domains
|
||||
add_header 'Referrer-Policy' 'origin-when-cross-origin';
|
||||
# Minimize information leaked to other domains
|
||||
add_header 'Referrer-Policy' 'origin-when-cross-origin';
|
||||
|
||||
# Disable embedding as a frame
|
||||
add_header X-Frame-Options DENY;
|
||||
# Disable embedding as a frame
|
||||
add_header X-Frame-Options DENY;
|
||||
|
||||
# Prevent injection of code in other mime types (XSS Attacks)
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
# Prevent injection of code in other mime types (XSS Attacks)
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
|
||||
# Enable XSS protection of the browser.
|
||||
# May be unnecessary when CSP is configured properly (see above)
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
# Enable XSS protection of the browser.
|
||||
# May be unnecessary when CSP is configured properly (see above)
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
|
||||
# This might create errors
|
||||
proxy_cookie_path / "/; secure; HttpOnly; SameSite=strict";
|
||||
'';
|
||||
recommendedProxySettings = true;
|
||||
virtualHosts = {
|
||||
"2li.ch" = {
|
||||
serverAliases = [ "www.2li.ch" ];
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
listen = [{ port = 4433; addr = "127.0.0.1"; ssl = true; }];
|
||||
locations."/" = {
|
||||
proxyPass = "http://127.0.0.1:8080";
|
||||
proxyWebsockets = true; # needed if you need to use WebSocket
|
||||
# This might create errors
|
||||
proxy_cookie_path / "/; secure; HttpOnly; SameSite=strict";
|
||||
'';
|
||||
recommendedProxySettings = true;
|
||||
virtualHosts = {
|
||||
"2li.ch" = {
|
||||
serverAliases = [ "www.2li.ch" ];
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
listen = [{ port = 4433; addr = "127.0.0.1"; ssl = true; }];
|
||||
locations."/" = {
|
||||
proxyPass = "http://127.0.0.1:8080";
|
||||
proxyWebsockets = true; # needed if you need to use WebSocket
|
||||
};
|
||||
};
|
||||
};
|
||||
"heimdall.2li.ch" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
listen = [{ port = 4433; addr = "127.0.0.1"; ssl = true; }];
|
||||
locations."/" = {
|
||||
proxyPass = "http://127.0.0.1:8081";
|
||||
proxyWebsockets = true; # needed if you need to use WebSocket
|
||||
"heimdall.2li.ch" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
listen = [{ port = 4433; addr = "127.0.0.1"; ssl = true; }];
|
||||
locations."/" = {
|
||||
proxyPass = "http://127.0.0.1:8081";
|
||||
proxyWebsockets = true; # needed if you need to use WebSocket
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue