refactor: rename modules to nixosModules

This commit is contained in:
Romain Paquet 2026-01-27 14:36:11 +01:00
parent 2eb4dc3730
commit 7062c95697
24 changed files with 21 additions and 8 deletions

View file

@ -0,0 +1,34 @@
{
config,
lib,
pkgs,
...
}:
{
security.acme = {
acceptTerms = true;
defaults.email = lib.mkDefault "admin@rpqt.fr";
};
# security.acme = {
# certs."home.rpqt.fr" = {
# group = config.services.nginx.group;
# domain = "home.rpqt.fr";
# extraDomainNames = [ "*.home.rpqt.fr" ];
# dnsProvider = "rfc2136";
# dnsPropagationCheck = true;
# credentialFiles = {
# RFC2136_TSIG_SECRET_FILE = config.clan.core.vars.generators.coredns.files.tsig-key.path;
# };
# environmentFile = pkgs.writeFile ''
# RFC2136_NAMESERVER=fd28:387a:90:c400::1
# '';
# email = "admin@rpqt.fr";
# dnsResolver = "1.1.1.1:53";
# server = "https://acme-staging-v02.api.letsencrypt.org/directory"; # TODO: use production api
# };
# };
# clan.core.vars.generators.coredns.files.tsig-key.group = "acme";
# clan.core.vars.generators.coredns.files.tsig-key.mode = "0440";
}

View file

@ -0,0 +1,17 @@
{ config, self, ... }:
let
user = "u422292";
sub-user = "${user}";
host = "${user}.your-storagebox.de";
in
{
imports = [
self.nixosModules.storagebox
self.inputs.clan-core.clanModules.borgbackup
];
clan.borgbackup.destinations."storagebox-${config.networking.hostName}" = {
repo = "${sub-user}@${host}:./borgbackup/${config.networking.hostName}";
rsh = "ssh -oPort=23 -i ${config.clan.core.vars.generators.borgbackup.files."borgbackup.ssh".path}";
};
}

53
nixosModules/desktop.nix Normal file
View file

@ -0,0 +1,53 @@
{ pkgs, ... }:
{
environment.systemPackages = [
pkgs.mpv # video player
pkgs.amberol # music player
pkgs.alacritty
pkgs.ghostty
pkgs.libreoffice
pkgs.nautilus
];
fonts.packages = [
pkgs.inter
];
programs.firefox = {
enable = true;
languagePacks = [ "fr" ];
};
programs.thunderbird.enable = true;
programs.nautilus-open-any-terminal = {
enable = true;
terminal = "ghostty";
};
# services.yubikey-agent.enable = true;
programs.gnupg.agent.pinentryPackage = pkgs.pinentry-gnome3;
services.pcscd.enable = true;
security.rtkit.enable = true;
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
};
hardware.bluetooth.enable = true;
services.displayManager = {
sddm.enable = true;
sddm.wayland.enable = true;
};
# Display manager keyboard layout
services.xserver = {
enable = true;
xkb.layout = "fr";
};
}

View file

@ -0,0 +1,28 @@
{ lib, ... }:
{
flake.nixosModules =
(
(builtins.readDir ./.)
|> lib.filterAttrs (path: type: type == "regular" && (lib.hasSuffix ".nix" path))
|> lib.mapAttrs' (
path: _: {
name = lib.removeSuffix ".nix" path;
value = {
imports = [ ./${path} ];
};
}
)
)
// {
server.imports = [
./motd.nix
];
common.imports = [
{
users.mutableUsers = lib.mkDefault false;
services.userborn.enable = lib.mkDefault true;
}
];
};
}

76
nixosModules/forgejo.nix Normal file
View file

