Add a11ywatch and related configurations for Podman and Nginx

- Introduced a new module for a11ywatch with Podman support, creating a bridge network and defining backend and frontend containers.
- Configured Nginx to serve the a11ywatch application with SSL and ACME support.
- Added user and group configurations for a11ywatch.
- Created a systemd service to ensure the Podman network exists on boot.

Implement Firefox Container Controller extension and host

- Added a module for the Firefox Container Controller extension, allowing installation via Nix.
- Created a native messaging host for the extension to communicate with the container controller.
- Included CLI helpers to enqueue commands for showing and hiding containers.

Enable fingerprint authentication in PAM

- Configured fingerprint authentication for login, sudo, and swaylock services.

Setup Raspberry Pi OS image creation script

- Developed a script to create a read-only Raspberry Pi OS Lite image with Snapcast client.
- Included configuration for Wi-Fi, hostname, and Snapcast server.
- Implemented user and group setup for Snapcast client and ensured necessary services are enabled.

Document Raspberry Pi Zero W setup instructions

- Added detailed instructions for configuring Raspberry Pi OS on Zero W, including disabling unused services and setting up Snapcast client.

Create test configuration script for NixOS

- Implemented a script to perform dry-builds for NixOS configurations, allowing for easy validation of host configurations.
This commit is contained in:
2025-05-29 00:10:07 +02:00
parent 8e52274edd
commit 53d73142ae
32 changed files with 1280 additions and 104 deletions

View File

