From aac10ac15df59e3021dc3215919ad4e2d8edd80b Mon Sep 17 00:00:00 2001 From: "Thomas A. Christensen II" <25492070+MillironX@users.noreply.github.com> Date: Fri, 20 Feb 2026 10:07:14 -0600 Subject: [PATCH 1/2] fix: Audiobookshelf file permissions --- services/audiobookshelf.nix | 3 +++ 1 file changed, 3 insertions(+) diff --git a/services/audiobookshelf.nix b/services/audiobookshelf.nix index c4f5070..c81b0dd 100644 --- a/services/audiobookshelf.nix +++ b/services/audiobookshelf.nix @@ -21,6 +21,9 @@ in { "use_path_request_style" "url=https://us-east-1.linodeobjects.com/" "passwd_file=${config.age.secrets.millironx-books-s3-token.path}" + "uid=${user}" + "gid=${user}" + "umask=0022" ]; }; From 02e115937f48088d7a938df5815034bdfd6c43fc Mon Sep 17 00:00:00 2001 From: "Thomas A. Christensen II" <25492070+MillironX@users.noreply.github.com> Date: Fri, 20 Feb 2026 16:06:33 -0600 Subject: [PATCH 2/2] feat: Add navidrome service --- secrets.nix | 4 ++ secrets/millironx-music-s3.age | Bin 0 -> 824 bytes secrets/navidrome.toml.age | Bin 0 -> 869 bytes services/navidrome.nix | 104 +++++++++++++++++++++++++++++++++ 4 files changed, 108 insertions(+) create mode 100644 secrets/millironx-music-s3.age create mode 100644 secrets/navidrome.toml.age create mode 100644 services/navidrome.nix diff --git a/secrets.nix b/secrets.nix index ffbb9ab..ce66958 100644 --- a/secrets.nix +++ b/secrets.nix @@ -38,6 +38,10 @@ in { ++ [ mcentire-host ]; "secrets/millironx-books-s3.age".publicKeys = system-administrators ++ [ mcentire-host ]; + "secrets/millironx-music-s3.age".publicKeys = system-administrators + ++ [ mcentire-host ]; + "secrets/navidrome.toml.age".publicKeys = system-administrators + ++ [ mcentire-host ]; "secrets/network-information.age".publicKeys = system-administrators ++ [ bosephus-host ]; } diff --git a/secrets/millironx-music-s3.age b/secrets/millironx-music-s3.age new file mode 100644 index 0000000000000000000000000000000000000000..14e9b6480b10c88b175f5d07b915dfa899bd98e4 GIT binary patch literal 824 zcmZY6yNlBR0LO6`Imv;OI*G*Dt7)3#dUZI+qiLE))1+zB#zE31&7*0a%@Yw+L=XfK zMa03u)dwPucP_Wwf1u|mPA5+1AR_8~{skYtzn^ZIHPfHPWw>$z|8fvpPzD3FZ7@mf znrSpJ3~qsrhj^6)W(g(J1RP-+V^ITE!~8%>^Z^86B{v#z6-g7m*Kdi_kp$#O6``9f z>UT4m4Q)1G=1n27sCK(P>CJHlX$I-mL{F*;J+8qPROC5mW};9`MqH-ki6pw&vXhy7 zjwOuHK>`|f350W4!<}$c7l`@Em@Qntr~+x8p^?F5Niz+gLd0i0-ZCsg$<=-w&AsHf zW=uJg$w5ky`*v)_4CRp8Oh}sYI8|bf^Xt5uM|9UHHb>H|K2>oP$h5#GChAn>4Us74 z2}_C%#Wg66a}_D&19(0gLk4omAf@9P67^T91$r2*qOuD$JBo}?Jvm^+YA7hIVNT0> zdlQ!7tc-18VUGnM&O^SQt!P8%ILTN1>{{3BizVb-aaUNS%__|67ulrL2pC zaW2(yHpGKQV^ErmS~zJB(80m?%~1vlfS>L?cKk7>fJ5)?T^#&rw1qY ZH_l&A*PrswpB#a!wZ~U(-#GmF>Mxgm9c2Ij literal 0 HcmV?d00001 diff --git a/secrets/navidrome.toml.age b/secrets/navidrome.toml.age new file mode 100644 index 0000000000000000000000000000000000000000..23319853d2194d799444462a70718142dcbe0cce GIT binary patch literal 869 zcmZY2&#T*X003|qOfjx5fogp4!0KnFDRDH^Z1QaJqYZB-OYdOR~ zPKt9h>&`o18N~$(W<$&8`4ps1S{F=h)|69w(CQ46(;L09@*>2Gxwo}NeIuapWYuIx zltqtcG;-A#+R55Q`tDGqc#^Kf5!MXEBPxK5=9L8D>H{K$wB`BE(IBK?BnTr{9^NARpU(hBVW^SU{)D=Gv)EN@K|K;NA@)IXFzG^P^AG{Af z`uDAGp8vY_2Dd2RIs4(IGr=oQ-griP?T+;6h3}sGQu&)&8Fd+NgH_x}0# h;mr*=xp~XI_v{aQckUl+ul{*A`+~W(`0;~l{{!OzEB*ig literal 0 HcmV?d00001 diff --git a/services/navidrome.nix b/services/navidrome.nix new file mode 100644 index 0000000..bd8bc94 --- /dev/null +++ b/services/navidrome.nix @@ -0,0 +1,104 @@ +{ config, pkgs, home-manager-quadlet-nix, ... }: +let + user = "navidrome"; + port = "4533"; + authentikPort = "9000"; + stateDirectory = "/var/lib/${user}"; + s3BucketName = "millironx-music"; + s3MountDirectory = "/mount/s3/${s3BucketName}"; +in { + age.secrets = { + millironx-music-s3-token.file = ./../secrets/millironx-music-s3.age; + "navidrome.toml" = { + file = ./../secrets/navidrome.toml.age; + owner = user; + }; + }; + + millironx.podman-secrets.navidrome = { + inherit user; + secrets-files = [ config.age.secrets."navidrome.toml".path ]; + }; + + environment.systemPackages = [ pkgs.s3fs ]; + + fileSystems."${s3BucketName}" = { + device = s3BucketName; + mountPoint = s3MountDirectory; + fsType = "fuse./run/current-system/sw/bin/s3fs"; + noCheck = true; + options = [ + "_netdev" + "allow_other" + "use_path_request_style" + "url=https://us-east-1.linodeobjects.com/" + "passwd_file=${config.age.secrets.millironx-music-s3-token.path}" + "uid=${user}" + "gid=${user}" + "umask=0022" + ]; + }; + + systemd.tmpfiles.rules = + map (d: "d ${stateDirectory}/${d} 1775 ${user} ${user} -") [ "" "data" ]; + + services.borgmatic.configurations."${config.networking.hostName}" = { + source_directories = map (d: "${stateDirectory}/${d}") [ "data" ]; + }; + + services.caddy.virtualHosts."music.millironx.com".extraConfig = '' + # Authentik output endpoint + reverse_proxy /outpost.goauthentik.io/* http://127.0.0.1:${authentikPort} + + # Protect everything except share and subsonic endpoints + @protected not path /share/* /rest/* + forward_auth @protected http://127.0.0.1:${authentikPort} { + uri /outpost.goauthentik.io/auth/caddy + copy_headers X-Authentik-Username>Remote-User + } + + # Forward everything to Navidrome + reverse_proxy 127.0.0.1:${port} + ''; + + users.users."${user}" = { + group = "${user}"; + isNormalUser = true; + home = stateDirectory; + createHome = true; + linger = true; + autoSubUidGidRange = true; + }; + users.groups."${user}" = { }; + + home-manager.users."${user}" = { config, osConfig, ... }: { + imports = [ home-manager-quadlet-nix ]; + + home.stateVersion = "25.05"; + + virtualisation.quadlet = { + autoUpdate.enable = true; + containers.navidrome = { + autoStart = true; + containerConfig = { + image = "docker.io/deluan/navidrome:latest"; + environments = { + ND_BASEURL = "https://music.millironx.com"; + ND_EXTAUTH_TRUSTEDSOURCES = "10.0.0.0/8"; + }; + secrets = + map (s: "${s},type=env") [ "ND_LASTFM_APIKEY" "ND_LASTFM_SECRET" ]; + volumes = [ + "${s3MountDirectory}:/music:Uro" + "${stateDirectory}/data:/data:U" + ]; + publishPorts = [ "127.0.0.1:${port}:${port}" ]; + unitConfig.Requires = + [ osConfig.millironx.podman-secrets.navidrome.ref ]; + unitConfig.After = + [ osConfig.millironx.podman-secrets.navidrome.ref ]; + }; + }; + }; + }; +}