nixos/matterjs-server: init

Assisted-by: Claude:claude-opus-4-7
This commit is contained in:
Ilan Joselevich
2026-05-25 21:13:41 +03:00
parent c542226491
commit 4c60b6fde1
6 changed files with 159 additions and 1 deletions

View File

@@ -92,6 +92,8 @@
- [kiwix-serve](https://wiki.kiwix.org/wiki/Kiwix-serve), a service that serves ZIM files (such as Wikipedia archives) over HTTP. Available as [services.kiwix-serve](#opt-services.kiwix-serve.enable).
- [matterjs-server](https://github.com/matter-js/matterjs-server), a Matter controller with a Home Assistant compatible WebSocket API. Available as [services.matterjs-server](#opt-services.matterjs-server.enable).
- [Remark42](https://remark42.com/), a self-hosted comment engine. Available as [services.remark42](#opt-services.remark42.enable).
- [LibreChat](https://www.librechat.ai/), open-source self-hostable ChatGPT clone with Agents and RAG APIs. Available as [services.librechat](#opt-services.librechat.enable).

View File

@@ -733,6 +733,7 @@
./services/home-automation/home-assistant.nix
./services/home-automation/homebridge.nix
./services/home-automation/matter-server.nix
./services/home-automation/matterjs-server.nix
./services/home-automation/openthread-border-router.nix
./services/home-automation/wyoming/faster-whisper.nix
./services/home-automation/wyoming/openwakeword.nix

View File

@@ -0,0 +1,127 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.services.matterjs-server;
in
{
options.services.matterjs-server = {
enable = lib.mkEnableOption "matterjs-server, a Matter Controller WebSocket server based on Matter.js";
package = lib.mkPackageOption pkgs "matterjs-server" { };
listenAddress = lib.mkOption {
type = lib.types.str;
default = "127.0.0.1";
description = "IP address the WebSocket API binds to.";
};
port = lib.mkOption {
type = lib.types.port;
default = 5580;
description = "TCP port the WebSocket API listens on.";
};
openFirewall = lib.mkEnableOption null // {
description = "Whether to open the WebSocket API port in the firewall.";
};
bluetoothSupport = lib.mkEnableOption ''
BLE (Bluetooth Low Energy) commissioning support. Select an adapter with
`--bluetooth-adapter=<id>` in
{option}`services.matterjs-server.extraArgs`
'';
extraArgs = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
example = [
"--primary-interface=enp11s0"
"--log-level=debug"
];
description = ''
Additional command-line arguments passed to `matterjs-server`. See
`matterjs-server --help` for the full list of options.
'';
};
};
config = lib.mkIf cfg.enable {
networking.firewall = lib.mkIf cfg.openFirewall {
allowedTCPPorts = [ cfg.port ];
};
systemd.services.matterjs-server = {
description = "Matter Controller WebSocket server based on Matter.js";
documentation = [ "https://github.com/matter-js/matterjs-server" ];
wantedBy = [ "multi-user.target" ];
after = [ "network-online.target" ];
wants = [ "network-online.target" ];
serviceConfig =
let
bluetoothCaps = [
"CAP_NET_RAW"
"CAP_NET_ADMIN"
];
in
{
ExecStart = lib.escapeShellArgs (
[
(lib.getExe cfg.package)
"--storage-path=%S/matterjs-server"
"--listen-address=${cfg.listenAddress}"
"--port=${toString cfg.port}"
"--production-mode"
]
++ cfg.extraArgs
);
StateDirectory = "matterjs-server";
StateDirectoryMode = "0700";
DynamicUser = true;
# Required for interaction with hci devices and bluetooth sockets
AmbientCapabilities = lib.optionals cfg.bluetoothSupport bluetoothCaps;
CapabilityBoundingSet = lib.optionals cfg.bluetoothSupport bluetoothCaps;
LockPersonality = true;
NoNewPrivileges = true;
PrivateTmp = true;
PrivateUsers = !cfg.bluetoothSupport; # Prevents gaining capabilities in the host namespace
ProcSubset = "pid";
ProtectClock = true;
ProtectControlGroups = true;
ProtectHome = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectProc = "invisible";
ProtectSystem = "strict";
RestrictAddressFamilies = [
"AF_INET"
"AF_INET6"
"AF_NETLINK"
"AF_UNIX"
]
++ lib.optional cfg.bluetoothSupport "AF_BLUETOOTH";
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
SystemCallArchitectures = "native";
SystemCallFilter = [
"@system-service"
"~@privileged"
];
UMask = "0077";
};
};
};
meta.maintainers = with lib.maintainers; [ kranzes ];
}

View File

@@ -966,6 +966,7 @@ in
matrix-synapse-workers = runTest ./matrix/synapse-workers.nix;
matrix-tuwunel = runTest ./matrix/tuwunel.nix;
matter-server = runTest ./matter-server.nix;
matterjs-server = runTest ./matterjs-server.nix;
mattermost = handleTest ./mattermost { };
mautrix-discord = runTest ./matrix/mautrix-discord.nix;
mautrix-meta-postgres = runTest ./matrix/mautrix-meta-postgres.nix;

View File

@@ -0,0 +1,23 @@
{ lib, ... }:
{
name = "matterjs-server";
meta.maintainers = with lib.maintainers; [ kranzes ];
nodes.machine.services.matterjs-server.enable = true;
testScript =
{ nodes, ... }:
let
inherit (nodes.machine.services.matterjs-server) listenAddress port package;
in
''
import json
machine.wait_for_unit("matterjs-server.service")
machine.wait_for_open_port(${toString port})
health = json.loads(machine.succeed("curl -fsS http://${listenAddress}:${toString port}/health"))
assert health["version"] == "${package.version}"
'';
}

View File

@@ -7,6 +7,7 @@
udev,
versionCheckHook,
nix-update-script,
nixosTests,
}:
buildNpmPackage (finalAttrs: {
@@ -59,7 +60,10 @@ buildNpmPackage (finalAttrs: {
doInstallCheck = true;
versionCheckProgramArg = "--version";
passthru.updateScript = nix-update-script { };
passthru = {
tests = { inherit (nixosTests) matterjs-server; };
updateScript = nix-update-script { };
};
meta = {
description = "Matter server based on Matter.js";