Compare commits

...

8 Commits

10 changed files with 261 additions and 3 deletions

View File

@@ -94,6 +94,14 @@ in
} }
]; ];
registry.homepage.${config.networking.hostName}.romm = {
tab = "Apps";
section = "Media";
name = "RomM";
description = "Games";
icon = "romm.png";
};
guests.romm = { guests.romm = {
interior = { interior = {
modules.services.romm.enable = true; modules.services.romm.enable = true;

View File

@@ -104,6 +104,7 @@
domain = "games.alexion.dev"; domain = "games.alexion.dev";
protocol = "https"; protocol = "https";
port = 80; port = 80;
clientMaxBodySize = "0";
}; };
}; };
}; };

View File

@@ -44,6 +44,7 @@
modules.desktop.enable = true; modules.desktop.enable = true;
modules.desktop.apps.obsidian.enable = true; modules.desktop.apps.obsidian.enable = true;
modules.desktop.apps.r2modman.enable = true; modules.desktop.apps.r2modman.enable = true;
modules.desktop.emulation.enable = true;
modules.desktop.apps.signal.enable = true; modules.desktop.apps.signal.enable = true;
modules.desktop.apps.steam.enable = true; modules.desktop.apps.steam.enable = true;
modules.desktop.apps.vencord.enable = true; modules.desktop.apps.vencord.enable = true;

View File

@@ -0,0 +1,36 @@
{
config,
lib,
...
}:
# Shared directories for emulators.
let
user = config.user.name;
directory = "/home/${user}/emulation";
in
{
options.modules.desktop.emulation.enable = lib.mkEnableOption "shared emulation directories";
config = lib.mkIf config.modules.desktop.emulation.enable {
modules.desktop.emulation.retroarch = {
enable = lib.mkDefault true;
browserDirectory = "${directory}/roms";
};
home-manager.users.${user} = hm: {
home.file = {
".config/retroarch/saves".source = hm.config.lib.file.mkOutOfStoreSymlink "${directory}/saves";
".config/retroarch/states".source = hm.config.lib.file.mkOutOfStoreSymlink "${directory}/states";
".config/retroarch/system".source = hm.config.lib.file.mkOutOfStoreSymlink "${directory}/bios";
};
systemd.user.tmpfiles.rules = map (path: "d ${path} 0700 - - -") [
directory
"${directory}/bios"
"${directory}/roms"
"${directory}/saves"
"${directory}/states"
];
};
};
}

View File

@@ -0,0 +1,62 @@
{
config,
lib,
pkgs,
util,
...
}:
# RetroArch with the selected PlayStation and Sega Saturn cores.
let
cfg = config.modules.desktop.emulation.retroarch;
user = config.user.name;
in
{
options.modules.desktop.emulation.retroarch = {
enable = lib.mkEnableOption "RetroArch with PlayStation and Sega Saturn cores";
browserDirectory = lib.mkOption {
type = lib.types.str;
default = "";
description = "Directory where RetroArch starts its content browser.";
};
};
config = lib.mkIf cfg.enable {
home-manager.users.${user} = {
home.packages = [
(pkgs.wrapRetroArch {
cores = with pkgs.libretro; [
beetle-psx-hw
beetle-saturn
];
settings = {
savefiles_in_content_dir = "false";
savestates_in_content_dir = "false";
system_directory = "/home/${user}/.config/retroarch/system";
video_fullscreen = "true";
sort_savefiles_enable = "true";
sort_savestates_enable = "true";
cloud_sync_enable = "true";
cloud_sync_driver = "webdav";
webdav_url = "https://games.alexion.dev/api/sync/retroarch/";
cloud_sync_sync_saves = "true";
cloud_sync_sync_configs = "true";
cloud_sync_sync_thumbs = "false";
cloud_sync_sync_system = "false";
cloud_sync_sync_mode = "0";
cloud_sync_destructive = "false";
}
// lib.optionalAttrs (cfg.browserDirectory != "") {
rgui_browser_directory = cfg.browserDirectory;
};
})
];
};
registry.window-icon.${config.networking.hostName}.retroarch = {
class = "com.libretro.RetroArch";
icon = util.glyph "f11b";
};
};
}

View File

@@ -71,7 +71,10 @@ let
extraConfig = lib.optionalString (route.clientMaxBodySize != null) '' extraConfig = lib.optionalString (route.clientMaxBodySize != null) ''
client_max_body_size ${route.clientMaxBodySize}; client_max_body_size ${route.clientMaxBodySize};
''; '';
locations."/".proxyPass = mkBackend address port; locations."/" = {
proxyPass = mkBackend address port;
proxyWebsockets = true;
};
}; };
}; };

View File