@ -0,0 +1,76 @@
{ config, lib, ... }:
let
cfg = config.services.forgejo;
in
{
services.forgejo = {
enable = true;
lfs.enable = true;
settings = {
# storage = {
# };
server = {
ROOT_URL = "https://${cfg.settings.server.DOMAIN}";
DOMAIN = "git.rpqt.fr";
HTTP_PORT = 3001;
LANDING_PAGE = "explore";
};
session.PROVIDER = "db";
session.COOKIE_SECURE = true;
service.DISABLE_REGISTRATION = true;
# Create a repository by pushing to it
repository.ENABLE_PUSH_CREATE_USER = true;
};
};
systemd.services.forgejo.environment = {
FORGEJO__storage__STORAGE_TYPE = "minio";
FORGEJO__storage__MINIO_ENDPOINT = "localhost:3900";
FORGEJO__storage__MINIO_BUCKET = "forgejo";
FORGEJO__storage__MINIO_LOCATION = "garage";
FORGEJO__storage__MINIO_USE_SSL = "false";
};
systemd.services.forgejo.serviceConfig = {
LoadCredential = [
"minio_access_key_id:${config.clan.core.vars.generators.forgejo-s3-storage.files.access-key-id.path}"
"minio_secret_access_key:${config.clan.core.vars.generators.forgejo-s3-storage.files.access-key-secret.path}"
];
Environment = [
"FORGEJO__storage__MINIO_ACCESS_KEY_ID__FILE=%d/minio_access_key_id"
"FORGEJO__storage__MINIO_SECRET_ACCESS_KEY__FILE=%d/minio_secret_access_key"
];
};
clan.core.vars.generators.forgejo-s3-storage = {
prompts.access-key-id = {
description = "s3 access key id";
type = "line";
persist = true;
};
prompts.access-key-secret = {
description = "s3 access key secret";
type = "hidden";
persist = true;
};
};
clan.core.state.forgejo.folders = [ config.services.forgejo.stateDir ];
services.nginx.virtualHosts."git.rpqt.fr" = {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://localhost:${builtins.toString (cfg.settings.server.HTTP_PORT)}";
};
};
security.acme.certs."git.rpqt.fr" = {
email = "admin@rpqt.fr";
};
}

60
nixosModules/garage.nix Normal file
View file

@ -0,0 +1,60 @@
{
config,
lib,
pkgs,
self,
...
}:
let
zerotier_interface = "zts7mq7onf";
zerotier_ip =
self.nixosConfigurations.${config.networking.hostName}.config.clan.core.vars.generators.zerotier.files.zerotier-ip.value;
s3_port = 3900;
rpc_port = 3901;
web_port = 3902;
admin_port = 3903;
in
{
services.garage = {
package = pkgs.garage;
settings = {
metadata_dir = "/var/lib/garage/meta";
data_dir = lib.mkDefault "/var/lib/garage/data";
db_engine = "sqlite";
replication_factor = 3;
rpc_bind_addr = "[::]:${toString rpc_port}";
rpc_public_addr = "[::]:${toString rpc_port}";
s3_api = {
api_bind_addr = "[::]:${toString s3_port}";
s3_region = "garage";
root_domain = ".s3.garage.home.rpqt.fr";
};
s3_web = {
bind_addr = "127.0.0.1:${toString web_port}";
root_domain = ".web.garage.home.rpqt.fr";
};
admin = {
api_bind_addr = "[::]:${toString admin_port}";
# TODO: use metrics_token
};
};
};
networking.firewall.interfaces =
let
allowedTCPPorts = [
s3_port
rpc_port
admin_port
];
in
{
${zerotier_interface} = { inherit allowedTCPPorts; };
wireguard = { inherit allowedTCPPorts; };
};
}

71
nixosModules/gitea.nix Normal file
View file

@ -0,0 +1,71 @@
{ config, ... }:
{
services.gitea = {
enable = true;
lfs.enable = true;
settings = {
# storage = {
# };
server = {
ROOT_URL = "https://git.turifer.dev";
DOMAIN = "git.turifer.dev";
};
session.PROVIDER = "db";
session.COOKIE_SECURE = true;
service.DISABLE_REGISTRATION = true;
# Create a repository by pushing to it
repository.ENABLE_PUSH_CREATE_USER = true;
};
};
systemd.services.gitea.environment = {
GITEA__storage__STORAGE_TYPE = "minio";
GITEA__storage__MINIO_ENDPOINT = "localhost:3900";
GITEA__storage__MINIO_BUCKET = "gitea";
GITEA__storage__MINIO_LOCATION = "garage";
GITEA__storage__MINIO_USE_SSL = "false";
};
systemd.services.gitea.serviceConfig = {
LoadCredential = [
"minio_access_key_id:${config.clan.core.vars.generators.gitea-s3-storage.files.access-key-id.path}"
"minio_secret_access_key:${config.clan.core.vars.generators.gitea-s3-storage.files.access-key-secret.path}"
];
Environment = [
"GITEA__storage__MINIO_ACCESS_KEY_ID=%d/minio_access_key_id"
"GITEA__storage__MINIO_SECRET_ACCESS_KEY=%d/minio_secret_access_key"
];
};
clan.core.vars.generators.gitea-s3-storage = {
prompts.access-key-id = {
description = "s3 access key id";
type = "line";
persist = true;
};
prompts.access-key-secret = {
description = "s3 access key secret";
type = "hidden";
persist = true;
};
};
clan.core.state.gitea.folders = [ config.services.gitea.stateDir ];
services.nginx.virtualHosts."git.turifer.dev" = {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://localhost:${builtins.toString (config.services.gitea.settings.server.HTTP_PORT)}";
};
};
security.acme.certs."git.turifer.dev" = {
email = "admin@turifer.dev";
};
}

