main
1{lib, ...}: {
2 den.aspects.services.stash = {
3 settings = {
4 external = lib.mkEnableOption "Whether to expose Stash service to public internet";
5 domain = lib.mkOption {
6 type = lib.types.str;
7 };
8 address = lib.mkOption {
9 type = lib.types.str;
10 default = "127.0.0.1";
11 };
12 port = lib.mkOption {
13 type = lib.types.port;
14 default = 9482;
15 };
16 jwtSecretKeyFileAged = lib.mkOption {
17 type = lib.types.path;
18 };
19 sessionStoreKeyFileAged = lib.mkOption {
20 type = lib.types.path;
21 };
22 passwordFileAged = lib.mkOption {
23 type = lib.types.path;
24 };
25 };
26
27 persist = {config, ...}: {
28 directories = [
29 {
30 directory = lib.dirOf config.services.stash.settings.database;
31 inherit (config.services.stash) user group;
32 }
33 {
34 directory = config.services.stash.settings.blobs_path;
35 inherit (config.services.stash) user group;
36 }
37 ];
38 };
39
40 cache = {config, ...}: {
41 directories =
42 [
43 {
44 directory = lib.dirOf config.services.stash.settings.cache;
45 inherit (config.services.stash) user group;
46 }
47 {
48 directory = config.services.stash.settings.generated;
49 inherit (config.services.stash) user group;
50 }
51 ]
52 ++ (lib.optional config.services.stash.mutablePlugins {
53 directory = config.services.stash.settings.plugins_path;
54 inherit (config.services.stash) user group;
55 })
56 ++ (lib.optional config.services.stash.mutableScrapers {
57 directory = config.services.stash.settings.scrapers_path;
58 inherit (config.services.stash) user group;
59 });
60 };
61
62 reverseProxy = {host, ...}: let
63 cfg = host.settings.services.stash;
64 in
65 lib.optionalAttrs (cfg.external) {
66 ${cfg.domain} = {
67 port = cfg.port;
68 };
69 };
70
71 reverseProxyTailscale = {host, ...}: let
72 cfg = host.settings.services.stash;
73 in
74 lib.optionalAttrs (!cfg.external) {
75 ${cfg.domain} = {
76 port = cfg.port;
77 };
78 };
79
80 nixos = {
81 host,
82 config,
83 pkgs,
84 ...
85 }: let
86 cfg = host.settings.services.stash;
87 in {
88 services.stash = {
89 enable = true;
90 mutableSettings = false;
91 mutablePlugins = true;
92 mutableScrapers = true;
93 jwtSecretKeyFile = config.vaultix.secrets.stash-jwt-secret.path;
94 sessionStoreKeyFile = config.vaultix.secrets.stash-session-store-key.path;
95 username = "admin";
96 passwordFile = config.vaultix.secrets.stash-password.path;
97 settings = {
98 host = cfg.address;
99 port = cfg.port;
100
101 blobs_path = lib.mkDefault "${config.services.stash.dataDir}/blobs";
102 cache = "${config.services.stash.dataDir}/cache";
103 database = "${config.services.stash.dataDir}/database/stash-go.sqlite";
104 generated = "${config.services.stash.dataDir}/generated";
105 plugins_path = lib.mkIf config.services.stash.mutablePlugins "${config.services.stash.dataDir}/plugins";
106 scrapers_path = lib.mkIf config.services.stash.mutableScrapers "${config.services.stash.dataDir}/scrapers";
107 preview_segments = 16;
108 };
109 };
110
111 vaultix.secrets = {
112 stash-jwt-secret = {
113 file = cfg.jwtSecretKeyFileAged;
114 owner = config.services.stash.user;
115 inherit (config.services.stash) group;
116 };
117 stash-session-store-key = {
118 file = cfg.sessionStoreKeyFileAged;
119 owner = config.services.stash.user;
120 inherit (config.services.stash) group;
121 };
122 stash-password = {
123 file = cfg.passwordFileAged;
124 owner = config.services.stash.user;
125 inherit (config.services.stash) group;
126 };
127 };
128
129 # Original module uses ffmpeg-full instead of ffmpeg-headless
130 # which brings lots of GUI dependenices
131 systemd.services.stash.path = lib.mkForce (with pkgs; [
132 ffmpeg-headless
133 python3
134 ruby
135
136 coreutils
137 findutils
138 gnugrep
139 gnused
140 systemd
141 ]);
142 };
143 };
144}