@@ -1,28 +1,18 @@
{ pkgs, config, python3Packages, ... }:
{ pkgs, config, lib, python3Packages, ... }:
let
domain = "snapcast.cloonar.com";
mopidyDomain = "mopidy.cloonar.com";
networkPrefix = config.networkPrefix;
snapweb = pkgs.stdenv.mkDerivation {
pname = "snapweb";
version = "0.8";
src = pkgs.fetchzip {
url = "https://github.com/badaix/snapweb/releases/download/v0.8.0/snapweb.zip";
sha256 = "sha256-IpT1pcuzcM8kqWJUX3xxpRQHlfPNsrwhemLmY0PyzjI=";
stripRoot = false;
};
installPhase = ''
mkdir -p $out
cp -r $src/* $out/
'';
};
in
{
security.acme.certs."${domain}" = {
group = "nginx";
};
security.acme.certs."${mopidyDomain}" = {
group = "nginx";
};
sops.secrets.mopidy-spotify = { };
containers.snapcast = {
autoStart = true;
@@ -39,6 +29,13 @@ in
hostPath = "${config.security.acme.certs.${domain}.directory}";
isReadOnly = true;
};
"/var/lib/acme/mopidy/" = {
hostPath = "${config.security.acme.certs.${mopidyDomain}.directory}";
isReadOnly = true;
};
"/run/secrets/mopidy-spotify" = {
hostPath = "${config.sops.secrets.mopidy-spotify.path}";
};
};
config = { lib, config, pkgs, python3Packages, ... }:
let
@@ -51,18 +48,59 @@ in
"--with-metadata"
];
});
snapweb = pkgs.stdenv.mkDerivation {
pname = "snapweb";
version = "0.8";
src = pkgs.fetchzip {
url = "https://github.com/badaix/snapweb/releases/download/v0.8.0/snapweb.zip";
sha256 = "sha256-IpT1pcuzcM8kqWJUX3xxpRQHlfPNsrwhemLmY0PyzjI=";
stripRoot = false;
};
installPhase = ''
mkdir -p $out
cp -r $src/* $out/
'';
};
mopidy-autoplay = pkgs.python3Packages.buildPythonApplication rec {
pname = "Mopidy-Autoplay";
version = "0.2.3";
src = pkgs.python3Packages.fetchPypi {
inherit pname version;
sha256 = "sha256-E2Q+Cn2LWSbfoT/gFzUfChwl67Mv17uKmX2woFz/3YM=";
};
propagatedBuildInputs = [
pkgs.mopidy
] ++ (with pkgs.python3Packages; [
configobj
]);
# no tests implemented
doCheck = false;
meta = with lib; {
homepage = "https://codeberg.org/sph/mopidy-autoplay";
};
};
in
{
networking = {
hostName = "snapcast";
useHostResolvConf = false;
defaultGateway = {
address = "${networkPrefix}.96.1";
address = "${networkPrefix}.97.1";
interface = "eth0";
};
nameservers = [ "${networkPrefix}.97.1" ];
firewall.enable = false;
};
environment.systemPackages = with pkgs; [
# shanocast
];
environment.etc = {
# Creates /etc/nanorc
shairport = {
@@ -83,36 +121,79 @@ in
};
};
systemd.tmpfiles.rules = [
"p /run/snapserver/mopidyfifo 0660 mopidy snapserver -"
];
services.mopidy = {
enable = true;
extensionPackages = [
pkgs.mopidy-iris
pkgs.mopidy-tunein
pkgs.mopidy-spotify
mopidy-autoplay
];
configuration = ''
[audio]
output = audioresample ! audioconvert ! audio/x-raw,rate=48000,channels=2,format=S16LE ! wavenc ! filesink location=/run/snapserver/mopidyfifo
[file]
enabled = false
[autoplay]
enabled = true
'';
extraConfigFiles = [
"/run/secrets/mopidy-spotify"
];
};
services.snapserver = {
enable = true;
codec = "flac";
http.enable = true;
http.docRoot = "${snapweb}/";
streams.mopidy = {
type = "pipe";
location = "/run/snapserver/mopidy";
};
buffer = 1000;
streamBuffer = 1000;
streams.airplay = {
type = "airplay";
location = "${shairport-sync}/bin/shairport-sync";
query = {
devicename = "Multi Room New";
devicename = "Multi Room";
port = "5000";
params = "--mdns=avahi";
};
sampleFormat = "44100:16:2";
codec = "pcm";
};
streams.mopidy = {
type = "pipe";
location = "/run/snapserver/mopidyfifo";
};
streams.mixed = {
type = "meta";
location = "/airplay/mopidy";
type = "meta";
location = "meta:///airplay/mopidy?name=Mixed&sampleformat=44100:16:2";
codec = "opus";
};
};
# run after tmpfiles-setup
systemd.services.snapserver = {
after = [ "systemd-tmpfiles-setup.service" ];
requires = [ "systemd-tmpfiles-setup.service" ];
};
systemd.services.mopidy = {
after = [ "systemd-tmpfiles-setup.service" ];
requires = [ "systemd-tmpfiles-setup.service" ];
};
services.avahi.enable = true;
services.avahi.publish.enable = true;
services.avahi.publish.userServices = true;
services.nginx.enable = true;
services.nginx.virtualHosts."snapcast.cloonar.com" = {
services.nginx.virtualHosts."${domain}" = {
sslCertificate = "/var/lib/acme/snapcast/fullchain.pem";
sslCertificateKey = "/var/lib/acme/snapcast/key.pem";
sslTrustedCertificate = "/var/lib/acme/snapcast/chain.pem";
@@ -131,6 +212,26 @@ in
'';
};
services.nginx.virtualHosts."${mopidyDomain}" = {
sslCertificate = "/var/lib/acme/mopidy/fullchain.pem";
sslCertificateKey = "/var/lib/acme/mopidy/key.pem";
sslTrustedCertificate = "/var/lib/acme/mopidy/chain.pem";
forceSSL = true;
extraConfig = ''
proxy_buffering off;
'';
locations."/".extraConfig = ''
proxy_pass http://127.0.0.1:6680;
proxy_set_header Host $host;
proxy_redirect http:// https://;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
'';
};
system.stateVersion = "23.05";
};
};