View file

@ -0,0 +1,14 @@
{
services.openssh = {
enable = true;
settings = {
# PermitRootLogin = "no";
PasswordAuthentication = false;
KbdInteractiveAuthentication = false;
AuthenticationMethods = "publickey";
PubkeyAuthentication = "yes";
ChallengeResponseAuthentication = "no";
X11Forwarding = false;
};
};
}

View file

@ -0,0 +1,23 @@
{
self,
lib,
pkgs,
...
}:
{
imports = [
self.inputs.lanzaboote.nixosModules.lanzaboote
];
environment.systemPackages = [
# For debugging and troubleshooting Secure Boot.
pkgs.sbctl
];
boot.loader.systemd-boot.enable = lib.mkForce false;
boot.lanzaboote = {
enable = true;
pkiBundle = "/var/lib/sbctl";
};
}

13
nixosModules/lounge.nix Normal file
View file

@ -0,0 +1,13 @@
let
tld = "val";
domain = "lounge.${tld}";
in
{
services.nginx.virtualHosts.${domain} = {
enableACME = true;
forceSSL = true;
root = "/var/www/lounge";
};
security.acme.certs.${domain}.server = "https://ca.${tld}/acme/acme/directory";
}

6
nixosModules/motd.nix Normal file
View file

@ -0,0 +1,6 @@
{ config, ... }:
{
users.motd = ''
Welcome to ${config.networking.hostName}!
'';
}

View file

@ -0,0 +1,84 @@
{ config, pkgs, ... }:
let
fqdn = "cloud.rpqt.fr";
in
{
imports = [
./acme-home.nix
];
services.nextcloud = {
enable = true;
hostName = fqdn;
https = true;
package = pkgs.nextcloud32;
config = {
dbtype = "pgsql";
dbuser = "nextcloud";
dbhost = "/run/postgresql";
dbname = "nextcloud";
# admin user is only for the initial setup
adminuser = "root";
adminpassFile = config.clan.core.vars.generators.nextcloud.files.admin-password.path;
objectstore.s3 = {
enable = true;
bucket = "nextcloud";
key = config.clan.core.vars.generators.nextcloud-s3-storage.files.access-key-id.value;
secretFile = config.clan.core.vars.generators.nextcloud-s3-storage.files.access-key-secret.path;
hostname = "[${config.clan.core.vars.generators.zerotier.files.zerotier-ip.value}]";
port = 3900;
useSsl = false;
region = "garage";
usePathStyle = true;
};
};
extraAppsEnable = true;
extraApps = {
inherit (config.services.nextcloud.package.packages.apps) tasks contacts calendar;
};
};
clan.core.postgresql = {
enable = true;
databases = {
nextcloud = {
create.enable = true;
restore.stopOnRestore = [ "nextcloud" ];
};
};
};
systemd.services."nextcloud-setup" = {
requires = [ "postgresql.service" ];
after = [ "postgresql.service" ];
};
services.nginx.virtualHosts.${config.services.nextcloud.hostName} = {
forceSSL = true;
enableACME = true;
};
clan.core.vars.generators.nextcloud = {
prompts.admin-password = {
description = "nextcloud admin password";
type = "hidden";
persist = true;
};
files.admin-password.owner = "nextcloud";
};
clan.core.vars.generators.nextcloud-s3-storage = {
prompts.access-key-id = {
description = "s3 access key id";
type = "line";
persist = true;
};
prompts.access-key-secret = {
description = "s3 access key secret";
type = "hidden";
persist = true;
};
files.access-key-id.secret = false;
files.access-key-secret.owner = "nextcloud";
};
}

View file

