feat(nixos): deploy RomM guest
This commit is contained in:
@@ -13,11 +13,6 @@ in
|
||||
modules.services.reverse-proxy.enable = true;
|
||||
|
||||
services.nginx.virtualHosts = {
|
||||
"games.alexion.dev" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
locations."/".proxyPass = "http://10.23.20.32";
|
||||
};
|
||||
"git.alexion.dev" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
|
||||
181
configs/nixos/guests/romm.nix
Normal file
181
configs/nixos/guests/romm.nix
Normal file
@@ -0,0 +1,181 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.guests.romm;
|
||||
rommUid = config.registry."stable-uid".${config.networking.hostName}.romm;
|
||||
redisUid = config.registry."stable-uid".${config.networking.hostName}."redis-romm";
|
||||
in
|
||||
{
|
||||
options.guests.romm = {
|
||||
dataPath = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
example = "/srv/romm";
|
||||
description = "Host path mounted as RomM application data.";
|
||||
};
|
||||
|
||||
postgresqlPath = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
example = "/srv/romm/postgresql";
|
||||
description = "Host path mounted as RomM's PostgreSQL data.";
|
||||
};
|
||||
|
||||
redisPath = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
example = "/srv/romm/redis";
|
||||
description = "Host path mounted as RomM's Redis data.";
|
||||
};
|
||||
|
||||
romsPath = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
example = "/srv/roms";
|
||||
description = "Host path mounted as RomM's ROM library.";
|
||||
};
|
||||
|
||||
biosPath = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
example = "/srv/bios";
|
||||
description = "Host path mounted as RomM's BIOS library.";
|
||||
};
|
||||
|
||||
usersPath = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
example = "/srv/romm/users";
|
||||
description = "Host path mounted as RomM's user assets.";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
assertions =
|
||||
map
|
||||
(path: {
|
||||
assertion = path.value != null;
|
||||
message = "guests.romm.${path.name} must point at the host directory that stores ${path.description}.";
|
||||
})
|
||||
[
|
||||
{
|
||||
name = "dataPath";
|
||||
value = cfg.dataPath;
|
||||
description = "RomM application data";
|
||||
}
|
||||
{
|
||||
name = "postgresqlPath";
|
||||
value = cfg.postgresqlPath;
|
||||
description = "RomM PostgreSQL data";
|
||||
}
|
||||
{
|
||||
name = "redisPath";
|
||||
value = cfg.redisPath;
|
||||
description = "RomM Redis data";
|
||||
}
|
||||
{
|
||||
name = "romsPath";
|
||||
value = cfg.romsPath;
|
||||
description = "RomM's ROM library";
|
||||
}
|
||||
{
|
||||
name = "biosPath";
|
||||
value = cfg.biosPath;
|
||||
description = "RomM's BIOS library";
|
||||
}
|
||||
{
|
||||
name = "usersPath";
|
||||
value = cfg.usersPath;
|
||||
description = "RomM's user assets";
|
||||
}
|
||||
];
|
||||
|
||||
guests.romm = {
|
||||
interior = {
|
||||
modules.services.romm.enable = true;
|
||||
services.romm.nginx.virtualHost = cfg.reverseProxy.route.domain;
|
||||
};
|
||||
|
||||
mounts = {
|
||||
"/var/lib/romm" = {
|
||||
directory = cfg.dataPath;
|
||||
owner = rommUid;
|
||||
group = "storage";
|
||||
mode = "2770";
|
||||
};
|
||||
"/var/lib/postgresql" = {
|
||||
directory = cfg.postgresqlPath;
|
||||
owner = config.ids.uids.postgres;
|
||||
group = "storage";
|
||||
mode = "0700";
|
||||
};
|
||||
"/var/lib/redis-romm" = {
|
||||
directory = cfg.redisPath;
|
||||
owner = redisUid;
|
||||
group = "storage";
|
||||
mode = "0700";
|
||||
};
|
||||
"/var/lib/romm/library/roms" = {
|
||||
directory = cfg.romsPath;
|
||||
owner = rommUid;
|
||||
group = "storage";
|
||||
mode = "2770";
|
||||
};
|
||||
"/var/lib/romm/library/bios" = {
|
||||
directory = cfg.biosPath;
|
||||
owner = rommUid;
|
||||
group = "storage";
|
||||
mode = "2770";
|
||||
};
|
||||
"/var/lib/romm/assets/users" = {
|
||||
directory = cfg.usersPath;
|
||||
owner = rommUid;
|
||||
group = "storage";
|
||||
mode = "2770";
|
||||
};
|
||||
"/run/secrets/romm.env" = {
|
||||
file = config.sops.templates."romm.env".path;
|
||||
readOnly = true;
|
||||
};
|
||||
};
|
||||
|
||||
limits = {
|
||||
memory = lib.mkDefault "4G";
|
||||
cpu = lib.mkDefault "200%";
|
||||
tasksMax = lib.mkDefault 512;
|
||||
};
|
||||
};
|
||||
|
||||
sops.secrets =
|
||||
lib.genAttrs
|
||||
[
|
||||
"services/romm/igdb/client-id"
|
||||
"services/romm/igdb/client-secret"
|
||||
"services/romm/retroachievements/api-key"
|
||||
"services/romm/screenscraper/user"
|
||||
"services/romm/screenscraper/password"
|
||||
"services/romm/steamgriddb/api-key"
|
||||
]
|
||||
(_: {
|
||||
sopsFile = ../secrets + "/${config.networking.hostName}.yaml";
|
||||
});
|
||||
|
||||
sops.templates."romm.env" = {
|
||||
owner = "root";
|
||||
group = "storage";
|
||||
mode = "0440";
|
||||
content = ''
|
||||
IGDB_CLIENT_ID=${config.sops.placeholder."services/romm/igdb/client-id"}
|
||||
IGDB_CLIENT_SECRET=${config.sops.placeholder."services/romm/igdb/client-secret"}
|
||||
SCREENSCRAPER_USER=${config.sops.placeholder."services/romm/screenscraper/user"}
|
||||
SCREENSCRAPER_PASSWORD=${config.sops.placeholder."services/romm/screenscraper/password"}
|
||||
RETROACHIEVEMENTS_API_KEY=${config.sops.placeholder."services/romm/retroachievements/api-key"}
|
||||
STEAMGRIDDB_API_KEY=${config.sops.placeholder."services/romm/steamgriddb/api-key"}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -88,6 +88,26 @@
|
||||
};
|
||||
};
|
||||
|
||||
guests.romm = {
|
||||
enable = true;
|
||||
vlan = 20;
|
||||
address = "10.23.20.112";
|
||||
dataPath = "/pikachu/data/romm";
|
||||
postgresqlPath = "/pikachu/data/romm/postgresql";
|
||||
redisPath = "/pikachu/data/romm/redis";
|
||||
romsPath = "/pikachu/media/games/emulation/roms";
|
||||
biosPath = "/pikachu/media/games/emulation/bios";
|
||||
usersPath = "/pikachu/media/games/emulation/users";
|
||||
reverseProxy = {
|
||||
enable = true;
|
||||
route = {
|
||||
domain = "games.alexion.dev";
|
||||
protocol = "https";
|
||||
port = 80;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
guests.reverse-proxy = {
|
||||
enable = true;
|
||||
vlan = 20;
|
||||
|
||||
47
configs/nixos/modules/services/romm.nix
Normal file
47
configs/nixos/modules/services/romm.nix
Normal file
@@ -0,0 +1,47 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.modules.services.romm;
|
||||
in
|
||||
{
|
||||
options.modules.services.romm = {
|
||||
enable = lib.mkEnableOption "RomM";
|
||||
|
||||
environmentFile = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = "/run/secrets/romm.env";
|
||||
readOnly = true;
|
||||
description = "Path to RomM's environment file.";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkMerge [
|
||||
{
|
||||
registry."stable-uid".${config.networking.hostName} = {
|
||||
romm = 20005;
|
||||
"redis-romm" = 20006;
|
||||
};
|
||||
}
|
||||
|
||||
(lib.mkIf cfg.enable {
|
||||
networking.firewall.allowedTCPPorts = [ 80 ];
|
||||
|
||||
services.romm = {
|
||||
enable = true;
|
||||
group = "storage";
|
||||
database.createLocally = true;
|
||||
redis.createLocally = true;
|
||||
watcher.enable = true;
|
||||
inherit (cfg) environmentFile;
|
||||
};
|
||||
|
||||
users.users = {
|
||||
romm.uid = config.registry."stable-uid".${config.networking.hostName}.romm;
|
||||
redis-romm.uid = config.registry."stable-uid".${config.networking.hostName}."redis-romm";
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
||||
@@ -12,7 +12,7 @@ let
|
||||
|
||||
in
|
||||
{
|
||||
# Next stable UID: 20005
|
||||
# Next stable UID: 20007
|
||||
|
||||
type = lib.types.ints.positive;
|
||||
|
||||
|
||||
@@ -6,6 +6,17 @@ services:
|
||||
lastfm:
|
||||
api-key: ENC[AES256_GCM,data:Zb0I5TpdEqOxLAD6ed2XywFGZp7dfY69vcGiWOUJkJQ=,iv:pO53pHr09jWfzJyTsQbTHtzTmiQ9+RQkDwZJmInIiX8=,tag:io9jkSN7TF2I8+qlSymaYw==,type:str]
|
||||
secret: ENC[AES256_GCM,data:rKhd9i0/tbJlXhc9Wf81IDydjpD8khSdwJEEMK260E4=,iv:btBXWBKJp9br5a3yZsRVegN8Ytzc45Qbk2iNlPbENkQ=,tag:LUbu+6gxfqQvVpddZto7Tg==,type:str]
|
||||
romm:
|
||||
igdb:
|
||||
client-id: ENC[AES256_GCM,data:tme7NzzbOlCmkMwVObWz793mOsCyVIzSjGoFvxpe,iv:5aOMvsDi8Z9aBymbqhbK79X4kJsqaET1y2Py6YUZZ/U=,tag:ih3GghlxiLsVyeTJoqU9/Q==,type:str]
|
||||
client-secret: ENC[AES256_GCM,data:AqF7B9VaxM/X3sRqY6C5JVWPWqgRIoqy09P9ZUFj,iv:D+vDPUuGGdzKYnTVTRkI9TV/EOJgVECIeNDt9g8NGl0=,tag:MRaTT7TdEZSd+98xthVw1A==,type:str]
|
||||
retroachievements:
|
||||
api-key: ENC[AES256_GCM,data:LMzETQCMi9Ib783W0BZDe2PaSUSTVM5a61502RtZLg8=,iv:Hf5nBoVtZdJszQuc2n0LVNMtJCCpJrh40y4g+l+az70=,tag:esfKLpI1W8BG3Pfsg3xxKQ==,type:str]
|
||||
steamgriddb:
|
||||
api-key: ENC[AES256_GCM,data:+kBRieIB/dHbvQLbH2gQTQh2j6DQhybVWEGkSCRZrZY=,iv:3h6dhfiV7HfaZhMv93x8+7F3utzYG6fIbTDScA14PVI=,tag:Wo24YnvsIxe7iMRLyxrj2w==,type:str]
|
||||
screenscraper:
|
||||
user: ENC[AES256_GCM,data:7hGcFF4xqg==,iv:SFOdYej94Thfn+Te0kXsC9Kq568A1dsnaR+JB90MgBQ=,tag:inIWuFY7f5Tvv8EyV71dYA==,type:str]
|
||||
password: ENC[AES256_GCM,data:eUWwDDQUSytm/6QZlG5XjbSi41nsBQbm4w==,iv:82S2a3rAVjaF0CXcjXUXErNHMY7MEkjpDL7EVX9cIHw=,tag:uGuVJCv8ThsaNnA0C0WR2Q==,type:str]
|
||||
sops:
|
||||
age:
|
||||
- enc: |
|
||||
@@ -26,7 +37,7 @@ sops:
|
||||
dyjzy0/9Ui1IIXH36AImO5hiEZcrGePV2qPLLQc7ZLngC1jlJuEKJA==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
recipient: age1wf5s0n0tgt6ld2ysgu9dc67mj8ylwecgl4utzg7hqwy3kut9zyms7aglmh
|
||||
lastmodified: "2026-09-12T22:54:25Z"
|
||||
mac: ENC[AES256_GCM,data:4R3a0ytf4i8aM8iBQ9vRC/q+hvtjLrCTNgbpCB5DbqBMBYmhtGsBmO/0i1yT0N4tydyLaGOMkNfuuuVi3ASLEOKnViy9w3uD9IN0F79W4f2vguWUVIp/T8skvN9wbV9o9xd0LkJzmeVVgzb1H6HKw+rTGjbquleoIHEBDcDDM+k=,iv:0NlckMXlS+idY6UGBF+F0KFLt+pzD7Q/YEQOdXraAYg=,tag:JBBQduV8uhnKz9gPf6HfAQ==,type:str]
|
||||
lastmodified: "2026-10-20T01:27:06Z"
|
||||
mac: ENC[AES256_GCM,data:NCt6e/ctZwaBADfrhu1RXtILlClbHEqOAnIu8rE/zMPSwMIPB/kTtfd/ujf+1iRszoHaX4Se1xc0wz1th6NVToFVNarxBBgTk4JMUU8gdMweOjmwlh3GXU3ZcYY/xAXxWF1hxyXSEW78j3S2844H9XXENAq/Bf3mjdCYQ/qr/d4=,iv:4nFyBSmRvF4zSAwvL+xccMwtWrVbHtFKNoTb7f3rSH4=,tag:eCV/7P0TjyMZXKcWBUPXQA==,type:str]
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.13.3
|
||||
|
||||
Reference in New Issue
Block a user