diff --git a/machines/Home-Hypervisor/default.nix b/machines/Home-Hypervisor/default.nix index 10516e5..750bad6 100644 --- a/machines/Home-Hypervisor/default.nix +++ b/machines/Home-Hypervisor/default.nix @@ -22,8 +22,17 @@ in { nixosProfiles.mailserver nixosProfiles.nginx nixosProfiles.roundcube + nixosProfiles.tinyproxy nixosProfiles.vaultwarden nixosProfiles.vscode-server + + nixosProfiles.media-stack + nixosProfiles.copyparty + nixosProfiles.seafile + nixosProfiles.cocalc + # nixosProfiles.neko-browser + + nixosProfiles.yandex-db ]; deviceSpecific.devInfo = { @@ -86,7 +95,7 @@ in { services.zfs = { autoScrub.enable = true; - autoScrub.interval = "daily"; + autoScrub.interval = "weekly"; trim.enable = true; trim.interval = "weekly"; }; @@ -120,6 +129,8 @@ in { 127.0.0.1 code.ataraxiadev.com ''; + # networking.proxy.default = "http://127.0.0.1:3128"; + services.logind.lidSwitch = "lock"; services.logind.lidSwitchDocked = "lock"; services.logind.lidSwitchExternalPower = "lock"; diff --git a/profiles/overlay.nix b/profiles/overlay.nix index 362f128..188d91c 100644 --- a/profiles/overlay.nix +++ b/profiles/overlay.nix @@ -93,6 +93,10 @@ with lib; { narodmon-py = prev.writers.writePython3Bin "temp.py" { libraries = with prev.python3Packages; [ requests ]; } ./packages/narodmon-py.nix; + + yandex-taxi-py = prev.writers.writePython3 "yandex-taxi.py" { + libraries = with prev.python3Packages; [ requests ]; + } ./packages/yandex-taxi-py.nix; } ) ]; diff --git a/profiles/packages/yandex-taxi-py.nix b/profiles/packages/yandex-taxi-py.nix new file mode 100644 index 0000000..fff1abc --- /dev/null +++ b/profiles/packages/yandex-taxi-py.nix @@ -0,0 +1,92 @@ +'' +import datetime +import requests +import json +import io +import sqlite3 +from sqlite3 import Error +from requests.exceptions import RequestException + + +database = "/srv/yandex.db" +params_file = "/var/secrets/yandex-token" + + +def create_connection(db_file): + conn = None + try: + conn = sqlite3.connect(db_file, + detect_types=sqlite3.PARSE_DECLTYPES | + sqlite3.PARSE_COLNAMES) + except Error as e: + SystemExit(e) + return conn + + +def create_ride(conn): + sql = """ CREATE TABLE IF NOT EXISTS RIDE ( + distance REAL NOT NULL, + class_name TEXT NOT NULL, + min_price INT NOT NULL, + price INT NOT NULL, + waiting_time INT NOT NULL, + time INT NOT NULL, + timestamp TIMESTAMP NOT NULL) """ + cur = conn.cursor() + cur.execute(sql) + conn.commit() + return cur.lastrowid + + +def insert_ride(conn, ride): + sql = """ INSERT INTO ride(distance,class_name,min_price, + price,waiting_time,time,timestamp) + VALUES(?,?,?,?,?,?,?) """ + cur = conn.cursor() + cur.execute(sql, ride) + conn.commit() + return cur.lastrowid + + +def get_api_json(json_data): + headers = json_data['headers'] + params = json_data['params'] + uri = 'https://taxi-routeinfo.taxi.yandex.net/taxi_info' + + try: + r = requests.get(uri, params=params, headers=headers) + except RequestException as e: + raise SystemExit(e) + return r.json() + + +def read_params(filename): + try: + with io.open(filename, 'r', encoding='utf-8') as in_file: + json_data = json.load(in_file) + except Exception as e: + SystemExit(e) + return json_data + + +def main(): + conn = create_connection(database) + with conn: + create_ride(conn) + + params_json = read_params(params_file) + json_data = get_api_json(params_json) + currentDateTime = datetime.datetime.now() + + for i in range(2): + opt = json_data['options'][i] + ride = (json_data['distance'], opt['class_name'], + opt['min_price'], opt['price'], + opt['waiting_time'], json_data['time'], + currentDateTime) + insert_ride(conn, ride) + + +if __name__ == '__main__': + main() +'' diff --git a/profiles/servers/authentik.nix b/profiles/servers/authentik.nix index d540a49..52b0275 100644 --- a/profiles/servers/authentik.nix +++ b/profiles/servers/authentik.nix @@ -3,10 +3,17 @@ let backend = config.virtualisation.oci-containers.backend; data-dir = "/srv/authentik"; pod-name = "authentik-pod"; - open-ports = [ "127.0.0.1:9000:9000/tcp" "127.0.0.1:9443:9443/tcp" ]; + open-ports = [ + # authentik + "9000:9000/tcp" "9443:9443/tcp" + # ldap + "389:3389/tcp" "636:6636/tcp" + ]; owner = "1000"; + authentik-version = "2023.1.2"; in { - secrets.authentik-env = { }; + secrets.authentik-env.services = [ "${backend}-authentik-server.service" ]; + secrets.authentik-ldap.services = [ "${backend}-authentik-ldap.service" ]; virtualisation.oci-containers.containers = { authentik-postgresql = { @@ -30,7 +37,7 @@ in { authentik-server = { autoStart = true; dependsOn = [ "authentik-postgresql" "authentik-redis" ]; - image = "ghcr.io/goauthentik/server:2023.1.2"; + image = "ghcr.io/goauthentik/server:${authentik-version}"; cmd = [ "server" ]; extraOptions = [ "--pod=${pod-name}" ]; environment = { @@ -46,7 +53,7 @@ in { authentik-worker = { autoStart = true; dependsOn = [ "authentik-server" ]; - image = "ghcr.io/goauthentik/server:2023.1.2"; + image = "ghcr.io/goauthentik/server:${authentik-version}"; cmd = [ "worker" ]; extraOptions = [ "--pod=${pod-name}" ]; environment = { @@ -62,6 +69,17 @@ in { "${data-dir}/custom-templates:/templates" ]; }; + authentik-ldap = { + autoStart = true; + dependsOn = [ "authentik-server" ]; + image = "ghcr.io/goauthentik/ldap:${authentik-version}"; + extraOptions = [ "--pod=${pod-name}" ]; + environment = { + AUTHENTIK_HOST = "https://auth.ataraxiadev.com"; + AUTHENTIK_INSECURE = "false"; + }; + environmentFiles = [ config.secrets.authentik-ldap.decrypted ]; + }; }; systemd.services."podman-create-${pod-name}" = let @@ -84,6 +102,7 @@ in { "${backend}-authentik-redis.service" "${backend}-authentik-server.service" "${backend}-authentik-worker.service" + "${backend}-authentik-ldap.service" ]; wantedBy = before; partOf = before; diff --git a/profiles/servers/cocalc.nix b/profiles/servers/cocalc.nix new file mode 100644 index 0000000..123d864 --- /dev/null +++ b/profiles/servers/cocalc.nix @@ -0,0 +1,15 @@ +{ config, lib, pkgs, ... }: +let + backend = config.virtualisation.oci-containers.backend; + nas-path = "/media/nas/containers"; +in { + virtualisation.oci-containers.containers.cocalc = { + autoStart = true; + image = "docker.io/ataraxiadev/cocalc-latex:1b335d368d26"; + ports = [ "127.0.0.1:9099:443/tcp" ]; + volumes = [ + "${nas-path}/cocalc:/projects" + "${nas-path}/databases/cocalc:/projects/postgres" + ]; + }; +} \ No newline at end of file diff --git a/profiles/servers/copyparty.nix b/profiles/servers/copyparty.nix new file mode 100644 index 0000000..ac67533 --- /dev/null +++ b/profiles/servers/copyparty.nix @@ -0,0 +1,25 @@ +{ config, lib, pkgs, ... }: +let + backend = config.virtualisation.oci-containers.backend; + nas-path = "/media/nas"; +in { + virtualisation.oci-containers.containers.copyparty = { + autoStart = true; + image = "docker.io/copyparty/min"; + cmd = [ + "--xdev" "--xvol" + # "-e2dsa" "-e2ts" + # "--re-maxage 600" + # "--hist /cache/copyparty" + # "--no-robots" + "-q" "--http-only" "--no-dav" + "-s" "--no-logues" "--no-readme" + # "-i localhost" + ]; + ports = [ "127.0.0.1:3923:3923/tcp" ]; + user = "1000:100"; + volumes = [ + "${nas-path}:/w" + ]; + }; +} \ No newline at end of file diff --git a/profiles/servers/duplicacy.nix b/profiles/servers/duplicacy.nix index f761914..9aef177 100644 --- a/profiles/servers/duplicacy.nix +++ b/profiles/servers/duplicacy.nix @@ -1,90 +1,3 @@ -# { config, lib, pkgs, ... }: -# let -# start-backup = '' -# #!${pkgs.runtimeShell} -# export DUPLICACY_GCD_TOKEN=/var/secrets/gcd-token -# export DUPLICACY_PASSWORD=$(cat /var/secrets/duplicacy-pass) - -# if [ ! -d "/backups/.duplicacy" ]; then -# echo "First init duplicacy repo with \"duplicacy init -e gcd://\"" -# exit 1 -# fi - -# if [ ! -d "/backups/var" ]; then -# mkdir -p /backups/var -# fi - -# if [ ! -L "/backups/var/dkim" ]; then -# ln -s /var/dkim /backups/var/dkim -# fi - -# if [ ! -L "/backups/var/vmail" ]; then -# ln -s /var/vmail /backups/var/vmail -# fi - -# if [ ! -L "/backups/var/microbin" ]; then -# ln -s /var/microbin /backups/var/microbin -# fi - -# if [ ! -L "/backups/gitea" ]; then -# ln -s /gitea /backups/gitea -# fi - -# if [ ! -d "/backups/srv" ]; then -# mkdir -p /backups/var -# fi - -# if [ ! -L "/backups/srv/joplin" ]; then -# ln -s /srv/joplin /backups/srv/joplin -# fi - -# cd /backups -# duplicacy backup -# ''; -# start-prune = '' -# #!${pkgs.runtimeShell} -# export DUPLICACY_GCD_TOKEN=/var/secrets/gcd-token; -# export DUPLICACY_PASSWORD=$(cat /var/secrets/duplicacy-pass); - -# if [ ! -d "/backups/.duplicacy" ]; then -# echo "First init duplicacy repo with \"duplicacy init -e gcd://\"" -# exit 1 -# fi -# cd /backups -# duplicacy prune -keep 0:30 -keep 7:14 -keep 1:7 -# ''; -# in { -# secrets.gcd-token.services = [ ]; -# secrets.duplicacy-pass.services = [ ]; - -# systemd.services.duplicacy-backup = { -# serviceConfig.Type = "oneshot"; -# path = [ pkgs.duplicacy ]; -# script = start-backup; -# }; - -# systemd.timers.duplicacy-backup = { -# wantedBy = [ "timers.target" ]; -# partOf = [ "duplicacy-backup.service" ]; -# timerConfig.OnCalendar = [ "*-*-* 05:00:00" ]; -# }; - -# systemd.services.duplicacy-prune = { -# serviceConfig.Type = "oneshot"; -# path = [ pkgs.duplicacy ]; -# script = start-prune; -# }; - -# systemd.timers.duplicacy-prune = { -# wantedBy = [ "timers.target" ]; -# partOf = [ "duplicacy-prune.service" ]; -# timerConfig.OnCalendar = [ "*-*-* 01:00:00" ]; -# }; - -# # FIXME! -# persist.state.directories = lib.mkIf config.deviceSpecific.devInfo.fileSystem != "zfs" -# [ "/backup" ]; -# } { config, lib, pkgs, ... }: let backend = config.virtualisation.oci-containers.backend; diff --git a/profiles/servers/fail2ban.nix b/profiles/servers/fail2ban.nix index 1a90389..0859317 100644 --- a/profiles/servers/fail2ban.nix +++ b/profiles/servers/fail2ban.nix @@ -1,5 +1,5 @@ { config, pkgs, lib, ... }: { - services.openssh.logLevel = "VERBOSE"; + services.openssh.settings.LogLevel = "VERBOSE"; services.fail2ban = { enable = true; diff --git a/profiles/servers/gitea.nix b/profiles/servers/gitea.nix index 4ebd4bb..c0fd04f 100644 --- a/profiles/servers/gitea.nix +++ b/profiles/servers/gitea.nix @@ -17,6 +17,7 @@ in { # TODO: backups! gitea.dump setting services.gitea = { enable = true; + package = pkgs.forgejo; appName = "AtaraxiaDev's Gitea Instance"; database = { type = "postgres"; @@ -46,7 +47,6 @@ in { }; mailer = { ENABLED = true; - # PROTOCOL = "smtp+starttls"; PROTOCOL = "smtps"; SMTP_ADDR = "mail.ataraxiadev.com"; USER = "gitea@ataraxiadev.com"; diff --git a/profiles/servers/mailserver.nix b/profiles/servers/mailserver.nix index 52f6062..c8d8ae0 100644 --- a/profiles/servers/mailserver.nix +++ b/profiles/servers/mailserver.nix @@ -14,6 +14,7 @@ in { secrets.mailserver-seafile = secrets-default; secrets.mailserver-gitea = secrets-default; secrets.mailserver-authentik = secrets-default; + secrets.mailserver-kavita = secrets-default; security.acme.certs."mail.ataraxiadev.com" = { webroot = "/var/lib/acme/acme-challenge"; @@ -81,6 +82,10 @@ in { aliases = [ "joplin" ]; hashedPasswordFile = config.secrets.mailserver-joplin.decrypted; }; + "kavita@ataraxiadev.com" = { + aliases = [ "kavita" ]; + hashedPasswordFile = config.secrets.mailserver-kavita.decrypted; + }; "vaultwarden@ataraxiadev.com" = { aliases = [ "vaultwarden" ]; hashedPasswordFile = config.secrets.mailserver-vaultwarden.decrypted; @@ -113,6 +118,7 @@ in { # "/var/lib/dovecot" # "/var/lib/postfix" # "/var/lib/dhparams" + "/var/sieve" ] ++ lib.optionals (config.deviceSpecific.devInfo.fileSystem != "zfs") [ config.mailserver.dkimKeyDirectory config.mailserver.mailDirectory diff --git a/profiles/servers/media-stack/bazarr.nix b/profiles/servers/media-stack/bazarr.nix deleted file mode 100644 index 8bad096..0000000 --- a/profiles/servers/media-stack/bazarr.nix +++ /dev/null @@ -1,20 +0,0 @@ -{ config, lib, pkgs, ... }: { - virtualisation.oci-containers.containers.bazarr = { - autoStart = true; - environment = { - PUID = "1015"; - PGID = "1005"; - UMASK = "002"; - TZ = "Europe/Moscow"; - }; - extraOptions = [ - "--network=media" - ]; - image = "cr.hotio.dev/hotio/bazarr:release-1.0.3"; - volumes = [ - "/etc/localtime:/etc/localtime:ro" - "/media/configs/bazarr/config:/config" - "/media/data:/data" - ]; - }; -} \ No newline at end of file diff --git a/profiles/servers/media-stack/botdarr.nix b/profiles/servers/media-stack/botdarr.nix deleted file mode 100644 index 57af068..0000000 --- a/profiles/servers/media-stack/botdarr.nix +++ /dev/null @@ -1,37 +0,0 @@ -{ config, lib, pkgs, ... }: -with config.virtualisation.oci-containers; { - secrets.botdarr-telegram = { - services = [ "${backend}-botdarr-telegram.service" ]; - }; - secrets.botdarr-matrix = { - services = [ "${backend}-botdarr-matrix.service" ]; - }; - - virtualisation.oci-containers.containers.botdarr-telegram = { - autoStart = true; - extraOptions = [ - "--network=media" - ]; - image = "shayaantx/botdarr:5.3.4"; - volumes = [ - "/etc/localtime:/etc/localtime:ro" - "/media/configs/botdarr-telegram/logs:/home/botdarr/logs" - "/media/configs/botdarr-telegram/database:/home/botdarr/database" - "${config.secrets.botdarr-telegram.decrypted}:/home/botdarr/config/properties:ro" - ]; - }; - - virtualisation.oci-containers.containers.botdarr-matrix = { - autoStart = true; - extraOptions = [ - "--network=media" - ]; - image = "shayaantx/botdarr:5.3.4"; - volumes = [ - "/etc/localtime:/etc/localtime:ro" - "/media/configs/botdarr-matrix/logs:/home/botdarr/logs" - "/media/configs/botdarr-matrix/database:/home/botdarr/database" - "${config.secrets.botdarr-matrix.decrypted}:/home/botdarr/config/properties:ro" - ]; - }; -} \ No newline at end of file diff --git a/profiles/servers/media-stack/caddy.nix b/profiles/servers/media-stack/caddy.nix index ecf35ee..36d0781 100644 --- a/profiles/servers/media-stack/caddy.nix +++ b/profiles/servers/media-stack/caddy.nix @@ -1,67 +1,53 @@ { config, lib, pkgs, ... }: let + backend = config.virtualisation.oci-containers.backend; + nas-path = "/media/nas/media-stack"; caddyconf = pkgs.writeText "Caddyfile" '' { auto_https off - http_port 8080 + http_port 8180 log { output file /config/logs/access.log } } - jellyfin.ataraxiadev.com:8080 { + jellyfin.ataraxiadev.com:8180 { reverse_proxy jellyfin:8096 } - radarr.ataraxiadev.com:8080 { - reverse_proxy radarr:7878 - } - qbit.ataraxiadev.com:8080 { + qbit.ataraxiadev.com:8180 { reverse_proxy qbittorrent:8080 } - prowlarr.ataraxiadev.com:8080 { - reverse_proxy prowlarr:9696 + medusa.ataraxiadev.com:8180 { + reverse_proxy medusa:8081 } - sonarr.ataraxiadev.com:8080 { - reverse_proxy sonarr-anime:8989 + jackett.ataraxiadev.com:8180 { + reverse_proxy jackett:9117 } - sonarrtv.ataraxiadev.com:8080 { - reverse_proxy sonarr-tv:8989 + sonarr.ataraxiadev.com:8180 { + reverse_proxy sonarr:8989 } - organizr.ataraxiadev.com:8080 { - reverse_proxy organizr:80 + radarr.ataraxiadev.com:8180 { + reverse_proxy radarr:7878 } - lidarr.ataraxiadev.com:8080 { + lidarr.ataraxiadev.com:8180 { reverse_proxy lidarr:8686 } - bazarr.ataraxiadev.com:8080 { - reverse_proxy bazarr:6767 - } - nzbhydra.ataraxiadev.com:8080 { - reverse_proxy nzbhydra2:5076 - } - kavita.ataraxiadev.com:8080 { + kavita.ataraxiadev.com:8180 { reverse_proxy kavita:5000 } - shoko.ataraxiadev.com:8080 { - reverse_proxy shokoserver:8111 - } ''; in { virtualisation.oci-containers.containers.media-caddy = { autoStart = true; + image = "cr.hotio.dev/hotio/caddy:release-2.6.4"; environment = { - PUID = "1009"; - PGID = "1005"; + PUID = "1000"; + PGID = "100"; UMASK = "002"; TZ = "Europe/Moscow"; }; - extraOptions = [ - "--network=media" - ]; - ports = [ "127.0.0.1:8100:8080" ]; - image = "cr.hotio.dev/hotio/caddy:release-2.5.1"; + extraOptions = [ "--pod=media-stack" ]; volumes = [ - "/etc/localtime:/etc/localtime:ro" - "/media/configs/caddy/config:/config" + "${nas-path}/configs/caddy:/config" "${caddyconf}:/config/Caddyfile" ]; }; diff --git a/profiles/servers/media-stack/default.nix b/profiles/servers/media-stack/default.nix index d7a047e..0416e74 100644 --- a/profiles/servers/media-stack/default.nix +++ b/profiles/servers/media-stack/default.nix @@ -1,64 +1,52 @@ -{ config, pkgs, ... }: -with config.virtualisation.oci-containers; { +{ config, lib, pkgs, ... }: +let + backend = config.virtualisation.oci-containers.backend; + pod-name = "media-stack"; + open-ports = [ + # caddy + "127.0.0.1:8180:8180" + ]; +in { imports = [ - ./bazarr.nix - # ./botdarr.nix ./caddy.nix + ./jackett.nix ./jellyfin.nix ./kavita.nix ./lidarr.nix - ./nzbhydra2.nix - ./organizr.nix - ./prowlarr.nix + ./medusa.nix ./qbittorrent.nix ./radarr.nix - # ./shoko.nix + ./recyclarr.nix ./sonarr.nix ]; - secrets.xray-config = { - services = [ "${backend}-xray.service" ]; - }; - - virtualisation.oci-containers.containers.xray = { - autoStart = true; - environment = { - TZ = "Europe/Moscow"; - }; - extraOptions = [ - "--network=media" - ]; - image = "teddysun/xray:1.5.4"; - volumes = [ - "/etc/localtime:/etc/localtime:ro" - "${config.secrets.xray-config.decrypted}:/etc/xray/config.json" - ]; - }; - - systemd.services.create-media-network = { - serviceConfig.Type = "oneshot"; - wantedBy = [ - "${backend}-bazarr.service" - # "${backend}-botdarr-matrix.service" - # "${backend}-botdarr-telegram.service" - "${backend}-jellyfin.service" - "${backend}-kavita.service" - "${backend}-lidarr.service" - "${backend}-media-caddy.service" - "${backend}-nzbhydra2.service" - "${backend}-organizr.service" - "${backend}-prowlarr.service" - "${backend}-qbittorrent.service" - "${backend}-radarr.service" - # "${backend}-shokoserver.service" - "${backend}-sonarr-anime.service" - "${backend}-sonarr-tv.service" - "${backend}-xray.service" - ]; - script = '' - ${pkgs.docker}/bin/docker network inspect media || \ - ${pkgs.docker}/bin/docker network create -d bridge media + systemd.services."podman-create-${pod-name}" = let + portsMapping = lib.concatMapStrings (port: " -p " + port) open-ports; + start = pkgs.writeShellScript "create-pod" '' + podman pod exists ${pod-name} && podman pod rm -i ${pod-name} || podman pod create -n ${pod-name} ${portsMapping} exit 0 ''; + in rec { + path = [ pkgs.coreutils config.virtualisation.podman.package ]; + before = [ + "${backend}-media-caddy.service" + "${backend}-jackett.service" + "${backend}-jellyfin.service" + "${backend}-kavita.service" + "${backend}-kavitaemail.service" + "${backend}-lidarr.service" + "${backend}-medusa.service" + "${backend}-qbittorrent.service" + "${backend}-radarr.service" + "${backend}-recyclarr.service" + "${backend}-sonarr.service" + ]; + wantedBy = before; + partOf = before; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = "yes"; + ExecStart = start; + }; }; -} +} \ No newline at end of file diff --git a/profiles/servers/media-stack/jackett.nix b/profiles/servers/media-stack/jackett.nix new file mode 100644 index 0000000..52b1232 --- /dev/null +++ b/profiles/servers/media-stack/jackett.nix @@ -0,0 +1,20 @@ +{ config, lib, pkgs, ... }: +let + backend = config.virtualisation.oci-containers.backend; + nas-path = "/media/nas/media-stack"; +in { + virtualisation.oci-containers.containers.jackett = { + autoStart = true; + environment = { + PUID = "1000"; + PGID = "100"; + UMASK = "002"; + TZ = "Europe/Moscow"; + }; + extraOptions = [ "--pod=media-stack" ]; + image = "cr.hotio.dev/hotio/jackett:release-0.20.3546"; + volumes = [ + "${nas-path}/configs/jackett:/config" + ]; + }; +} \ No newline at end of file diff --git a/profiles/servers/media-stack/jellyfin.nix b/profiles/servers/media-stack/jellyfin.nix index a0e1cff..3606ab0 100644 --- a/profiles/servers/media-stack/jellyfin.nix +++ b/profiles/servers/media-stack/jellyfin.nix @@ -1,20 +1,22 @@ -{ config, lib, pkgs, ... }: { +{ config, lib, pkgs, ... }: +let + backend = config.virtualisation.oci-containers.backend; + nas-path = "/media/nas/media-stack"; +in { virtualisation.oci-containers.containers.jellyfin = { autoStart = true; + image = "cr.hotio.dev/hotio/jellyfin:release-10.8.9-1"; environment = { - PUID = "1010"; - PGID = "1005"; + PUID = "1000"; + PGID = "100"; UMASK = "002"; TZ = "Europe/Moscow"; }; - extraOptions = [ - "--network=media" - ]; - image = "cr.hotio.dev/hotio/jellyfin:release-10.7.7-1"; + extraOptions = [ "--pod=media-stack" "--device=/dev/dri:/dev/dri" ]; + # ports = [ "127.0.0.1:8096:8096/tcp" ]; volumes = [ - "/etc/localtime:/etc/localtime:ro" - "/media/configs/jellyfin/config:/config" - "/media/data/media:/data/media" + "${nas-path}/configs/jellyfin:/config" + "${nas-path}/media:/data/media" ]; }; } \ No newline at end of file diff --git a/profiles/servers/media-stack/kavita.nix b/profiles/servers/media-stack/kavita.nix index 9030fff..d82679e 100644 --- a/profiles/servers/media-stack/kavita.nix +++ b/profiles/servers/media-stack/kavita.nix @@ -1,20 +1,40 @@ -{ config, lib, pkgs, ... }: { - virtualisation.oci-containers.containers.kavita = { - autoStart = true; - environment = { - PUID = "1022"; - PGID = "1005"; - UMASK = "002"; - TZ = "Europe/Moscow"; +{ config, lib, pkgs, ... }: +let + backend = config.virtualisation.oci-containers.backend; + nas-path = "/media/nas/media-stack"; +in { + secrets.mailserver-kavita = { }; + + virtualisation.oci-containers.containers = { + kavita = { + autoStart = true; + image = "docker.io/ataraxiadev/kavita:latest"; + environment = { + PUID = "1000"; + PGID = "100"; + }; + extraOptions = [ "--pod=media-stack" ]; + volumes = [ + "/etc/localtime:/etc/localtime:ro" + "${nas-path}/configs/kavita:/kavita/config" + "${nas-path}/media/manga:/manga/manga" + "${nas-path}/media/books:/manga/books" + "${nas-path}/media/comics:/manga/comics" + ]; + }; + kavitaemail = { + autoStart = true; + image = "docker.io/kizaing/kavitaemail:latest"; + environment = { + SMTP_HOST = "https://mail.ataraxiadev.com"; + SMTP_PORT = "587"; + SMTP_USER = "kavita@ataraxiadev.com"; + SEND_ADDR = "kavita@ataraxiadev.com"; + DISP_NAME = "Kavita "; + ALLOW_SENDTO = "false"; + }; + environmentFiles = [ config.secrets.mailserver-kavita.decrypted ]; + extraOptions = [ "--pod=media-stack" ]; }; - extraOptions = [ - "--network=media" - ]; - image = "kizaing/kavita:0.5.2"; - volumes = [ - "/etc/localtime:/etc/localtime:ro" - "/media/configs/kavita/config:/kavita/config" - "/media/data/media/books:/books" - ]; }; } \ No newline at end of file diff --git a/profiles/servers/media-stack/lidarr.nix b/profiles/servers/media-stack/lidarr.nix index ee923db..3e55953 100644 --- a/profiles/servers/media-stack/lidarr.nix +++ b/profiles/servers/media-stack/lidarr.nix @@ -1,20 +1,54 @@ -{ config, lib, pkgs, ... }: { +{ config, lib, pkgs, ... }: +let + backend = config.virtualisation.oci-containers.backend; + nas-path = "/media/nas/media-stack"; +in { virtualisation.oci-containers.containers.lidarr = { autoStart = true; environment = { - PUID = "1014"; - PGID = "1005"; - UMASK = "002"; + PUID = "1000"; + PGID = "100"; TZ = "Europe/Moscow"; + scriptInterval = "15m"; + enableAudioScript = "true"; + enableVideoScript = "false"; + # enableVideoScript = "true"; + # videoDownloadTag = "video"; + configureLidarrWithOptimalSettings = "true"; + searchSort = "date"; + audioFormat = "native"; + audioBitrate = "lossless"; + requireQuality = "true"; + enableReplaygainTags = "true"; + audioLyricType = "both"; + # dlClientSource = "both"; + dlClientSource = "tidal"; + # arlToken = "Token_Goes_Here"; + tidalCountryCode = "AR"; + addDeezerTopArtists = "false"; + addDeezerTopAlbumArtists = "false"; + addDeezerTopTrackArtists = "false"; + topLimit = "10"; + addRelatedArtists = "false"; + numberOfRelatedArtistsToAddPerArtist = "5"; + lidarrSearchForMissing = "true"; + addFeaturedVideoArtists = "false"; + youtubeSubtitleLanguage = "en,ru"; + # webHook = ""; + enableQueueCleaner = "true"; + matchDistance = "5"; + enableBeetsTagging = "true"; + beetsMatchPercentage = "90"; + retryNotFound = "90"; }; - extraOptions = [ - "--network=media" - ]; - image = "cr.hotio.dev/hotio/lidarr:release-0.8.1.2135"; + extraOptions = [ "--pod=media-stack" ]; + image = "docker.io/randomninjaatk/lidarr-extended:latest"; volumes = [ - "/etc/localtime:/etc/localtime:ro" - "/media/configs/lidarr/config:/config" - "/media/data:/data" + "${nas-path}/configs/lidarr:/config" + "${nas-path}/torrents/music:/downloads" + "${nas-path}/torrents/lidarr-extended-downloads:/downloads-lidarr-extended" + "${nas-path}/media/music:/music" + "${nas-path}/media/music-videos:/music-videos" ]; }; } diff --git a/profiles/servers/media-stack/medusa.nix b/profiles/servers/media-stack/medusa.nix new file mode 100644 index 0000000..704dce0 --- /dev/null +++ b/profiles/servers/media-stack/medusa.nix @@ -0,0 +1,25 @@ +{ config, lib, pkgs, ... }: +let + backend = config.virtualisation.oci-containers.backend; + nas-path = "/media/nas/media-stack"; +in { + virtualisation.oci-containers.containers.medusa = { + autoStart = true; + image = "docker.io/pymedusa/medusa"; + environment = { + PUID = "1000"; + PGID = "100"; + TZ = "Europe/Moscow"; + # HTTP_PROXY = "http://192.168.0.6:8888"; + # HTTPS_PROXY = "http://192.168.0.6:8888"; + }; + extraOptions = [ "--pod=media-stack" ]; + # ports = [ "127.0.0.1:8081:8081/tcp" ]; + volumes = [ + "${nas-path}/configs/medusa:/config" + "${nas-path}:/data" + # "${nas-path}/torrents:/downloads" + # "${nas-path}/media/anime:/tv" + ]; + }; +} \ No newline at end of file diff --git a/profiles/servers/media-stack/nzbhydra2.nix b/profiles/servers/media-stack/nzbhydra2.nix deleted file mode 100644 index 7095fe7..0000000 --- a/profiles/servers/media-stack/nzbhydra2.nix +++ /dev/null @@ -1,20 +0,0 @@ -{ config, lib, pkgs, ... }: { - virtualisation.oci-containers.containers.nzbhydra2 = { - autoStart = true; - environment = { - PUID = "1020"; - PGID = "1005"; - UMASK = "002"; - TZ = "Europe/Moscow"; - }; - extraOptions = [ - "--network=media" - ]; - image = "cr.hotio.dev/hotio/nzbhydra2:release-4.3.1"; - volumes = [ - "/etc/localtime:/etc/localtime:ro" - "/media/configs/nzbhydra2/config:/config" - # "/media/data:/data" - ]; - }; -} \ No newline at end of file diff --git a/profiles/servers/media-stack/organizr.nix b/profiles/servers/media-stack/organizr.nix deleted file mode 100644 index 761d2d1..0000000 --- a/profiles/servers/media-stack/organizr.nix +++ /dev/null @@ -1,19 +0,0 @@ -{ config, lib, pkgs, ... }: { - virtualisation.oci-containers.containers.organizr = { - autoStart = true; - environment = { - PUID = "1017"; - PGID = "1005"; - UMASK = "002"; - TZ = "Europe/Moscow"; - }; - extraOptions = [ - "--network=media" - ]; - image = "organizr/organizr"; - volumes = [ - "/etc/localtime:/etc/localtime:ro" - "/media/configs/organizr/config:/config" - ]; - }; -} \ No newline at end of file diff --git a/profiles/servers/media-stack/prowlarr.nix b/profiles/servers/media-stack/prowlarr.nix index be3d7d3..3e0e28d 100644 --- a/profiles/servers/media-stack/prowlarr.nix +++ b/profiles/servers/media-stack/prowlarr.nix @@ -1,20 +1,21 @@ -{ config, lib, pkgs, ... }: { +{ config, lib, pkgs, ... }: +let + backend = config.virtualisation.oci-containers.backend; + nas-path = "/media/nas/media-stack"; +in { virtualisation.oci-containers.containers.prowlarr = { autoStart = true; environment = { - PUID = "1016"; - PGID = "1005"; + PUID = "1000"; + PGID = "100"; UMASK = "002"; TZ = "Europe/Moscow"; }; - extraOptions = [ - "--network=media" - ]; - image = "cr.hotio.dev/hotio/prowlarr:testing-0.3.0.1730"; + extraOptions = [ "--pod=media-stack" ]; + image = "cr.hotio.dev/hotio/prowlarr:release-1.2.2.2699"; volumes = [ - "/etc/localtime:/etc/localtime:ro" - "/media/configs/prowlarr/config:/config" - "/media/data/torrents:/data/torrents" + "${nas-path}/configs/prowlarr:/config" + "${nas-path}/torrents:/data" ]; }; } \ No newline at end of file diff --git a/profiles/servers/media-stack/qbittorrent.nix b/profiles/servers/media-stack/qbittorrent.nix index 6da27c1..420a4c4 100644 --- a/profiles/servers/media-stack/qbittorrent.nix +++ b/profiles/servers/media-stack/qbittorrent.nix @@ -1,20 +1,22 @@ -{ config, lib, pkgs, ... }: { +{ config, lib, pkgs, ... }: +let + backend = config.virtualisation.oci-containers.backend; + nas-path = "/media/nas/media-stack"; +in { virtualisation.oci-containers.containers.qbittorrent = { autoStart = true; + image = "cr.hotio.dev/hotio/qbittorrent:release-4.5.2"; environment = { - PUID = "1018"; - PGID = "1005"; + PUID = "1000"; + PGID = "100"; UMASK = "002"; TZ = "Europe/Moscow"; }; - extraOptions = [ - "--network=media" - ]; - image = "cr.hotio.dev/hotio/qbittorrent:release-4.4.2"; + extraOptions = [ "--pod=media-stack" ]; + # ports = [ "127.0.0.1:8082:8080/tcp" ]; volumes = [ - "/etc/localtime:/etc/localtime:ro" - "/media/configs/qbittorrent/config:/config" - "/media/data/torrents:/data/torrents" + "${nas-path}/configs/qbittorrent:/config" + "${nas-path}:/data" ]; }; } \ No newline at end of file diff --git a/profiles/servers/media-stack/radarr.nix b/profiles/servers/media-stack/radarr.nix index ba40f41..f775176 100644 --- a/profiles/servers/media-stack/radarr.nix +++ b/profiles/servers/media-stack/radarr.nix @@ -1,20 +1,23 @@ -{ config, lib, pkgs, ... }: { +{ config, lib, pkgs, ... }: +let + backend = config.virtualisation.oci-containers.backend; + nas-path = "/media/nas/media-stack"; +in { virtualisation.oci-containers.containers.radarr = { autoStart = true; environment = { - PUID = "1011"; - PGID = "1005"; + PUID = "1000"; + PGID = "100"; UMASK = "002"; TZ = "Europe/Moscow"; + HTTP_PROXY = "http://192.168.0.6:8888"; + HTTPS_PROXY = "http://192.168.0.6:8888"; }; - extraOptions = [ - "--network=media" - ]; - image = "cr.hotio.dev/hotio/radarr:release-4.1.0.6175"; + extraOptions = [ "--pod=media-stack" ]; + image = "cr.hotio.dev/hotio/radarr:release-4.3.2.6857"; volumes = [ - "/etc/localtime:/etc/localtime:ro" - "/media/configs/radarr/config:/config" - "/media/data:/data" + "${nas-path}/configs/radarr:/config" + "${nas-path}:/data" ]; }; } \ No newline at end of file diff --git a/profiles/servers/media-stack/recyclarr.nix b/profiles/servers/media-stack/recyclarr.nix new file mode 100644 index 0000000..7fefccc --- /dev/null +++ b/profiles/servers/media-stack/recyclarr.nix @@ -0,0 +1,19 @@ +{ config, lib, pkgs, ... }: +let + backend = config.virtualisation.oci-containers.backend; + nas-path = "/media/nas/media-stack"; +in { + virtualisation.oci-containers.containers.recyclarr = { + autoStart = true; + environment = { + CRON_SCHEDULE = "@daily"; + TZ = "Europe/Moscow"; + }; + extraOptions = [ "--pod=media-stack" ]; + image = "ghcr.io/recyclarr/recyclarr:4.3.0"; + volumes = [ + "${nas-path}/configs/recyclarr:/config" + ]; + user = "1000:100"; + }; +} \ No newline at end of file diff --git a/profiles/servers/media-stack/shoko.nix b/profiles/servers/media-stack/shoko.nix deleted file mode 100644 index cf79318..0000000 --- a/profiles/servers/media-stack/shoko.nix +++ /dev/null @@ -1,19 +0,0 @@ -{ config, lib, pkgs, ... }: { - virtualisation.oci-containers.containers.shokoserver = { - autoStart = true; - environment = { - PUID = "1019"; - PGID = "1005"; - TZ = "Europe/Moscow"; - }; - extraOptions = [ - "--network=media" - ]; - image = "shokoanime/server:v4.1.1"; - volumes = [ - "/etc/localtime:/etc/localtime:ro" - "/media/configs/shokoserver/config:/home/shoko/.shoko" - "/media/data:/data" - ]; - }; -} \ No newline at end of file diff --git a/profiles/servers/media-stack/sonarr.nix b/profiles/servers/media-stack/sonarr.nix index d0319c5..dd075fc 100644 --- a/profiles/servers/media-stack/sonarr.nix +++ b/profiles/servers/media-stack/sonarr.nix @@ -1,39 +1,21 @@ -{ config, lib, pkgs, ... }: { - virtualisation.oci-containers.containers.sonarr-anime = { +{ config, lib, pkgs, ... }: +let + backend = config.virtualisation.oci-containers.backend; + nas-path = "/media/nas/media-stack"; +in { + virtualisation.oci-containers.containers.sonarr = { autoStart = true; environment = { - PUID = "1012"; - PGID = "1005"; + PUID = "1000"; + PGID = "100"; UMASK = "002"; TZ = "Europe/Moscow"; }; - extraOptions = [ - "--network=media" - ]; - image = "cr.hotio.dev/hotio/sonarr:release-3.0.8.1507"; + extraOptions = [ "--pod=media-stack" ]; + image = "cr.hotio.dev/hotio/sonarr:v4-4.0.0.397"; volumes = [ - "/etc/localtime:/etc/localtime:ro" - "/media/configs/sonarr-anime/config:/config" - "/media/data:/data" - ]; - }; - - virtualisation.oci-containers.containers.sonarr-tv = { - autoStart = true; - environment = { - PUID = "1013"; - PGID = "1005"; - UMASK = "002"; - TZ = "Europe/Moscow"; - }; - extraOptions = [ - "--network=media" - ]; - image = "cr.hotio.dev/hotio/sonarr:release-3.0.8.1507"; - volumes = [ - "/etc/localtime:/etc/localtime:ro" - "/media/configs/sonarr-tv/config:/config" - "/media/data:/data" + "${nas-path}/configs/sonarr:/config" + "${nas-path}:/data" ]; }; } \ No newline at end of file diff --git a/profiles/servers/neko-browser.nix b/profiles/servers/neko-browser.nix new file mode 100644 index 0000000..8687345 --- /dev/null +++ b/profiles/servers/neko-browser.nix @@ -0,0 +1,30 @@ +{ config, lib, pkgs, ... }: +let + backend = config.virtualisation.oci-containers.backend; +in { + virtualisation.oci-containers.containers.neko-browser = { + autoStart = true; + image = "ghcr.io/m1k1o/neko/intel-firefox"; + environment = { + NEKO_ICELITE = "true"; + NEKO_SCREEN = "1920x1080@30"; + NEKO_PASSWORD = "neko"; + NEKO_PASSWORD_ADMIN = "admin"; + NEKO_TCPMUX = "8091"; + NEKO_UDPMUX = "8092"; + NEKO_BIND = "127.0.0.1:8090"; + NEKO_NAT1TO1 = "91.202.204.123"; + }; + extraOptions = [ + "--cap-add=SYS_ADMIN" + "--cap-add=SYS_CHROOT" + "--device=/dev/dri:/dev/dri" + "--shm-size=1gb" + ]; + ports = [ + "127.0.0.1:8090:8090" + "127.0.0.1:8091:8091" + "127.0.0.1:8092:8092/udp" + ]; + }; +} \ No newline at end of file diff --git a/profiles/servers/nginx.nix b/profiles/servers/nginx.nix index 9162c79..e507c5c 100644 --- a/profiles/servers/nginx.nix +++ b/profiles/servers/nginx.nix @@ -1,38 +1,82 @@ -{ config, lib, pkgs, ... }: { +{ config, lib, pkgs, ... }: +let + authentik = { root ? {}, rootExtraConfig ? "", locations ? {}, ... }: { + locations = locations // { + "/" = { + extraConfig = '' + auth_request /outpost.goauthentik.io/auth/nginx; + error_page 401 = @goauthentik_proxy_signin; + auth_request_set $auth_cookie $upstream_http_set_cookie; + add_header Set-Cookie $auth_cookie; + + # translate headers from the outposts back to the actual upstream + auth_request_set $authentik_username $upstream_http_x_authentik_username; + auth_request_set $authentik_groups $upstream_http_x_authentik_groups; + auth_request_set $authentik_email $upstream_http_x_authentik_email; + auth_request_set $authentik_name $upstream_http_x_authentik_name; + auth_request_set $authentik_uid $upstream_http_x_authentik_uid; + + proxy_set_header X-authentik-username $authentik_username; + proxy_set_header X-authentik-groups $authentik_groups; + proxy_set_header X-authentik-email $authentik_email; + proxy_set_header X-authentik-name $authentik_name; + proxy_set_header X-authentik-uid $authentik_uid; + '' + rootExtraConfig; + } // root; + # all requests to /outpost.goauthentik.io must be accessible without authentication + "/outpost.goauthentik.io" = { + extraConfig = '' + proxy_pass http://127.0.0.1:9000/outpost.goauthentik.io; + # proxy_pass http://auth.ataraxiadev.com:9000/outpost.goauthentik.io; + # proxy_pass https://auth.ataraxiadev.com/outpost.goauthentik.io; + # ensure the host of this vserver matches your external URL you've configured in authentik + proxy_set_header Host $host; + proxy_set_header X-Original-URL $scheme://$http_host$request_uri; + add_header Set-Cookie $auth_cookie; + auth_request_set $auth_cookie $upstream_http_set_cookie; + proxy_pass_request_body off; + proxy_set_header Content-Length ""; + ''; + }; + # Special location for when the /auth endpoint returns a 401, redirect to the /start URL which initiates SSO + "@goauthentik_proxy_signin" = { + extraConfig = '' + internal; + add_header Set-Cookie $auth_cookie; + # return 302 /outpost.goauthentik.io/start?rd=$request_uri; + # For domain level, use the below error_page to redirect to your authentik server with the full redirect path + return 302 https://auth.ataraxiadev.com/outpost.goauthentik.io/start?rd=$scheme://$http_host$request_uri; + ''; + }; + }; + }; +in { security.acme.certs = { "ataraxiadev.com" = { webroot = "/var/lib/acme/acme-challenge"; extraDomainNames = [ - # "matrix.ataraxiadev.com" - # "cinny.ataraxiadev.com" - # "dimension.ataraxiadev.com" - # "element.ataraxiadev.com" - # "goneb.ataraxiadev.com" - # "jitsi.ataraxiadev.com" - # "stats.ataraxiadev.com" "startpage.ataraxiadev.com" "vw.ataraxiadev.com" "code.ataraxiadev.com" - # "file.ataraxiadev.com" + "fb.ataraxiadev.com" + "browser.ataraxiadev.com" "webmail.ataraxiadev.com" - # "jellyfin.ataraxiadev.com" - # "radarr.ataraxiadev.com" - # "qbit.ataraxiadev.com" - # "prowlarr.ataraxiadev.com" - # "sonarr.ataraxiadev.com" - # "sonarrtv.ataraxiadev.com" - # "organizr.ataraxiadev.com" - # "lidarr.ataraxiadev.com" - # "bazarr.ataraxiadev.com" - # "nzbhydra.ataraxiadev.com" - # "kavita.ataraxiadev.com" - # "shoko.ataraxiadev.com" + "jellyfin.ataraxiadev.com" + "medusa.ataraxiadev.com" + "qbit.ataraxiadev.com" + "jackett.ataraxiadev.com" + "ldap.ataraxiadev.com" "bathist.ataraxiadev.com" - # "microbin.ataraxiadev.com" "joplin.ataraxiadev.com" "api.ataraxiadev.com" "fsync.ataraxiadev.com" "auth.ataraxiadev.com" + "sonarr.ataraxiadev.com" + "radarr.ataraxiadev.com" + "file.ataraxiadev.com" + "lidarr.ataraxiadev.com" + "cocalc.ataraxiadev.com" + "kavita.ataraxiadev.com" ]; }; }; @@ -52,10 +96,11 @@ clientMaxBodySize = "250m"; commonHttpConfig = '' proxy_hide_header X-Frame-Options; - proxy_hide_header Content-Security-Policy; - add_header X-XSS-Protection "1; mode=block"; - add_header X-Robots-Tag "none"; - add_header X-Content-Type-Options "nosniff"; + # proxy_hide_header Content-Security-Policy; + # add_header Content-Security-Policy "upgrade-insecure-requests"; + # add_header X-XSS-Protection "1; mode=block"; + # add_header X-Robots-Tag "none"; + # add_header X-Content-Type-Options "nosniff"; ''; virtualHosts = let default = { @@ -157,18 +202,48 @@ extraConfig = proxySettings; }; } // default; - "bathist.ataraxiadev.com" = { - locations."/" = { - proxyPass = "http://localhost:9999"; - extraConfig = proxySettings; - }; - } // default; - # "file.ataraxiadev.com" = { + # "bathist.ataraxiadev.com" = { # locations."/" = { - # proxyPass = "http://localhost:8088"; + # proxyPass = "http://localhost:9999"; # extraConfig = proxySettings; # }; # } // default; + "bathist.ataraxiadev.com" = default // authentik { + root = { proxyPass = "http://localhost:9999"; }; + rootExtraConfig = proxySettings; + }; + "browser.ataraxiadev.com" = { + locations."/" = { + proxyPass = "http://localhost:8090"; + proxyWebsockets = true; + extraConfig = '' + proxy_read_timeout 86400; + '' + proxySettings; + }; + } // default; + "fb.ataraxiadev.com" = default // authentik { + root = { proxyPass = "http://localhost:3923"; }; + rootExtraConfig = '' + proxy_redirect off; + proxy_http_version 1.1; + client_max_body_size 0; + proxy_buffering off; + proxy_request_buffering off; + proxy_set_header Connection "Keep-Alive"; + '' + proxySettings; + }; + "file.ataraxiadev.com" = { + locations."/" = { + proxyPass = "http://localhost:8088"; + extraConfig = '' + proxy_read_timeout 3600s; + client_max_body_size 0; + '' + proxySettings; + }; + extraConfig = '' + proxy_set_header X-Forwarded-For $remote_addr; + ''; + } // default; "webmail.ataraxiadev.com" = { locations."/" = { extraConfig = '' @@ -176,35 +251,42 @@ '' + proxySettings; }; } // default; - # "media-stack" = { - # serverAliases = [ - # "jellyfin.ataraxiadev.com" - # "radarr.ataraxiadev.com" - # "qbit.ataraxiadev.com" - # "prowlarr.ataraxiadev.com" - # "sonarr.ataraxiadev.com" - # "sonarrtv.ataraxiadev.com" - # "organizr.ataraxiadev.com" - # "lidarr.ataraxiadev.com" - # "bazarr.ataraxiadev.com" - # "nzbhydra.ataraxiadev.com" - # "kavita.ataraxiadev.com" - # "shoko.ataraxiadev.com" - # ]; - # locations."/" = { - # proxyPass = "http://localhost:8100"; - # proxyWebsockets = true; - # extraConfig = '' - # proxy_buffer_size 128k; - # proxy_buffers 4 256k; - # proxy_busy_buffers_size 256k; - # send_timeout 15m; - # proxy_connect_timeout 600; - # proxy_send_timeout 600; - # proxy_read_timeout 15m; - # '' + proxySettings; - # }; - # } // default; + "cocalc.ataraxiadev.com" = { + locations."/" = { + proxyPass = "https://localhost:9099"; + proxyWebsockets = true; + extraConfig = proxySettings; + }; + } // default; + "media-stack" = { + serverAliases = [ + "jellyfin.ataraxiadev.com" + "qbit.ataraxiadev.com" + "medusa.ataraxiadev.com" + "prowlarr.ataraxiadev.com" + "jackett.ataraxiadev.com" + "sonarr.ataraxiadev.com" + "radarr.ataraxiadev.com" + "lidarr.ataraxiadev.com" + "kavita.ataraxiadev.com" + ]; + locations."/" = { + proxyPass = "http://localhost:8180"; + proxyWebsockets = true; + extraConfig = '' + # For Medusa + add_header Content-Security-Policy "upgrade-insecure-requests"; + + proxy_buffer_size 128k; + proxy_buffers 4 256k; + proxy_busy_buffers_size 256k; + send_timeout 15m; + proxy_connect_timeout 600; + proxy_send_timeout 600; + proxy_read_timeout 15m; + '' + proxySettings; + }; + } // default; # "microbin.ataraxiadev.com" = { # locations."/" = { # proxyPass = "http://localhost:9988"; @@ -228,9 +310,11 @@ "auth.ataraxiadev.com" = { locations."/" = { proxyPass = "http://localhost:9000"; + proxyWebsockets = true; extraConfig = proxySettings; }; } // default; + "ldap.ataraxiadev.com" = default; "api.ataraxiadev.com" = { locations."~ (\\.py|\\.sh)$" = with config.services; { alias = "/srv/http/api.ataraxiadev.com"; diff --git a/profiles/servers/seafile.nix b/profiles/servers/seafile.nix index 1386b81..30288b9 100644 --- a/profiles/servers/seafile.nix +++ b/profiles/servers/seafile.nix @@ -1,5 +1,48 @@ -{ config, lib, pkgs, ... }: { - secrets.db-pass = { }; +{ config, lib, pkgs, ... }: +let + backend = config.virtualisation.oci-containers.backend; + nas-path = "/media/nas/seafile"; + pod-name = "seafile"; + open-ports = [ "127.0.0.1:8088:80" ]; + seahub-media-caddyfile = pkgs.writeText "Caddyfile" '' + { + admin off + http_port 8098 + https_port 8099 + } + :8098 { + root * /usr/share/caddy + file_server + } + ''; + seafile-caddy-caddyfile = pkgs.writeText "Caddyfile" '' + { + auto_https disable_redirects + } + + http:// https:// { + reverse_proxy seahub:8000 { + lb_policy header X-Forwarded-For + trusted_proxies private_ranges + } + handle_path /seafhttp* { + uri strip_prefix seafhttp + reverse_proxy seafile-server:8082 { + trusted_proxies private_ranges + } + } + reverse_proxy /seafdav* seafile-server:8080 { + header_up Destination https:// http:// + trusted_proxies private_ranges + } + reverse_proxy /media/* seahub-media:8098 { + lb_policy header X-Forwarded-For + trusted_proxies private_ranges + } + } + ''; +in { + secrets.seafile-db-pass = { }; secrets.seafile-admin-pass = { }; virtualisation.oci-containers.containers.seafile-server = { @@ -8,17 +51,16 @@ environment = { DB_HOST = "seafile-db"; TIME_ZONE = "Europe/Moscow"; - HTTPS = "false"; + HTTPS = "true"; SEAFILE_SERVER_HOSTNAME = "file.ataraxiadev.com"; + GC_CRON = "0 6 * * 0"; }; environmentFiles = [ - config.secrets.db-pass.decrypted + config.secrets.seafile-db-pass.decrypted ]; - extraOptions = [ - "--network=seafile" - ]; - image = "ggogel/seafile-server:9.0.4"; - volumes = [ "/media/seafile/server-data:/shared" ]; + extraOptions = [ "--pod=seafile" ]; + image = "docker.io/ggogel/seafile-server:9.0.10"; + volumes = [ "${nas-path}/server-data:/shared" ]; }; virtualisation.oci-containers.containers.seahub = { @@ -31,24 +73,24 @@ config.secrets.seafile-admin-pass.decrypted ]; extraOptions = [ - "--network=seafile" + "--pod=seafile" + # "--add-host=auth.ataraxiadev:192.168.0.10" ]; - image = "ggogel/seahub:9.0.4"; + image = "docker.io/ggogel/seahub:9.0.10"; volumes = [ - "/media/seafile/server-data:/shared" + "${nas-path}/server-data:/shared" ]; }; virtualisation.oci-containers.containers.seahub-media = { autoStart = true; dependsOn = [ "seafile-caddy" ]; - extraOptions = [ - "--network=seafile" - ]; - image = "ggogel/seahub-media:9.0.4"; + extraOptions = [ "--pod=seafile" ]; + image = "docker.io/ggogel/seahub-media:9.0.10"; volumes = [ - "/media/seafile/server-data/seafile/seahub-data/avatars:/usr/share/caddy/media/avatars" - "/media/seafile/server-data/seafile/seahub-data/custom:/usr/share/caddy/media/custom" + "${seahub-media-caddyfile}:/etc/caddy/Caddyfile" + "${nas-path}/server-data/seafile/seahub-data/avatars:/usr/share/caddy/media/avatars" + "${nas-path}/server-data/seafile/seahub-data/custom:/usr/share/caddy/media/custom" ]; }; @@ -58,40 +100,38 @@ MYSQL_LOG_CONSOLE = "true"; }; environmentFiles = [ - config.secrets.db-pass.decrypted + config.secrets.seafile-db-pass.decrypted ]; - extraOptions = [ - "--network=seafile" - ]; - image = "mariadb:10.7.1"; + extraOptions = [ "--pod=seafile" ]; + image = "docker.io/mariadb:10.7.8"; volumes = [ - "/media/seafile/mariadb:/var/lib/mysql" + "${nas-path}/db:/var/lib/mysql" ]; }; virtualisation.oci-containers.containers.memcached = { autoStart = true; - environment = { - MEMCACHED_CACHE_SIZE = "128"; - }; - extraOptions = [ - "--network=seafile" - ]; - image = "bitnami/memcached:1.6.14"; + cmd = [ "memcached" "-m 256" ]; + extraOptions = [ "--pod=seafile" ]; + image = "docker.io/memcached:1.6.18"; }; virtualisation.oci-containers.containers.seafile-caddy = { autoStart = true; - extraOptions = [ - "--network=seafile" - ]; - ports = [ "127.0.0.1:8088:80" ]; - image = "ggogel/seafile-caddy:1.0.6"; + extraOptions = [ "--pod=seafile" ]; + image = "docker.io/ggogel/seafile-caddy:1.0.8"; + volumes = [ "${seafile-caddy-caddyfile}:/etc/caddy/Caddyfile" ]; }; - systemd.services.create-seafile-network = with config.virtualisation.oci-containers; { - serviceConfig.Type = "oneshot"; - wantedBy = [ + systemd.services."podman-create-${pod-name}" = let + portsMapping = lib.concatMapStrings (port: " -p " + port) open-ports; + start = pkgs.writeShellScript "create-pod" '' + podman pod exists ${pod-name} || podman pod create -n ${pod-name} ${portsMapping} + exit 0 + ''; + in rec { + path = [ pkgs.coreutils config.virtualisation.podman.package ]; + before = [ "${backend}-seafile-server.service" "${backend}-seahub.service" "${backend}-seahub-media.service" @@ -99,10 +139,12 @@ "${backend}-memcached.service" "${backend}-seafile-caddy.service" ]; - script = '' - ${pkgs.docker}/bin/docker network inspect seafile || \ - ${pkgs.docker}/bin/docker network create -d bridge seafile - exit 0 - ''; + wantedBy = before; + partOf = before; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = "yes"; + ExecStart = start; + }; }; } diff --git a/profiles/servers/tinyproxy.nix b/profiles/servers/tinyproxy.nix new file mode 100644 index 0000000..35dab30 --- /dev/null +++ b/profiles/servers/tinyproxy.nix @@ -0,0 +1,36 @@ +{ config, pkgs, lib, ... }: { + containers.tinyproxy = { + extraFlags = [ "-U" ]; + autoStart = true; + ephemeral = true; + privateNetwork = true; + hostBridge = "br0"; + localAddress = "192.168.0.6/24"; + # tmpfs = [ "/" ]; # not working with unprivilliged container + config = { config, pkgs, ... }: { + services.privoxy = { + enable = true; + settings = { + listen-address = "192.168.0.6:8888"; + toggle = false; + keep-alive-timeout = 300; + default-server-timeout = 60; + connection-sharing = false; + }; + }; + networking = { + defaultGateway = "192.168.0.1"; + hostName = "tinyproxy-node"; + nameservers = [ "192.168.0.1" ]; + # enableIPv6 = false; + useHostResolvConf = false; + firewall = { + enable = true; + allowedTCPPorts = [ 8888 ]; + rejectPackets = false; + }; + }; + system.stateVersion = "22.11"; + }; + }; +} \ No newline at end of file diff --git a/profiles/servers/yandex-db.nix b/profiles/servers/yandex-db.nix new file mode 100644 index 0000000..5e11ad3 --- /dev/null +++ b/profiles/servers/yandex-db.nix @@ -0,0 +1,12 @@ +{ config, lib, pkgs, ... }: { + secrets.yandex-token = {}; + + systemd.services.yandex-db = { + description = "Gathers data on rides taken via Yandex Taxi."; + serviceConfig = { + Type = "oneshot"; + ExecStart = pkgs.yandex-taxi-py; + }; + startAt = "*:0/15"; + }; +} \ No newline at end of file