@ -0,0 +1,20 @@
{ pkgs, ... }:
{
# for flakes
environment.systemPackages = [ pkgs.git ];
nix.settings = {
auto-optimise-store = true;
builders-use-substitutes = true;
experimental-features = [
"nix-command"
"flakes"
"pipe-operators"
];
trusted-users = [
"root"
"@wheel"
];
};
}

44
nixosModules/radicle.nix Normal file
View file

@ -0,0 +1,44 @@
{
config,
pkgs,
...
}:
{
services.radicle = {
enable = true;
privateKeyFile = config.clan.core.vars.generators.radicle.files."id_ed25519".path;
publicKey = config.clan.core.vars.generators.radicle.files."id_ed25519.pub".value;
node = {
openFirewall = true;
};
httpd = {
enable = true;
nginx = {
serverName = "radicle.rpqt.fr";
enableACME = true;
forceSSL = true;
};
};
settings = {
# FIXME: activation fails with rad saying the config is invalid
web.avatarUrl = "https://rpqt.fr/favicon.svg";
web.description = "rpqt's radicle node";
web.pinned.repositories = [
"rad:z2DH9K384tPCrM5HJcpiKEoZZdftY" # lila
"rad:z29gVX1f6HC1XGx755RL1m1hhMp6x" # corner
"rad:z36HRN3Soay4wMXBSiR4aW7Hg9rT7" # flocon
];
};
};
clan.core.vars.generators.radicle = {
files."id_ed25519".secret = true;
files."id_ed25519.pub".secret = false;
runtimeInputs = [ pkgs.openssh ];
script = ''
ssh-keygen -t ed25519 -f "$out"/id_ed25519 -N "" -C "radicle"
'';
};
clan.core.state.radicle.folders = [ "/var/lib/radicle" ];
}

View file

@ -0,0 +1,51 @@
{ config, lib, ... }:
let
cfg = config.roles.remote-builder;
in
{
options = {
roles.remote-builder = {
enable = lib.mkEnableOption {
description = "Whether to allow remote building on this machine";
};
user = lib.mkOption {
type = lib.types.str;
default = "nixremote";
example = "remote-builder";
description = "The name of the user used to run the builds";
};
group = lib.mkOption {
type = lib.types.str;
default = "${cfg.user}";
example = "remote-builder";
description = "The group of the user used to run the builds";
};
authorizedKeys = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
example = [ "ssh-ed25519 AAAA... user@host" ];
description = "List of SSH keys authorized to run builds on this machine";
};
};
};
config = lib.mkIf cfg.enable {
users.users."${cfg.user}" = {
createHome = true;
home = "/home/${cfg.user}";
isSystemUser = true;
group = cfg.group;
useDefaultShell = true;
openssh.authorizedKeys.keys = map (
key: ''restrict,command="nix-daemon --stdio" ${key}''
) cfg.authorizedKeys;
};
users.groups.${cfg.user} = { };
nix.settings.trusted-users = [ cfg.user ];
};
}

View file

@ -0,0 +1,12 @@
let
user = "u422292";
host = "${user}.your-storagebox.de";
in
{
programs.ssh.knownHosts = {
storagebox-ed25519 = {
hostNames = [ "[${host}]:23" ];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIICf9svRenC/PLKIL9nk6K/pxQgoiFC41wTNvoIncOxs";
};
};
}

View file

@ -0,0 +1,11 @@
{ config, ... }:
{
networking.firewall = {
trustedInterfaces = [ config.services.tailscale.interfaceName ];
};
services.tailscale = {
enable = true;
openFirewall = true;
};
}

View file

@ -0,0 +1,21 @@
{ lib, pkgs, ... }:
{
users.users.rpqt = {
isNormalUser = true;
createHome = lib.mkDefault true;
home = lib.mkDefault "/home/rpqt";
description = "Romain Paquet";
shell = pkgs.fish;
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGa8R8obgptefcp27Cdp9bc2fiyc9x0oTfMsTPFp2ktE rpqt@haze"
];
extraGroups = [ "wheel" ];
};
programs.fish.enable = true;
}

View file

@ -0,0 +1,18 @@
{
config,
...
}:
{
services.vaultwarden = {
enable = true;
domain = "vaultwarden.val";
configureNginx = true;
};
services.nginx.virtualHosts.${config.services.vaultwarden.domain} = {
enableACME = true;
};
security.acme.certs.${config.services.vaultwarden.domain}.server =
"https://ca.val/acme/acme/directory";
}