Add linting, formatting, and CI

- Add deadnix, nixfmt, and statix to flake inputs
- Add formatter output to flake for nix fmt support
- Add deadnix, nixfmt, statix to Home Manager packages
- Format all nix files with nixfmt
- Add GitHub Actions workflow for CI validation
- Support x86_64-darwin in formatter
This commit is contained in:
Gene Liverman 2026-03-14 01:04:02 -04:00
parent 1312755c4b
commit c1a53997ce
No known key found for this signature in database
75 changed files with 1417 additions and 767 deletions

View file

@ -1,4 +1,10 @@
{ inputs, pkgs, username, ... }: {
{
inputs,
pkgs,
username,
...
}:
{
imports = [
../../../shared/nixos/nixroutes.nix
./disk-config.nix
@ -24,14 +30,14 @@
networking = {
# Open ports in the firewall.
firewall.allowedTCPPorts = [
22 # ssh
25 # SMTP (unencrypted)
80 # http to local Nginx
143 # imap
443 # https to local Nginx
465 # SMTP with TLS
587 # SMTP with STARTTLS
993 # imaps
22 # ssh
25 # SMTP (unencrypted)
80 # http to local Nginx
143 # imap
443 # https to local Nginx
465 # SMTP with TLS
587 # SMTP with STARTTLS
993 # imaps
1883 # mqtt
8333 # Bitcoin Core
8448 # Matrix Synapse
@ -88,7 +94,10 @@
users.users.${username} = {
isNormalUser = true;
description = "Gene Liverman";
extraGroups = [ "networkmanager" "wheel" ];
extraGroups = [
"networkmanager"
"wheel"
];
linger = true;
};
}

View file

@ -4,11 +4,18 @@
{ lib, modulesPath, ... }:
{
imports =
[ (modulesPath + "/profiles/qemu-guest.nix")
];
imports = [
(modulesPath + "/profiles/qemu-guest.nix")
];
boot.initrd.availableKernelModules = [ "ahci" "xhci_pci" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod" ];
boot.initrd.availableKernelModules = [
"ahci"
"xhci_pci"
"virtio_pci"
"virtio_scsi"
"sd_mod"
"sr_mod"
];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ ];
boot.extraModulePackages = [ ];
@ -25,4 +32,3 @@
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
}

View file

@ -1,3 +1,4 @@
{ ... }: {
home.stateVersion = "24.05";
{ ... }:
{
home.stateVersion = "24.05";
}

View file

@ -1,6 +1,8 @@
{ config, username, ... }: let
{ config, username, ... }:
let
volume_base = "/var/lib/emqx";
in {
in
{
# Based on docs at https://docs.emqx.com/en/emqx/latest/deploy/install-docker.html
virtualisation.oci-containers.containers = {
"emqx" = {

View file

@ -1,7 +1,15 @@
{ config, lib, pkgs, username, ... }: let
{
config,
lib,
pkgs,
username,
...
}:
let
domain = "technicalissues.us";
restic_backup_time = "01:00";
in {
in
{
imports = [
../../../../shared/nixos/lets-encrypt.nix
../../../../shared/nixos/restic.nix
@ -26,7 +34,7 @@ in {
# Listen on loopback interface only, and accept requests from ::1
net = {
listen = "loopback";
post_allow.host = ["::1"];
post_allow.host = [ "::1" ];
};
# Restrict loading documents from WOPI Host nextcloud.example.com
@ -162,14 +170,14 @@ in {
};
matrix_secrets_yaml = {
owner = config.users.users.matrix-synapse.name;
restartUnits = ["matrix-synapse.service"];
restartUnits = [ "matrix-synapse.service" ];
};
matrix_homeserver_signing_key.owner = config.users.users.matrix-synapse.name;
mqtt_recorder_pass.restartUnits = ["mosquitto.service"];
mqtt_recorder_pass.restartUnits = [ "mosquitto.service" ];
nextcloud_admin_pass.owner = config.users.users.nextcloud.name;
owntracks_basic_auth = {
owner = config.users.users.nginx.name;
restartUnits = ["nginx.service"];
restartUnits = [ "nginx.service" ];
};
plausible_admin_pass.owner = config.users.users.nginx.name;
plausible_secret_key_base.owner = config.users.users.nginx.name;
@ -180,31 +188,36 @@ in {
};
systemd.services = {
nextcloud-config-collabora = let
inherit (config.services.nextcloud) occ;
nextcloud-config-collabora =
let
inherit (config.services.nextcloud) occ;
wopi_url = "http://[::1]:${toString config.services.collabora-online.port}";
public_wopi_url = "https://collabora.pack1828.org";
wopi_allowlist = lib.concatStringsSep "," [
"127.0.0.1"
"::1"
"5.161.244.95"
"2a01:4ff:f0:977c::1"
];
in {
wantedBy = ["multi-user.target"];
after = ["nextcloud-setup.service" "coolwsd.service"];
requires = ["coolwsd.service"];
script = ''
${occ}/bin/nextcloud-occ config:app:set richdocuments wopi_url --value ${lib.escapeShellArg wopi_url}
${occ}/bin/nextcloud-occ config:app:set richdocuments public_wopi_url --value ${lib.escapeShellArg public_wopi_url}
${occ}/bin/nextcloud-occ config:app:set richdocuments wopi_allowlist --value ${lib.escapeShellArg wopi_allowlist}
${occ}/bin/nextcloud-occ richdocuments:setup
'';
serviceConfig = {
Type = "oneshot";
wopi_url = "http://[::1]:${toString config.services.collabora-online.port}";
public_wopi_url = "https://collabora.pack1828.org";
wopi_allowlist = lib.concatStringsSep "," [
"127.0.0.1"
"::1"
"5.161.244.95"
"2a01:4ff:f0:977c::1"
];
in
{
wantedBy = [ "multi-user.target" ];
after = [
"nextcloud-setup.service"
"coolwsd.service"
];
requires = [ "coolwsd.service" ];
script = ''
${occ}/bin/nextcloud-occ config:app:set richdocuments wopi_url --value ${lib.escapeShellArg wopi_url}
${occ}/bin/nextcloud-occ config:app:set richdocuments public_wopi_url --value ${lib.escapeShellArg public_wopi_url}
${occ}/bin/nextcloud-occ config:app:set richdocuments wopi_allowlist --value ${lib.escapeShellArg wopi_allowlist}
${occ}/bin/nextcloud-occ richdocuments:setup
'';
serviceConfig = {
Type = "oneshot";
};
};
};
};
# Enable common container config files in /etc/containers

View file

@ -1,4 +1,5 @@
{ config, ... }: {
{ config, ... }:
{
services.matrix-synapse = {
enable = true;
configureRedisLocally = true;
@ -33,7 +34,7 @@
];
url_preview_enabled = true;
enable_registration = false;
trusted_key_servers = [{ server_name = "matrix.org"; }];
trusted_key_servers = [ { server_name = "matrix.org"; } ];
};
};

View file

@ -1,6 +1,8 @@
{ config, pkgs, ... }: let
{ config, pkgs, ... }:
let
metrics_server = "https://monitoring.home.technicalissues.us/remotewrite";
in {
in
{
services = {
vmagent = {
enable = true;
@ -14,11 +16,11 @@ in {
{
job_name = "node";
static_configs = [
{ targets = ["127.0.0.1:9100"]; }
{ targets = [ "127.0.0.1:9100" ]; }
];
metric_relabel_configs = [
{
source_labels = ["__name__"];
source_labels = [ "__name__" ];
regex = "go_.*";
action = "drop";
}
@ -35,11 +37,11 @@ in {
{
job_name = "nginx";
static_configs = [
{ targets = ["127.0.0.1:9113"]; }
{ targets = [ "127.0.0.1:9113" ]; }
];
metric_relabel_configs = [
{
source_labels = ["__name__"];
source_labels = [ "__name__" ];
regex = "go_.*";
action = "drop";
}
@ -77,7 +79,7 @@ in {
# ----------------------------
# Exporters (using built-in NixOS modules)
# ----------------------------
# Node exporter - using the built-in module
prometheus.exporters.node = {
enable = true;
@ -110,7 +112,7 @@ in {
group = "vmagent";
};
users.groups.vmagent = {};
users.groups.vmagent = { };
# ----------------------------
# SOPS secrets configuration
@ -119,10 +121,9 @@ in {
secrets = {
vmagent_push_pw = {
owner = "vmagent";
restartUnits = ["vmagent.service"];
restartUnits = [ "vmagent.service" ];
sopsFile = ../../../../shared/secrets.yaml;
};
};
};
}

View file

@ -1,16 +1,21 @@
{ config, ... }: let
{ config, ... }:
let
mqtt_domain = "mqtt.technicalissues.us";
in {
security.acme.certs.${mqtt_domain}.postRun = "systemctl restart ${config.systemd.services.mosquitto.name}";
in
{
security.acme.certs.${mqtt_domain}.postRun =
"systemctl restart ${config.systemd.services.mosquitto.name}";
services.mosquitto = {
enable = true;
bridges = {
liamcottle = {
addresses = [{
address = "mqtt.meshtastic.liamcottle.net";
port = 1883;
}];
addresses = [
{
address = "mqtt.meshtastic.liamcottle.net";
port = 1883;
}
];
topics = [
"msh/# out 1 \"\""
];
@ -24,10 +29,12 @@ in {
};
};
meshtastic = {
addresses = [{
address = "mqtt.meshtastic.org";
port = 1883;
}];
addresses = [
{
address = "mqtt.meshtastic.org";
port = 1883;
}
];
topics = [
"msh/# out 1 \"\""
];
@ -42,10 +49,12 @@ in {
};
};
homeassistant = {
addresses = [{
address = "homeasistant-lc.atlas-snares.ts.net";
port = 1883;
}];
addresses = [
{
address = "homeasistant-lc.atlas-snares.ts.net";
port = 1883;
}
];
topics = [
"msh/US/2/e/LongFast/!a386c80 out 1 \"\""
"msh/US/2/e/LongFast/!b03bcb24 out 1 \"\""
@ -62,53 +71,59 @@ in {
};
};
};
listeners = let
mqtt_users = {
genebean = {
acl = [
"readwrite msh/#"
];
hashedPasswordFile = config.sops.secrets.mosquitto_genebean.path;
listeners =
let
mqtt_users = {
genebean = {
acl = [
"readwrite msh/#"
];
hashedPasswordFile = config.sops.secrets.mosquitto_genebean.path;
};
mountain_mesh = {
acl = [
"readwrite msh/#"
];
hashedPasswordFile = config.sops.secrets.mosquitto_mountain_mesh.path;
};
};
mountain_mesh = {
acl = [
"readwrite msh/#"
];
hashedPasswordFile = config.sops.secrets.mosquitto_mountain_mesh.path;
};
};
in [
{
port = 1883;
users = mqtt_users;
settings.allow_anonymous = false;
}
{
port = 8883;
users = mqtt_users;
settings = let
certDir = config.security.acme.certs."${mqtt_domain}".directory;
in {
allow_anonymous = false;
keyfile = certDir + "/key.pem";
certfile = certDir + "/cert.pem";
cafile = certDir + "/chain.pem";
};
}
{
port = 9001;
users = mqtt_users;
settings = let
certDir = config.security.acme.certs."${mqtt_domain}".directory;
in {
allow_anonymous = false;
keyfile = certDir + "/key.pem";
certfile = certDir + "/cert.pem";
cafile = certDir + "/chain.pem";
protocol = "websockets";
};
}
];
in
[
{
port = 1883;
users = mqtt_users;
settings.allow_anonymous = false;
}
{
port = 8883;
users = mqtt_users;
settings =
let
certDir = config.security.acme.certs."${mqtt_domain}".directory;
in
{
allow_anonymous = false;
keyfile = certDir + "/key.pem";
certfile = certDir + "/cert.pem";
cafile = certDir + "/chain.pem";
};
}
{
port = 9001;
users = mqtt_users;
settings =
let
certDir = config.security.acme.certs."${mqtt_domain}".directory;
in
{
allow_anonymous = false;
keyfile = certDir + "/key.pem";
certfile = certDir + "/cert.pem";
cafile = certDir + "/chain.pem";
protocol = "websockets";
};
}
];
};
sops.secrets = {

View file

@ -1,9 +1,11 @@
{ config, ... }: let
{ config, ... }:
let
domain = "technicalissues.us";
http_port = 80;
https_port = 443;
private_btc = "umbrel.atlas-snares.ts.net";
in {
in
{
services.nginx = {
enable = true;
@ -134,14 +136,36 @@ in {
};
"matrix.${domain}" = {
listen = [
{ port = http_port; addr = "0.0.0.0"; }
{ port = http_port; addr = "[::]"; }
{
port = http_port;
addr = "0.0.0.0";
}
{
port = http_port;
addr = "[::]";
}
{ port = https_port; addr = "0.0.0.0"; ssl = true; }
{ port = https_port; addr = "[::]"; ssl = true; }
{
port = https_port;
addr = "0.0.0.0";
ssl = true;
}
{
port = https_port;
addr = "[::]";
ssl = true;
}
{ port = 8448; addr = "0.0.0.0"; ssl = true; }
{ port = 8448; addr = "[::]"; ssl = true; }
{
port = 8448;
addr = "0.0.0.0";
ssl = true;
}
{
port = 8448;
addr = "[::]";
ssl = true;
}
];
enableACME = true;
acmeRoot = null;
@ -195,7 +219,8 @@ in {
"/" = {
proxyPass = "http://127.0.0.1:8083";
};
"/pub" = { # Client apps need to point to this path
"/pub" = {
# Client apps need to point to this path
extraConfig = "proxy_set_header X-Limit-U $remote_user;";
proxyPass = "http://127.0.0.1:8083/pub";
};