@@ -1,6 +1,7 @@
{ {
config, config,
lib, lib,
pkgs,
... ...
}: }:
let let
@@ -31,13 +32,33 @@ in
services.romm = { services.romm = {
enable = true; enable = true;
package = pkgs.alexion.romm;
group = "storage"; group = "storage";
database.createLocally = true; database.createLocally = true;
redis.createLocally = true; redis.createLocally = true;
watcher.enable = true; watcher.enable = true;
extraEnvironment = {
HASHEOUS_API_ENABLED = "true";
PLAYMATCH_API_ENABLED = "true";
ROM_CONVERTO_ENABLED = "false";
};
inherit (cfg) environmentFile; inherit (cfg) environmentFile;
}; };
systemd.services.romm-worker.serviceConfig.ExecStart =
lib.mkForce "${lib.getExe' config.services.romm.package "romm-worker"} scans";
systemd.tmpfiles.settings."10-romm"."${config.services.romm.dataDir}/config/config.yml"."L+".argument =
toString (
(pkgs.formats.yaml { }).generate "romm-config.yml" {
emulatorjs.auto_save_sync = false;
filesystem.structure = {
default = "roms/{platform}/{game}";
firmware = "bios/{platform}";
};
}
);
users.users = { users.users = {
romm.uid = config.registry."stable-uid".${config.networking.hostName}.romm; romm.uid = config.registry."stable-uid".${config.networking.hostName}.romm;
redis-romm.uid = config.registry."stable-uid".${config.networking.hostName}."redis-romm"; redis-romm.uid = config.registry."stable-uid".${config.networking.hostName}."redis-romm";

View File

@@ -3,8 +3,8 @@ aliases:
- "0015" - "0015"
- RomM 5.4 Package - RomM 5.4 Package
date-created: 2026-10-19 19:40 date-created: 2026-10-19 19:40
date-modified: 2026-10-19 19:40 date-modified: 2026-10-21 00:01
status: open status: closed
area: "[[homelab]]" area: "[[homelab]]"
blocked-by: blocked-by:
- "[[0014-romm-guest]]" - "[[0014-romm-guest]]"

View File

@@ -4,5 +4,7 @@
inherit root; inherit root;
}; };
romm = pkgs.callPackage ./romm.nix { };
waybar = pkgs.callPackage ./waybar.nix { }; waybar = pkgs.callPackage ./waybar.nix { };
} }

124
src/flake/packages/romm.nix Normal file
View File

@@ -0,0 +1,124 @@
{
buildNpmPackage,
fetchFromGitHub,
lib,
python3,
romm,
}:
romm.overrideAttrs (
finalAttrs: previousAttrs:
let
frontend = buildNpmPackage {
pname = "romm-frontend";
inherit (finalAttrs) version;
src = "${finalAttrs.src}/frontend";
npmDepsHash = "sha256-f5IcpOVv7JYFzUPkZIq5nbT3dS1f/KCSllh8Vkgl1P0=";
npmFlags = [ "--ignore-scripts" ];
makeCacheWritable = true;
installPhase = ''
runHook preInstall
cp -r dist $out
chmod u+w $out/assets
cp -r assets/. $out/assets/
runHook postInstall
'';
};
# RomM 5.4 requires packages absent from the Nixpkgs 5.2 environment.
pythonEnv = python3.withPackages (
ps: with ps; [
aiohttp
alembic
anyio
apprise
asyncssh
authlib
bcrypt
colorama
croniter
cryptography
defusedxml
email-validator
fastapi
gunicorn
httpx
httpx2
itsdangerous
jinja2
joserfc
mariadb
mutagen
mysql-connector-python
opentelemetry-distro
opentelemetry-exporter-otlp
opentelemetry-instrumentation-aiohttp-client
opentelemetry-instrumentation-fastapi
opentelemetry-instrumentation-httpx
opentelemetry-instrumentation-redis
opentelemetry-instrumentation-sqlalchemy
passlib
pillow
psycopg
pydantic
pydash
python-dotenv
python-magic
python-multipart
python-socketio
pyyaml
redis
rq
rq-scheduler
sentry-sdk
sqlalchemy
starlette
streaming-form-data
strsimpy
ua-parser
unidecode
uvicorn
uvicorn-worker
watchfiles
yarl
zipfile-inflate64
zstandard
]
);
in
{
version = "5.4.0";
src = fetchFromGitHub {
owner = "rommapp";
repo = "romm";
tag = finalAttrs.version;
hash = "sha256-oIYEdIAJgXkcqjZtWlWKD/NFiQ3gbo7gxwLhqZOCWpM=";
};
postPatch = previousAttrs.postPatch + ''
# Redis 8.0.1 removed this argument.
# RomM disables the related maintenance notifications.
substituteInPlace backend/handler/redis_handler.py \
--replace-fail 'from redis.maint_notifications import MaintNotificationsConfig' "" \
--replace-fail ' "maint_notifications_config": MaintNotificationsConfig(enabled=False),' ""
'';
installPhase =
lib.replaceStrings
[
"${previousAttrs.passthru.frontend}"
"${previousAttrs.passthru.pythonEnv}"
]
[
"${frontend}"
"${pythonEnv}"
]
previousAttrs.installPhase;
passthru = previousAttrs.passthru // {
inherit frontend pythonEnv;
};
}
)