mirror of
https://gitlab.com/upRootNutrition/dotfiles.git
synced 2025-12-07 05:27:13 -06:00
test: trying to get microVMs to work
This commit is contained in:
parent
7c48cded1d
commit
8f74b8dbc8
10 changed files with 598 additions and 585 deletions
|
|
@ -50,7 +50,7 @@ in
|
||||||
# comfyui
|
# comfyui
|
||||||
# filesorter
|
# filesorter
|
||||||
# firefly-iii
|
# firefly-iii
|
||||||
# forgejo
|
forgejo
|
||||||
# glance
|
# glance
|
||||||
jellyfin
|
jellyfin
|
||||||
# logrotate
|
# logrotate
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,17 @@
|
||||||
{ flake, ... }:
|
{ flake, ... }:
|
||||||
{
|
let
|
||||||
imports = [
|
importList =
|
||||||
|
let
|
||||||
|
content = builtins.readDir ./.;
|
||||||
|
dirContent = builtins.filter (n: content.${n} == "directory") (builtins.attrNames content);
|
||||||
|
in
|
||||||
|
map (name: ./. + "/${name}") dirContent;
|
||||||
|
|
||||||
|
microVMImport = [
|
||||||
flake.inputs.microvm.nixosModules.host
|
flake.inputs.microvm.nixosModules.host
|
||||||
];
|
];
|
||||||
|
|
||||||
|
in
|
||||||
|
{
|
||||||
|
imports = importList ++ microVMImport;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ let
|
||||||
host = serviceCfg.domains.url0;
|
host = serviceCfg.domains.url0;
|
||||||
dns0 = instances.web.dns.provider0;
|
dns0 = instances.web.dns.provider0;
|
||||||
dns0Path = "dns/${dns0}";
|
dns0Path = "dns/${dns0}";
|
||||||
hostSecrets = "/opt/secrets";
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
microvm.vms.${serviceCfg.name} = {
|
microvm.vms.${serviceCfg.name} = {
|
||||||
219
modules/nixos/microvm/forgejo/default.nix
Executable file
219
modules/nixos/microvm/forgejo/default.nix
Executable file
|
|
@ -0,0 +1,219 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
flake,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
inherit (flake.config.people) user0;
|
||||||
|
inherit (flake.config.services) instances;
|
||||||
|
serviceCfg = flake.config.services.instances.forgejo;
|
||||||
|
smtpCfg = flake.config.services.instances.smtp;
|
||||||
|
hostCfg = flake.config.services.instances.web;
|
||||||
|
host = serviceCfg.domains.url0;
|
||||||
|
dns0 = instances.web.dns.provider0;
|
||||||
|
dns0Path = "dns/${dns0}";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
users.users.caddy.extraGroups = [ "acme" ];
|
||||||
|
|
||||||
|
security.acme.certs."${host}" = {
|
||||||
|
dnsProvider = dns0;
|
||||||
|
environmentFile = config.sops.secrets.${dns0Path}.path;
|
||||||
|
group = "caddy";
|
||||||
|
};
|
||||||
|
|
||||||
|
microvm.vms = {
|
||||||
|
${serviceCfg.name} = {
|
||||||
|
autostart = true;
|
||||||
|
restartIfChanged = true;
|
||||||
|
config = {
|
||||||
|
system.stateVersion = "24.05";
|
||||||
|
time.timeZone = "America/Winnipeg";
|
||||||
|
users.users.root.openssh.authorizedKeys.keys = flake.config.people.users.${user0}.sshKeys;
|
||||||
|
services = {
|
||||||
|
${serviceCfg.name} = {
|
||||||
|
enable = true;
|
||||||
|
lfs.enable = true;
|
||||||
|
database = {
|
||||||
|
type = "postgres";
|
||||||
|
};
|
||||||
|
secrets = {
|
||||||
|
mailer.PASSWD = "/run/secrets/smtp";
|
||||||
|
database.PASSWD = "/run/secrets/database";
|
||||||
|
};
|
||||||
|
settings = {
|
||||||
|
server = {
|
||||||
|
DOMAIN = host;
|
||||||
|
ROOT_URL = "https://${host}/";
|
||||||
|
HTTP_PORT = serviceCfg.ports.port0;
|
||||||
|
};
|
||||||
|
# If you need to start from scratch, don't forget to turn this off again
|
||||||
|
service.DISABLE_REGISTRATION = false;
|
||||||
|
actions = {
|
||||||
|
ENABLED = true;
|
||||||
|
DEFAULT_ACTIONS_URL = "github";
|
||||||
|
};
|
||||||
|
mirror = {
|
||||||
|
ENABLED = true;
|
||||||
|
};
|
||||||
|
mailer = {
|
||||||
|
ENABLED = true;
|
||||||
|
SMTP_ADDR = smtpCfg.hostname;
|
||||||
|
FROM = smtpCfg.email.address1;
|
||||||
|
USER = smtpCfg.email.address1;
|
||||||
|
PROTOCOL = "${smtpCfg.name}+${smtpCfg.records.record1}";
|
||||||
|
SMTP_PORT = smtpCfg.ports.port1;
|
||||||
|
SEND_AS_PLAIN_TEXT = true;
|
||||||
|
USE_CLIENT_CERT = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
openssh = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
PasswordAuthentication = false;
|
||||||
|
PermitRootLogin = "prohibit-password";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
postgresql = {
|
||||||
|
enable = true;
|
||||||
|
ensureDatabases = [ serviceCfg.name ];
|
||||||
|
ensureUsers = [
|
||||||
|
{
|
||||||
|
name = serviceCfg.name;
|
||||||
|
ensureDBOwnership = true;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.firewall.allowedTCPPorts = [
|
||||||
|
22 # SSH
|
||||||
|
25 # SMTP
|
||||||
|
139 # SMTP
|
||||||
|
587 # SMTP
|
||||||
|
2525 # SMTP
|
||||||
|
serviceCfg.ports.port0
|
||||||
|
];
|
||||||
|
|
||||||
|
fileSystems."/tmp" = {
|
||||||
|
device = "tmpfs";
|
||||||
|
fsType = "tmpfs";
|
||||||
|
options = [
|
||||||
|
"size=4G"
|
||||||
|
"mode=1777"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd = {
|
||||||
|
network = {
|
||||||
|
enable = true;
|
||||||
|
networks."20-lan" = {
|
||||||
|
matchConfig.Name = "enp0s5";
|
||||||
|
addresses = [ { Address = "${serviceCfg.interface.ip}/24"; } ];
|
||||||
|
routes = [
|
||||||
|
{
|
||||||
|
Destination = "${hostCfg.localhost.address1}/0";
|
||||||
|
Gateway = serviceCfg.interface.gate;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
dns = [
|
||||||
|
"1.1.1.1"
|
||||||
|
"8.8.8.8"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
tmpfiles.rules = [
|
||||||
|
"Z ${serviceCfg.varPaths.path0} 0755 ${serviceCfg.name} ${serviceCfg.name} -"
|
||||||
|
"Z /var/lib/postgresql 0755 postgres postgres -"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.systemd-networkd.wantedBy = [ "multi-user.target" ];
|
||||||
|
|
||||||
|
microvm = {
|
||||||
|
vcpu = 2;
|
||||||
|
mem = 3072;
|
||||||
|
hypervisor = "qemu";
|
||||||
|
interfaces = [
|
||||||
|
{
|
||||||
|
type = "tap";
|
||||||
|
id = serviceCfg.interface.id;
|
||||||
|
mac = serviceCfg.interface.mac;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
type = "user";
|
||||||
|
id = serviceCfg.interface.idUser;
|
||||||
|
mac = serviceCfg.interface.macUser;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
forwardPorts = [
|
||||||
|
{
|
||||||
|
from = "host";
|
||||||
|
host.port = serviceCfg.interface.ssh;
|
||||||
|
guest.port = 22;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
shares = [
|
||||||
|
{
|
||||||
|
mountPoint = "/nix/.ro-store";
|
||||||
|
proto = "virtiofs";
|
||||||
|
source = "/nix/store";
|
||||||
|
tag = "read_only_nix_store";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mountPoint = "/var/lib/${serviceCfg.name}";
|
||||||
|
proto = "virtiofs";
|
||||||
|
source = "${serviceCfg.mntPaths.path0}/data";
|
||||||
|
tag = "${serviceCfg.name}_data";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mountPoint = "/var/lib/postgresql";
|
||||||
|
proto = "virtiofs";
|
||||||
|
source = "${serviceCfg.mntPaths.path0}/database";
|
||||||
|
tag = "${serviceCfg.name}_database";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mountPoint = "/run/secrets";
|
||||||
|
proto = "virtiofs";
|
||||||
|
source = "/run/secrets/${serviceCfg.name}";
|
||||||
|
tag = "host_secrets";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.tmpfiles.rules = [
|
||||||
|
"d ${serviceCfg.mntPaths.path0}/data 0751 microvm wheel - -"
|
||||||
|
"d ${serviceCfg.mntPaths.path0}/database 0751 microvm wheel - -"
|
||||||
|
|
||||||
|
];
|
||||||
|
|
||||||
|
services.caddy.virtualHosts."${host}" = {
|
||||||
|
extraConfig = ''
|
||||||
|
reverse_proxy ${serviceCfg.interface.ip}:${toString serviceCfg.ports.port0} {
|
||||||
|
header_up X-Real-IP {remote_host}
|
||||||
|
}
|
||||||
|
|
||||||
|
tls ${serviceCfg.ssl.cert} ${serviceCfg.ssl.key}
|
||||||
|
|
||||||
|
encode zstd gzip
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
sops.secrets = {
|
||||||
|
"${serviceCfg.name}/smtp" = {
|
||||||
|
owner = "root";
|
||||||
|
mode = "0600";
|
||||||
|
};
|
||||||
|
"${serviceCfg.name}/database" = {
|
||||||
|
owner = "root";
|
||||||
|
mode = "0600";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
169
modules/nixos/microvm/jellyfin/default.nix
Executable file
169
modules/nixos/microvm/jellyfin/default.nix
Executable file
|
|
@ -0,0 +1,169 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
flake,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
inherit (flake.config.people) user0;
|
||||||
|
inherit (flake.config.services) instances;
|
||||||
|
serviceCfg = instances.jellyfin;
|
||||||
|
hostCfg = instances.web;
|
||||||
|
dns0 = instances.web.dns.provider0;
|
||||||
|
host = serviceCfg.domains.url0;
|
||||||
|
dns0Path = "dns/${dns0}";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
microvm.vms = {
|
||||||
|
${serviceCfg.name} = {
|
||||||
|
autostart = true;
|
||||||
|
restartIfChanged = true;
|
||||||
|
config = {
|
||||||
|
system.stateVersion = "25.05";
|
||||||
|
time.timeZone = "America/Winnipeg";
|
||||||
|
users.users.root.openssh.authorizedKeys.keys = flake.config.people.users.${user0}.sshKeys;
|
||||||
|
services = {
|
||||||
|
jellyfin = {
|
||||||
|
enable = true;
|
||||||
|
openFirewall = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
openssh = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
PasswordAuthentication = false;
|
||||||
|
PermitRootLogin = "prohibit-password";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.firewall.allowedTCPPorts = [
|
||||||
|
22
|
||||||
|
serviceCfg.ports.port0
|
||||||
|
serviceCfg.ports.port1
|
||||||
|
serviceCfg.ports.port2
|
||||||
|
];
|
||||||
|
|
||||||
|
# fileSystems."/tmp" = {
|
||||||
|
# device = "tmpfs";
|
||||||
|
# fsType = "tmpfs";
|
||||||
|
# options = [
|
||||||
|
# "size=4G"
|
||||||
|
# "mode=1777"
|
||||||
|
# ];
|
||||||
|
# };
|
||||||
|
|
||||||
|
systemd = {
|
||||||
|
network = {
|
||||||
|
enable = true;
|
||||||
|
networks."20-lan" = {
|
||||||
|
matchConfig.Name = "enp0s6";
|
||||||
|
addresses = [ { Address = "${serviceCfg.interface.ip}/24"; } ];
|
||||||
|
routes = [
|
||||||
|
{
|
||||||
|
Destination = "${hostCfg.localhost.address1}/0";
|
||||||
|
Gateway = serviceCfg.interface.gate;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
dns = [
|
||||||
|
"1.1.1.1"
|
||||||
|
"8.8.8.8"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
tmpfiles.rules = [
|
||||||
|
"Z ${serviceCfg.varPaths.path0} 0755 ${serviceCfg.name} ${serviceCfg.name} -"
|
||||||
|
"Z ${serviceCfg.varPaths.path2} 0755 ${serviceCfg.name} ${serviceCfg.name} -"
|
||||||
|
"d ${serviceCfg.varPaths.path1} 0755 ${serviceCfg.name} ${serviceCfg.name} -"
|
||||||
|
"Z ${serviceCfg.varPaths.path2} 0755 ${serviceCfg.name} ${serviceCfg.name} -"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.systemd-networkd.wantedBy = [ "multi-user.target" ];
|
||||||
|
|
||||||
|
microvm = {
|
||||||
|
vcpu = 6;
|
||||||
|
mem = 8192;
|
||||||
|
hypervisor = "qemu";
|
||||||
|
interfaces = [
|
||||||
|
{
|
||||||
|
type = "tap";
|
||||||
|
id = serviceCfg.interface.id;
|
||||||
|
mac = serviceCfg.interface.mac;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
type = "user";
|
||||||
|
id = serviceCfg.interface.idUser;
|
||||||
|
mac = serviceCfg.interface.macUser;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
forwardPorts = [
|
||||||
|
{
|
||||||
|
from = "host";
|
||||||
|
host.port = serviceCfg.interface.ssh;
|
||||||
|
guest.port = 22;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
shares = [
|
||||||
|
{
|
||||||
|
mountPoint = "/nix/.ro-store";
|
||||||
|
proto = "virtiofs";
|
||||||
|
source = "/nix/store";
|
||||||
|
tag = "read_only_nix_store";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mountPoint = serviceCfg.varPaths.path0;
|
||||||
|
proto = "virtiofs";
|
||||||
|
source = "${serviceCfg.mntPaths.path0}/data";
|
||||||
|
tag = "${serviceCfg.name}_data";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mountPoint = serviceCfg.varPaths.path1;
|
||||||
|
proto = "virtiofs";
|
||||||
|
source = "${serviceCfg.mntPaths.path0}/cache";
|
||||||
|
tag = "${serviceCfg.name}_cache";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mountPoint = serviceCfg.varPaths.path2;
|
||||||
|
proto = "virtiofs";
|
||||||
|
source = "${serviceCfg.mntPaths.path0}/media";
|
||||||
|
tag = "${serviceCfg.name}_media";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
security.acme.certs."${host}" = {
|
||||||
|
dnsProvider = dns0;
|
||||||
|
environmentFile = config.sops.secrets.${dns0Path}.path;
|
||||||
|
group = "caddy";
|
||||||
|
};
|
||||||
|
|
||||||
|
services = {
|
||||||
|
caddy = {
|
||||||
|
virtualHosts = {
|
||||||
|
"${host}" = {
|
||||||
|
extraConfig = ''
|
||||||
|
reverse_proxy ${serviceCfg.interface.ip}:${toString serviceCfg.ports.port0} {
|
||||||
|
header_up X-Real-IP {remote_host}
|
||||||
|
}
|
||||||
|
|
||||||
|
tls ${serviceCfg.ssl.cert} ${serviceCfg.ssl.key}
|
||||||
|
encode zstd gzip
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
users.users.caddy.extraGroups = [ "acme" ];
|
||||||
|
|
||||||
|
systemd.tmpfiles.rules = [
|
||||||
|
"d ${serviceCfg.mntPaths.path0} 0751 microvm wheel - -"
|
||||||
|
"d ${serviceCfg.mntPaths.path0}/data 0751 microvm wheel - -"
|
||||||
|
"d ${serviceCfg.mntPaths.path0}/cache 0751 microvm wheel - -"
|
||||||
|
"d ${serviceCfg.mntPaths.path0}/media 0751 microvm wheel - -"
|
||||||
|
];
|
||||||
|
}
|
||||||
193
modules/nixos/microvm/vaultwarden/default.nix
Executable file
193
modules/nixos/microvm/vaultwarden/default.nix
Executable file
|
|
@ -0,0 +1,193 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
flake,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
inherit (flake.config.people) user0;
|
||||||
|
inherit (flake.config.services) instances;
|
||||||
|
serviceCfg = instances.vaultwarden;
|
||||||
|
smtpCfg = instances.smtp;
|
||||||
|
hostCfg = instances.web;
|
||||||
|
dns0 = instances.web.dns.provider0;
|
||||||
|
host = serviceCfg.domains.url0;
|
||||||
|
dns0Path = "dns/${dns0}";
|
||||||
|
hostSecrets = "/var/lib/secrets/${serviceCfg.name}";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
microvm.vms = {
|
||||||
|
vaultwarden = {
|
||||||
|
autostart = true;
|
||||||
|
restartIfChanged = true;
|
||||||
|
config = {
|
||||||
|
system.stateVersion = "24.05";
|
||||||
|
time.timeZone = "America/Winnipeg";
|
||||||
|
users.users.root.openssh.authorizedKeys.keys = flake.config.people.users.${user0}.sshKeys;
|
||||||
|
services = {
|
||||||
|
vaultwarden = {
|
||||||
|
enable = true;
|
||||||
|
dbBackend = "sqlite";
|
||||||
|
config = {
|
||||||
|
# Domain Configuration
|
||||||
|
DOMAIN = "https://${host}";
|
||||||
|
|
||||||
|
# Email Configuration
|
||||||
|
SMTP_AUTH_MECHANISM = "Plain";
|
||||||
|
SMTP_EMBED_IMAGES = true;
|
||||||
|
SMTP_FROM = serviceCfg.email.address0;
|
||||||
|
SMTP_FROM_NAME = serviceCfg.label;
|
||||||
|
SMTP_HOST = smtpCfg.hostname;
|
||||||
|
SMTP_PORT = smtpCfg.ports.port1;
|
||||||
|
SMTP_SECURITY = smtpCfg.records.record1;
|
||||||
|
SMTP_USERNAME = smtpCfg.email.address0;
|
||||||
|
|
||||||
|
# Security Configuration
|
||||||
|
DISABLE_ADMIN_TOKEN = false;
|
||||||
|
|
||||||
|
# Event and Backup Management
|
||||||
|
EVENTS_DAYS_RETAIN = 90;
|
||||||
|
|
||||||
|
# User Features
|
||||||
|
SENDS_ALLOWED = true;
|
||||||
|
SIGNUPS_VERIFY = true;
|
||||||
|
WEB_VAULT_ENABLED = true;
|
||||||
|
|
||||||
|
# Rocket (Web Server) Settings
|
||||||
|
ROCKET_ADDRESS = "0.0.0.0";
|
||||||
|
ROCKET_PORT = serviceCfg.ports.port0;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Environment file with secrets (mounted from host)
|
||||||
|
environmentFile = "/run/secrets/env";
|
||||||
|
};
|
||||||
|
openssh = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
PasswordAuthentication = false;
|
||||||
|
PermitRootLogin = "prohibit-password";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.firewall.allowedTCPPorts = [
|
||||||
|
22 # SSH
|
||||||
|
25 # SMTP
|
||||||
|
139 # SMTP
|
||||||
|
587 # SMTP
|
||||||
|
2525 # SMTP
|
||||||
|
serviceCfg.ports.port0
|
||||||
|
];
|
||||||
|
|
||||||
|
systemd = {
|
||||||
|
network = {
|
||||||
|
enable = true;
|
||||||
|
networks."20-lan" = {
|
||||||
|
matchConfig.Name = "enp0s5";
|
||||||
|
addresses = [
|
||||||
|
{ Address = "${serviceCfg.interface.ip}/24"; }
|
||||||
|
];
|
||||||
|
routes = [
|
||||||
|
{
|
||||||
|
Destination = "${hostCfg.localhost.address1}/0";
|
||||||
|
Gateway = serviceCfg.interface.gate;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
dns = [
|
||||||
|
"1.1.1.1"
|
||||||
|
"8.8.8.8"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
tmpfiles.rules = [
|
||||||
|
"Z ${serviceCfg.varPaths.path0} 0755 ${serviceCfg.name} ${serviceCfg.name} -"
|
||||||
|
# "Z ${serviceCfg.secretPaths.path0} 0755 ${serviceCfg.name} ${serviceCfg.name} -"
|
||||||
|
];
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.systemd-networkd.wantedBy = [ "multi-user.target" ];
|
||||||
|
|
||||||
|
microvm = {
|
||||||
|
vcpu = 2;
|
||||||
|
mem = 3072;
|
||||||
|
hypervisor = "qemu";
|
||||||
|
interfaces = [
|
||||||
|
{
|
||||||
|
type = "tap";
|
||||||
|
id = serviceCfg.interface.id;
|
||||||
|
mac = serviceCfg.interface.mac;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
type = "user";
|
||||||
|
id = serviceCfg.interface.idUser;
|
||||||
|
mac = serviceCfg.interface.macUser;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
forwardPorts = [
|
||||||
|
{
|
||||||
|
from = "host";
|
||||||
|
host.port = serviceCfg.interface.ssh;
|
||||||
|
guest.port = 22;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
shares = [
|
||||||
|
{
|
||||||
|
mountPoint = "/nix/.ro-store";
|
||||||
|
proto = "virtiofs";
|
||||||
|
source = "/nix/store";
|
||||||
|
tag = "read_only_nix_store";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mountPoint = "/var/lib/bitwarden_rs";
|
||||||
|
proto = "virtiofs";
|
||||||
|
source = serviceCfg.mntPaths.path0;
|
||||||
|
tag = "vaultwarden_data";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mountPoint = "/run/secrets";
|
||||||
|
proto = "virtiofs";
|
||||||
|
source = "/run/secrets/${serviceCfg.name}";
|
||||||
|
tag = "host_secrets";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
security.acme.certs."${host}" = {
|
||||||
|
dnsProvider = dns0;
|
||||||
|
environmentFile = config.sops.secrets.${dns0Path}.path;
|
||||||
|
group = "caddy";
|
||||||
|
};
|
||||||
|
|
||||||
|
services.caddy.virtualHosts = {
|
||||||
|
"${host}" = {
|
||||||
|
extraConfig = ''
|
||||||
|
reverse_proxy ${serviceCfg.interface.ip}:${toString serviceCfg.ports.port0} {
|
||||||
|
header_up X-Real-IP {remote_host}
|
||||||
|
}
|
||||||
|
|
||||||
|
tls ${serviceCfg.ssl.cert} ${serviceCfg.ssl.key}
|
||||||
|
|
||||||
|
encode zstd gzip
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
users.users.caddy.extraGroups = [ "acme" ];
|
||||||
|
|
||||||
|
systemd.tmpfiles.rules = [
|
||||||
|
"d ${serviceCfg.mntPaths.path0} 0751 microvm wheel - -"
|
||||||
|
];
|
||||||
|
|
||||||
|
sops.secrets = {
|
||||||
|
"${serviceCfg.name}/env" = {
|
||||||
|
owner = "root";
|
||||||
|
mode = "0600";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -1,219 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
flake,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
inherit (flake.config.people) user0;
|
|
||||||
inherit (flake.config.services) instances;
|
|
||||||
serviceCfg = flake.config.services.instances.forgejo;
|
|
||||||
smtpCfg = flake.config.services.instances.smtp;
|
|
||||||
hostCfg = flake.config.services.instances.web;
|
|
||||||
host = serviceCfg.domains.url0;
|
|
||||||
dns0 = instances.web.dns.provider0;
|
|
||||||
dns0Path = "dns/${dns0}";
|
|
||||||
hostSecrets = "/opt/secrets";
|
|
||||||
in
|
|
||||||
{
|
|
||||||
users.users.caddy.extraGroups = [ "acme" ];
|
|
||||||
|
|
||||||
security.acme.certs."${host}" = {
|
|
||||||
dnsProvider = dns0;
|
|
||||||
environmentFile = config.sops.secrets.${dns0Path}.path;
|
|
||||||
group = "caddy";
|
|
||||||
};
|
|
||||||
|
|
||||||
microvm.vms.forgejo = {
|
|
||||||
autostart = true;
|
|
||||||
restartIfChanged = true;
|
|
||||||
config = {
|
|
||||||
system.stateVersion = "24.05";
|
|
||||||
time.timeZone = "America/Winnipeg";
|
|
||||||
users.users.root.openssh.authorizedKeys.keys = flake.config.people.users.${user0}.sshKeys;
|
|
||||||
services = {
|
|
||||||
forgejo = {
|
|
||||||
enable = true;
|
|
||||||
lfs.enable = true;
|
|
||||||
database = {
|
|
||||||
type = "postgres";
|
|
||||||
};
|
|
||||||
secrets = {
|
|
||||||
mailer.PASSWD = "/run/secrets/smtp";
|
|
||||||
database.PASSWD = "/run/secrets/database";
|
|
||||||
};
|
|
||||||
settings = {
|
|
||||||
server = {
|
|
||||||
DOMAIN = host;
|
|
||||||
ROOT_URL = "https://${host}/";
|
|
||||||
HTTP_PORT = serviceCfg.ports.port0;
|
|
||||||
};
|
|
||||||
# If you need to start from scratch, don't forget to turn this off again
|
|
||||||
service.DISABLE_REGISTRATION = false;
|
|
||||||
actions = {
|
|
||||||
ENABLED = true;
|
|
||||||
DEFAULT_ACTIONS_URL = "github";
|
|
||||||
};
|
|
||||||
mirror = {
|
|
||||||
ENABLED = true;
|
|
||||||
};
|
|
||||||
mailer = {
|
|
||||||
ENABLED = true;
|
|
||||||
SMTP_ADDR = smtpCfg.hostname;
|
|
||||||
FROM = smtpCfg.email.address1;
|
|
||||||
USER = smtpCfg.email.address1;
|
|
||||||
PROTOCOL = "${smtpCfg.name}+${smtpCfg.records.record1}";
|
|
||||||
SMTP_PORT = smtpCfg.ports.port1;
|
|
||||||
SEND_AS_PLAIN_TEXT = true;
|
|
||||||
USE_CLIENT_CERT = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
openssh = {
|
|
||||||
enable = true;
|
|
||||||
settings = {
|
|
||||||
PasswordAuthentication = false;
|
|
||||||
PermitRootLogin = "prohibit-password";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
postgresql = {
|
|
||||||
enable = true;
|
|
||||||
ensureDatabases = [ serviceCfg.name ];
|
|
||||||
ensureUsers = [
|
|
||||||
{
|
|
||||||
name = serviceCfg.name;
|
|
||||||
ensureDBOwnership = true;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
networking.firewall.allowedTCPPorts = [
|
|
||||||
22 # SSH
|
|
||||||
25 # SMTP
|
|
||||||
139 # SMTP
|
|
||||||
587 # SMTP
|
|
||||||
2525 # SMTP
|
|
||||||
serviceCfg.ports.port0
|
|
||||||
];
|
|
||||||
|
|
||||||
fileSystems."/tmp" = {
|
|
||||||
device = "tmpfs";
|
|
||||||
fsType = "tmpfs";
|
|
||||||
options = [
|
|
||||||
"size=4G"
|
|
||||||
"mode=1777"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd = {
|
|
||||||
network = {
|
|
||||||
enable = true;
|
|
||||||
networks."20-lan" = {
|
|
||||||
matchConfig.Name = "enp0s5";
|
|
||||||
addresses = [ { Address = "${serviceCfg.interface.ip}/24"; } ];
|
|
||||||
routes = [
|
|
||||||
{
|
|
||||||
Destination = "${hostCfg.localhost.address1}/0";
|
|
||||||
Gateway = serviceCfg.interface.gate;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
dns = [
|
|
||||||
"1.1.1.1"
|
|
||||||
"8.8.8.8"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
tmpfiles.rules = [
|
|
||||||
"Z ${serviceCfg.varPaths.path0} 0755 ${serviceCfg.name} ${serviceCfg.name} -"
|
|
||||||
# "Z ${serviceCfg.secretPaths.path0} 0755 ${serviceCfg.name} ${serviceCfg.name} -"
|
|
||||||
"Z /var/lib/postgresql 0755 postgres postgres -"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services.systemd-networkd.wantedBy = [ "multi-user.target" ];
|
|
||||||
|
|
||||||
microvm = {
|
|
||||||
vcpu = 2;
|
|
||||||
mem = 3072;
|
|
||||||
hypervisor = "qemu";
|
|
||||||
interfaces = [
|
|
||||||
{
|
|
||||||
type = "tap";
|
|
||||||
id = serviceCfg.interface.id;
|
|
||||||
mac = serviceCfg.interface.mac;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
type = "user";
|
|
||||||
id = serviceCfg.interface.idUser;
|
|
||||||
mac = serviceCfg.interface.macUser;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
forwardPorts = [
|
|
||||||
{
|
|
||||||
from = "host";
|
|
||||||
host.port = serviceCfg.interface.ssh;
|
|
||||||
guest.port = 22;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
shares = [
|
|
||||||
{
|
|
||||||
mountPoint = "/nix/.ro-store";
|
|
||||||
proto = "virtiofs";
|
|
||||||
source = "/nix/store";
|
|
||||||
tag = "read_only_nix_store";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
mountPoint = "/var/lib/${serviceCfg.name}";
|
|
||||||
proto = "virtiofs";
|
|
||||||
source = "${serviceCfg.mntPaths.path0}/data";
|
|
||||||
tag = "${serviceCfg.name}_data";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
mountPoint = "/var/lib/postgresql";
|
|
||||||
proto = "virtiofs";
|
|
||||||
source = "${serviceCfg.mntPaths.path0}/database";
|
|
||||||
tag = "${serviceCfg.name}_database";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
mountPoint = "/run/secrets";
|
|
||||||
proto = "virtiofs";
|
|
||||||
source = "/run/secrets/${serviceCfg.name}";
|
|
||||||
tag = "host_secrets";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.tmpfiles.rules = [
|
|
||||||
"d ${serviceCfg.mntPaths.path0}/data 0751 microvm wheel - -"
|
|
||||||
"d ${serviceCfg.mntPaths.path0}/database 0751 microvm wheel - -"
|
|
||||||
|
|
||||||
];
|
|
||||||
|
|
||||||
services.caddy.virtualHosts."${host}" = {
|
|
||||||
extraConfig = ''
|
|
||||||
reverse_proxy ${serviceCfg.interface.ip}:${toString serviceCfg.ports.port0} {
|
|
||||||
header_up X-Real-IP {remote_host}
|
|
||||||
}
|
|
||||||
|
|
||||||
tls ${serviceCfg.ssl.cert} ${serviceCfg.ssl.key}
|
|
||||||
|
|
||||||
encode zstd gzip
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
sops.secrets = {
|
|
||||||
"${serviceCfg.name}/smtp" = {
|
|
||||||
owner = "root";
|
|
||||||
mode = "0600";
|
|
||||||
};
|
|
||||||
"${serviceCfg.name}/database" = {
|
|
||||||
owner = "root";
|
|
||||||
mode = "0600";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,167 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
flake,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
inherit (flake.config.people) user0;
|
|
||||||
inherit (flake.config.services) instances;
|
|
||||||
serviceCfg = instances.jellyfin;
|
|
||||||
hostCfg = instances.web;
|
|
||||||
dns0 = instances.web.dns.provider0;
|
|
||||||
host = serviceCfg.domains.url0;
|
|
||||||
dns0Path = "dns/${dns0}";
|
|
||||||
in
|
|
||||||
{
|
|
||||||
microvm.vms.jellyfin = {
|
|
||||||
autostart = true;
|
|
||||||
restartIfChanged = true;
|
|
||||||
config = {
|
|
||||||
system.stateVersion = "25.05";
|
|
||||||
time.timeZone = "America/Winnipeg";
|
|
||||||
users.users.root.openssh.authorizedKeys.keys = flake.config.people.users.${user0}.sshKeys;
|
|
||||||
services = {
|
|
||||||
jellyfin = {
|
|
||||||
enable = true;
|
|
||||||
openFirewall = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
openssh = {
|
|
||||||
enable = true;
|
|
||||||
settings = {
|
|
||||||
PasswordAuthentication = false;
|
|
||||||
PermitRootLogin = "prohibit-password";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
networking.firewall.allowedTCPPorts = [
|
|
||||||
22
|
|
||||||
serviceCfg.ports.port0
|
|
||||||
serviceCfg.ports.port1
|
|
||||||
serviceCfg.ports.port2
|
|
||||||
];
|
|
||||||
|
|
||||||
# fileSystems."/tmp" = {
|
|
||||||
# device = "tmpfs";
|
|
||||||
# fsType = "tmpfs";
|
|
||||||
# options = [
|
|
||||||
# "size=4G"
|
|
||||||
# "mode=1777"
|
|
||||||
# ];
|
|
||||||
# };
|
|
||||||
|
|
||||||
systemd = {
|
|
||||||
network = {
|
|
||||||
enable = true;
|
|
||||||
networks."20-lan" = {
|
|
||||||
matchConfig.Name = "enp0s6";
|
|
||||||
addresses = [ { Address = "${serviceCfg.interface.ip}/24"; } ];
|
|
||||||
routes = [
|
|
||||||
{
|
|
||||||
Destination = "${hostCfg.localhost.address1}/0";
|
|
||||||
Gateway = serviceCfg.interface.gate;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
dns = [
|
|
||||||
"1.1.1.1"
|
|
||||||
"8.8.8.8"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
tmpfiles.rules = [
|
|
||||||
"Z ${serviceCfg.varPaths.path0} 0755 ${serviceCfg.name} ${serviceCfg.name} -"
|
|
||||||
"Z ${serviceCfg.varPaths.path2} 0755 ${serviceCfg.name} ${serviceCfg.name} -"
|
|
||||||
"d ${serviceCfg.varPaths.path1} 0755 ${serviceCfg.name} ${serviceCfg.name} -"
|
|
||||||
"Z ${serviceCfg.varPaths.path2} 0755 ${serviceCfg.name} ${serviceCfg.name} -"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services.systemd-networkd.wantedBy = [ "multi-user.target" ];
|
|
||||||
|
|
||||||
microvm = {
|
|
||||||
vcpu = 6;
|
|
||||||
mem = 8192;
|
|
||||||
hypervisor = "qemu";
|
|
||||||
interfaces = [
|
|
||||||
{
|
|
||||||
type = "tap";
|
|
||||||
id = serviceCfg.interface.id;
|
|
||||||
mac = serviceCfg.interface.mac;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
type = "user";
|
|
||||||
id = serviceCfg.interface.idUser;
|
|
||||||
mac = serviceCfg.interface.macUser;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
forwardPorts = [
|
|
||||||
{
|
|
||||||
from = "host";
|
|
||||||
host.port = serviceCfg.interface.ssh;
|
|
||||||
guest.port = 22;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
shares = [
|
|
||||||
{
|
|
||||||
mountPoint = "/nix/.ro-store";
|
|
||||||
proto = "virtiofs";
|
|
||||||
source = "/nix/store";
|
|
||||||
tag = "read_only_nix_store";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
mountPoint = serviceCfg.varPaths.path0;
|
|
||||||
proto = "virtiofs";
|
|
||||||
source = "${serviceCfg.mntPaths.path0}/data";
|
|
||||||
tag = "${serviceCfg.name}_data";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
mountPoint = serviceCfg.varPaths.path1;
|
|
||||||
proto = "virtiofs";
|
|
||||||
source = "${serviceCfg.mntPaths.path0}/cache";
|
|
||||||
tag = "${serviceCfg.name}_cache";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
mountPoint = serviceCfg.varPaths.path2;
|
|
||||||
proto = "virtiofs";
|
|
||||||
source = "${serviceCfg.mntPaths.path0}/media";
|
|
||||||
tag = "${serviceCfg.name}_media";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
security.acme.certs."${host}" = {
|
|
||||||
dnsProvider = dns0;
|
|
||||||
environmentFile = config.sops.secrets.${dns0Path}.path;
|
|
||||||
group = "caddy";
|
|
||||||
};
|
|
||||||
|
|
||||||
services = {
|
|
||||||
caddy = {
|
|
||||||
virtualHosts = {
|
|
||||||
"${host}" = {
|
|
||||||
extraConfig = ''
|
|
||||||
reverse_proxy ${serviceCfg.interface.ip}:${toString serviceCfg.ports.port0} {
|
|
||||||
header_up X-Real-IP {remote_host}
|
|
||||||
}
|
|
||||||
|
|
||||||
tls ${serviceCfg.ssl.cert} ${serviceCfg.ssl.key}
|
|
||||||
encode zstd gzip
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
users.users.caddy.extraGroups = [ "acme" ];
|
|
||||||
|
|
||||||
systemd.tmpfiles.rules = [
|
|
||||||
"d ${serviceCfg.mntPaths.path0} 0751 microvm wheel - -"
|
|
||||||
"d ${serviceCfg.mntPaths.path0}/data 0751 microvm wheel - -"
|
|
||||||
"d ${serviceCfg.mntPaths.path0}/cache 0751 microvm wheel - -"
|
|
||||||
"d ${serviceCfg.mntPaths.path0}/media 0751 microvm wheel - -"
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
@ -1,192 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
flake,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
inherit (flake.config.people) user0;
|
|
||||||
inherit (flake.config.services) instances;
|
|
||||||
serviceCfg = instances.vaultwarden;
|
|
||||||
smtpCfg = instances.smtp;
|
|
||||||
hostCfg = instances.web;
|
|
||||||
dns0 = instances.web.dns.provider0;
|
|
||||||
host = serviceCfg.domains.url0;
|
|
||||||
dns0Path = "dns/${dns0}";
|
|
||||||
hostSecrets = "/var/lib/secrets/${serviceCfg.name}";
|
|
||||||
in
|
|
||||||
{
|
|
||||||
|
|
||||||
microvm.vms.vaultwarden = {
|
|
||||||
autostart = true;
|
|
||||||
restartIfChanged = true;
|
|
||||||
config = {
|
|
||||||
system.stateVersion = "24.05";
|
|
||||||
time.timeZone = "America/Winnipeg";
|
|
||||||
users.users.root.openssh.authorizedKeys.keys = flake.config.people.users.${user0}.sshKeys;
|
|
||||||
services = {
|
|
||||||
vaultwarden = {
|
|
||||||
enable = true;
|
|
||||||
dbBackend = "sqlite";
|
|
||||||
config = {
|
|
||||||
# Domain Configuration
|
|
||||||
DOMAIN = "https://${host}";
|
|
||||||
|
|
||||||
# Email Configuration
|
|
||||||
SMTP_AUTH_MECHANISM = "Plain";
|
|
||||||
SMTP_EMBED_IMAGES = true;
|
|
||||||
SMTP_FROM = serviceCfg.email.address0;
|
|
||||||
SMTP_FROM_NAME = serviceCfg.label;
|
|
||||||
SMTP_HOST = smtpCfg.hostname;
|
|
||||||
SMTP_PORT = smtpCfg.ports.port1;
|
|
||||||
SMTP_SECURITY = smtpCfg.records.record1;
|
|
||||||
SMTP_USERNAME = smtpCfg.email.address0;
|
|
||||||
|
|
||||||
# Security Configuration
|
|
||||||
DISABLE_ADMIN_TOKEN = false;
|
|
||||||
|
|
||||||
# Event and Backup Management
|
|
||||||
EVENTS_DAYS_RETAIN = 90;
|
|
||||||
|
|
||||||
# User Features
|
|
||||||
SENDS_ALLOWED = true;
|
|
||||||
SIGNUPS_VERIFY = true;
|
|
||||||
WEB_VAULT_ENABLED = true;
|
|
||||||
|
|
||||||
# Rocket (Web Server) Settings
|
|
||||||
ROCKET_ADDRESS = "0.0.0.0";
|
|
||||||
ROCKET_PORT = serviceCfg.ports.port0;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Environment file with secrets (mounted from host)
|
|
||||||
environmentFile = "/run/secrets/env";
|
|
||||||
};
|
|
||||||
openssh = {
|
|
||||||
enable = true;
|
|
||||||
settings = {
|
|
||||||
PasswordAuthentication = false;
|
|
||||||
PermitRootLogin = "prohibit-password";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
networking.firewall.allowedTCPPorts = [
|
|
||||||
22 # SSH
|
|
||||||
25 # SMTP
|
|
||||||
139 # SMTP
|
|
||||||
587 # SMTP
|
|
||||||
2525 # SMTP
|
|
||||||
serviceCfg.ports.port0
|
|
||||||
];
|
|
||||||
|
|
||||||
systemd = {
|
|
||||||
network = {
|
|
||||||
enable = true;
|
|
||||||
networks."20-lan" = {
|
|
||||||
matchConfig.Name = "enp0s5";
|
|
||||||
addresses = [
|
|
||||||
{ Address = "${serviceCfg.interface.ip}/24"; }
|
|
||||||
];
|
|
||||||
routes = [
|
|
||||||
{
|
|
||||||
Destination = "${hostCfg.localhost.address1}/0";
|
|
||||||
Gateway = serviceCfg.interface.gate;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
dns = [
|
|
||||||
"1.1.1.1"
|
|
||||||
"8.8.8.8"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
tmpfiles.rules = [
|
|
||||||
"Z ${serviceCfg.varPaths.path0} 0755 ${serviceCfg.name} ${serviceCfg.name} -"
|
|
||||||
# "Z ${serviceCfg.secretPaths.path0} 0755 ${serviceCfg.name} ${serviceCfg.name} -"
|
|
||||||
];
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services.systemd-networkd.wantedBy = [ "multi-user.target" ];
|
|
||||||
|
|
||||||
microvm = {
|
|
||||||
vcpu = 2;
|
|
||||||
mem = 3072;
|
|
||||||
hypervisor = "qemu";
|
|
||||||
interfaces = [
|
|
||||||
{
|
|
||||||
type = "tap";
|
|
||||||
id = serviceCfg.interface.id;
|
|
||||||
mac = serviceCfg.interface.mac;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
type = "user";
|
|
||||||
id = serviceCfg.interface.idUser;
|
|
||||||
mac = serviceCfg.interface.macUser;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
forwardPorts = [
|
|
||||||
{
|
|
||||||
from = "host";
|
|
||||||
host.port = serviceCfg.interface.ssh;
|
|
||||||
guest.port = 22;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
shares = [
|
|
||||||
{
|
|
||||||
mountPoint = "/nix/.ro-store";
|
|
||||||
proto = "virtiofs";
|
|
||||||
source = "/nix/store";
|
|
||||||
tag = "read_only_nix_store";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
mountPoint = "/var/lib/bitwarden_rs";
|
|
||||||
proto = "virtiofs";
|
|
||||||
source = serviceCfg.mntPaths.path0;
|
|
||||||
tag = "vaultwarden_data";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
mountPoint = "/run/secrets";
|
|
||||||
proto = "virtiofs";
|
|
||||||
source = "/run/secrets/${serviceCfg.name}";
|
|
||||||
tag = "host_secrets";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
security.acme.certs."${host}" = {
|
|
||||||
dnsProvider = dns0;
|
|
||||||
environmentFile = config.sops.secrets.${dns0Path}.path;
|
|
||||||
group = "caddy";
|
|
||||||
};
|
|
||||||
|
|
||||||
services.caddy.virtualHosts = {
|
|
||||||
"${host}" = {
|
|
||||||
extraConfig = ''
|
|
||||||
reverse_proxy ${serviceCfg.interface.ip}:${toString serviceCfg.ports.port0} {
|
|
||||||
header_up X-Real-IP {remote_host}
|
|
||||||
}
|
|
||||||
|
|
||||||
tls ${serviceCfg.ssl.cert} ${serviceCfg.ssl.key}
|
|
||||||
|
|
||||||
encode zstd gzip
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
users.users.caddy.extraGroups = [ "acme" ];
|
|
||||||
|
|
||||||
systemd.tmpfiles.rules = [
|
|
||||||
"d ${serviceCfg.mntPaths.path0} 0751 microvm wheel - -"
|
|
||||||
];
|
|
||||||
|
|
||||||
sops.secrets = {
|
|
||||||
"${serviceCfg.name}/env" = {
|
|
||||||
owner = "root";
|
|
||||||
mode = "0600";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
ssh:
|
ssh:
|
||||||
private: ENC[AES256_GCM,data:XJk/gjPkFeSZtPkKYS2vRHqMY/X5zRaDlS4UwzUvjm9MvTgdhoXUlqvFC0Dl5SZhRlY+XXAuG7gIIUESzCFWQKdOoUcto3r0WSuIm9EwLKXnnaHemeFVHYgZU9Rz45PK6yFWUC06+n56b2A1dFXftjeXcCqaQrT/jk3RDSHmhW9u7QgDmhhaybxXOrzkup2U8kjhrMmRBcf4xP//nihuzHcyYX75ONr56bgkjl6gpZTfZrn2ad8b+4iGn+rElzf7RHAG0mwTeEX2kYRyafaanGuc2xTnZubBAYDnc1eM6T99PXC0iWh/lUKc1zG1l18UchWzgvl3sPK0Cb2/5aaFMUk2ET6kVOlpKyGc94MRpyv3iUi8soFjh34sWH3mFtec2OWfIxDhoVfZoc2hmP2Hflfjp7acwaMskFBHaCSO2DGtNmN3hSUhAAeLx8OZupSIJmDVpq00qKUbN+5z4K78AdGuUOP07cE889evNniCHLP6yPav7tIulnBS9lD2U+CbqF7vMtdZx/eYFwJjmMtE,iv:JxSytvXKWLHDedlE0Wq5YpPUnfb0HoQgKJ2bt1Z8yqk=,tag:MjOoUSWsHWHgxp0yu9YQFA==,type:str]
|
private: ENC[AES256_GCM,data:XJk/gjPkFeSZtPkKYS2vRHqMY/X5zRaDlS4UwzUvjm9MvTgdhoXUlqvFC0Dl5SZhRlY+XXAuG7gIIUESzCFWQKdOoUcto3r0WSuIm9EwLKXnnaHemeFVHYgZU9Rz45PK6yFWUC06+n56b2A1dFXftjeXcCqaQrT/jk3RDSHmhW9u7QgDmhhaybxXOrzkup2U8kjhrMmRBcf4xP//nihuzHcyYX75ONr56bgkjl6gpZTfZrn2ad8b+4iGn+rElzf7RHAG0mwTeEX2kYRyafaanGuc2xTnZubBAYDnc1eM6T99PXC0iWh/lUKc1zG1l18UchWzgvl3sPK0Cb2/5aaFMUk2ET6kVOlpKyGc94MRpyv3iUi8soFjh34sWH3mFtec2OWfIxDhoVfZoc2hmP2Hflfjp7acwaMskFBHaCSO2DGtNmN3hSUhAAeLx8OZupSIJmDVpq00qKUbN+5z4K78AdGuUOP07cE889evNniCHLP6yPav7tIulnBS9lD2U+CbqF7vMtdZx/eYFwJjmMtE,iv:JxSytvXKWLHDedlE0Wq5YpPUnfb0HoQgKJ2bt1Z8yqk=,tag:MjOoUSWsHWHgxp0yu9YQFA==,type:str]
|
||||||
public: ENC[AES256_GCM,data:Cn4hutHHeptbefHOKK7zv5TmveGOqfHAwGHogDq9sRmeb+b1lzHwj7qvg8lcnlJtIo4qS+TrKtSj5ZCsPNXOhWG1rkk97gTfPMbcxj5f1O3WJigL2wsrB2cQgc5UsA==,iv:ID4zRdr/efClOAHbXzxG1bNuJR0A2qbydzGlMhvEcRE=,tag:qbIoaGb+RXxRRkkQtuX7/A==,type:str]
|
public: ENC[AES256_GCM,data:Cn4hutHHeptbefHOKK7zv5TmveGOqfHAwGHogDq9sRmeb+b1lzHwj7qvg8lcnlJtIo4qS+TrKtSj5ZCsPNXOhWG1rkk97gTfPMbcxj5f1O3WJigL2wsrB2cQgc5UsA==,iv:ID4zRdr/efClOAHbXzxG1bNuJR0A2qbydzGlMhvEcRE=,tag:qbIoaGb+RXxRRkkQtuX7/A==,type:str]
|
||||||
hosts: ENC[AES256_GCM,data:cgizSZ5PiwkhNm2c3PNYOO29iNUg6U+skkSb5HpOeYNFv3ZkwtVM3SdEXdZEHDF91JhFeoJiNevLF80ol7YR9J493bQsEZPuOyMIpsDIWAHKFBS+S46ekG/oBwN8JZUy0Hnh3x421cg5KOE8J8Um5wJhh8Lun9Y0747nmEhqXt+cAjzaGNBbuFJR7z8XAO8/ZjrBxOr+LcxJt2IYG6PqA6r9ZEFEglXqxDeezTcQsNxIGuflBrB0QKyUp0CGkM4uaW9506UrvUzdHh71hYHm5Ir9pmhYawlWCWuOgydR8aCkIiz2lbatvjukHJvoMd2S1TxSYHMkheXMhFEDmfzQvPW/7LdfQ3PmMyGq23JFuSxsvPXSOLpI2QfqpQBwkCbNhzEkmc0ln50rRAka/z4HfR6Ga77FLW9Jcz9rpwRiI0eF46x1gRxiB2DO74kSwwZgjTNyafPGChQJjDh6Fycs9ivMOFEoltIaipHHSrxDTQvz1nhJkb1S/qgQEkfm9GbfJS9OxYgheHzWJOxtocPVVpUc5wac/9KrS2O1lfgI4IrtNF1J0zti6JcsGewFQZzfDx6usTKw/R9T1okNhtM4njn5qADsJyWnpkuiiqXh2ozO9CLgehxpm6oSbw/FVA3BDME2iU+16CXsZVxxVW3zSSI5ctZXpkDgSJh19DCh7Er5nb6iwsLLCCRqcIKtfAf2ZHPABB2BoZE0CGvf/nnkQd++MfL9W18OwXz3/9aVkW+gYNrDU9Mv8LiGz0BIarpneTdIw4i+LT7wtv5h0RSjvfJS50LP/1eK39vTwP9OiJ5UsCDyURSkB2sVS0MeSca6nVGoIOdWr2ee8IBp3QFS24VWZvLFE+0MY90S4ZNZsOF8nmN+M/SCvS4h/ixqQQ6zr+qtS8Hm1N/EHx2U2CqRbE64HnQhaHnj/hKUkQiABIlt1kz1eR2NjEt5aa1hQyoKl8E4J9V9V/u3t3vd0aIkWFL08SUEQEQWith066Jdf0VMdQvaSUKiSlhfZZ5Wj6ex1Y1hX9vT9utEGUAS12vlh2KMEpPi6eFxvIyOiu7bCMSeicQLpjGKEIsKJOVDPYPjbilwXuz8agjUevoguoAT12CKdCWPlnrjuByCZ34/U/qBHdak7UqnjS9MbbDTIcr8uz/2g8w2dMIAbRA0I9A4CrOUAAecIPQMCFU2scuJt+4xxZxof+HUlyqXQR3YD6Wh89/5rVK+kvgoNjflijegxW0rju7NyU0kU3jZp36V1F4HxzXsz7OOHmN54GJTvRSqhrQfQ39+eOSvyd04pwCM7EAOfJYw0moozVnVtmjnDLVjR49ho9qHrvDVLJ/sEcG/iyDrNtp8PCq9OK6EOEgPGNq4qDEow1GelPz6M1BU7t+KL5QnqDi0azz7L2ctx9N6b34LOHgNoHD5qGWP0CnNo1Pq7lQYoN9/XHYdQbHrc8NWjR56NmBnUnA65Af8+67J7+stLSVDrUyRRf9Ohcp5k6WK5N1yyJeYxa1EDulsXzToEEbadSbbS6REEESEn/jlup7U5NituT5wT9al,iv:ervRE0xkjtsKNYB/1W9oHM59lHwHTsOk3NLhnaRvWCM=,tag:Yj3emxFA5h2ndIilC5L16w==,type:str]
|
hosts: ENC[AES256_GCM,data:QuyhBCfYd/CXRhqbenhO7c8PRuaxMQyXVwetbCN5qOwRv32IPOAYcFByQygmz6J3sAaw47arSYXqNWarzRNX0OPfEvxAusIDyB4Ia0kRnELJKJ+LHOWC8fbKwh+w1IVPFznEUDJsq2dIkMd3uOLw+R70Z2A/uTycjOI8ZtTz+Pw0fbu8wtGUR0yzTjgMVia7L7L6m2k5Owkc6M+MYqd2GlkSarVQa+XiwOmp06hEVqSeWb/rXIGEszb54iC0jbnArfAHVeiZ9moLogDpcZRUFEUxY72wG3Y7DM0bNEG5B3bXm11hemvIGPCY1kqvG4ROtDbvgx6C4XNupxiYG9tUMneJHwfRXAFs4gGO0r7wSsE8qQePWAlGg4YcpZX/R3WraQsUSHjS4rGtqNUAsEMRN195/WChcHGyP2aMjrzl1RSs27fIA7O04pLEH6Uhcv26Rp7c1JwlpvcKgnMZ0GqiHKuqVYYJMPEzLWlWXpRpcODDB5iqad0o0T/9rnVlK7HGhCTEl5rYj0jSYrwu4ktApZ2jNMCsMNIek1p12OJK1RrP9HvIThuSDNXo5vaIreHL1MlIgMb4t8MvsXcczN1+yAiJ0msZhyV/OH/LRO3pfceHMmf3LCB7zIFsJpTcQGAMFrscSA7D6Zise81GMIL2DJVzlbdhQxIwB2DTDa7mf74DdZzUkNbQCbWRP6YnrfiIOCcQGWMVXbm+QVr48l066NXfuxPbFFnCT3hK3cnNwRpMzTqzLc5ol6kxtN+ryVPCQ7hvMe1InoSnMXJhf5GEeEUH26mAOQ2o1eakcKonyCTLi0Ui1Wlw2x9EbM0QCk9Nl5YcxUZLPddEyWdkvCJ8JqGM5IitTNwuzHLUjqkNb+DP0d35ON2ek5vK9kAh8oJOuN8vKVdvbR3XmexEbo9oviGSQwB3dWl274D29Oy7k2H7u+rro+HDeZp1MCkCJ8DgvKGaHYXNjESVNxSJ9/sch0i5h2N2aEs0lK8/WqpW6K6DX6m2yjO7qdZf+j31bilRZD6mwELMtXrpQWwH9OIEYDsCxxjC/Q4soZ+d61U6YRdXrhfG4wwrL6GWr6CQD46kDobNlnt2mrdlWOrWz5tfPhsEAHZ5f7/WNk+xTHC+MuDt/aFUGisXuW5Wv2LmADBIHablsV2V1THDeT+r1753djtI4zn9QGWQnJ+5kgsw+lQScJVROOPriSJYWrvHJmkDMMOg2I5yYyx9jQO1xafPM5RO05FDQo8zJtCodKmZVyikP97mspFfKukBKuUHC9X3OXaIbvUrc3RDh/L7whQ5p3Ih+fgTFm4Pw+yPVq6KJ9hNMRmuvrnZsstWeMBIg5hus5k8g4q+xHmL5uVjLvkDxCFgoKC66gQYENm/XPYdcj3b5bSRW4WYoofk0XjppgU/zGKIrgtr3F7mWo64ZMwv9XyVznReHNVBcyRxQlvLdpAzrb8vczEKFkpyRdM+uIdovNl88vhgaLbLKtIY9LVp7w1p7QIuCkBqS1qAhFzYd20NZKDTAd6TnUfPC+/bswbHslSNEIFYBoUvEwJW,iv:OZdzyvCeRCHMqdUPkHGxiZdXlm/+u0LAagk7HLHWG94=,tag:IkDpOIQmtC5FvKjlmmhH2A==,type:str]
|
||||||
network:
|
network:
|
||||||
server: ENC[AES256_GCM,data:EFsmXNkuf5OAMh8hjfZTixmmdjqBNIME9JjQC8azeCwcMVInm8bWdxE4OqFmxOk9MAU=,iv:pI6WeM2aQC+7vx1Xmp5O2rikqNLgzuEOg+Lo7TqFQxU=,tag:ElcA8mn9dx+IjIf38nKT5A==,type:str]
|
server: ENC[AES256_GCM,data:EFsmXNkuf5OAMh8hjfZTixmmdjqBNIME9JjQC8azeCwcMVInm8bWdxE4OqFmxOk9MAU=,iv:pI6WeM2aQC+7vx1Xmp5O2rikqNLgzuEOg+Lo7TqFQxU=,tag:ElcA8mn9dx+IjIf38nKT5A==,type:str]
|
||||||
fallaryn: ENC[AES256_GCM,data:O77hH3STB6zpl0b9iXsVu9OOrlLKUwfs2qI9hdqX4kMuBs3XgT/xsQ==,iv:RDKsuJoy+LIyADMc3bgOEmLKdXtu6kad2aeVetuZdJI=,tag:MrpCZ+iJUnGIjeHMgcYG6Q==,type:str]
|
fallaryn: ENC[AES256_GCM,data:O77hH3STB6zpl0b9iXsVu9OOrlLKUwfs2qI9hdqX4kMuBs3XgT/xsQ==,iv:RDKsuJoy+LIyADMc3bgOEmLKdXtu6kad2aeVetuZdJI=,tag:MrpCZ+iJUnGIjeHMgcYG6Q==,type:str]
|
||||||
|
|
@ -61,7 +61,7 @@ sops:
|
||||||
bXBOa1VSakoyaWxpODJEOU11QUZCaUEK8Ch9Ten3DdrPHF1DTH2qei85AlHUOaLD
|
bXBOa1VSakoyaWxpODJEOU11QUZCaUEK8Ch9Ten3DdrPHF1DTH2qei85AlHUOaLD
|
||||||
aNfzakake7ej+MxJYdKEU0bcWofNMKzIlZa2uM10KZSENDP8d8qlig==
|
aNfzakake7ej+MxJYdKEU0bcWofNMKzIlZa2uM10KZSENDP8d8qlig==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
lastmodified: "2025-11-10T05:21:40Z"
|
lastmodified: "2025-11-11T03:26:53Z"
|
||||||
mac: ENC[AES256_GCM,data:1e2wUXNJSCP5108HqTnaEalBrDgGI60CgsLrc/ZWE52OpUxOkzfhXZDb1MZWkPEUbmc3ZeJazF9SHBHspYqnO/wznisEzLAPpGMLJePqSPla6pg81UqZdVawwtqoopurCmtr/SHpdQfGcHk9pR5n7tDdwat7xIEPoOStyZUpoDE=,iv:wg9XTEIr4ozhqr4mQP5auG+DZls1towlDAJSGXb08SI=,tag:PUDxUZfTYqy+FMGd6sLy3g==,type:str]
|
mac: ENC[AES256_GCM,data:Wsc9G4UIX/GfuYdHgf/rMqHNJBKFQp4/pp13IJhFXyONxullcHqH5qZBophGen9loRhaRTLVglRDVPEfQwisFJHIDu6yQ7A2YLLVl5oZ5GB2jkUxK/hnw5FqQG5NTaoAls150niyDQchTe0GO7YzEamIucnJwkiUVsc0+7ZGED4=,iv:ZOk64KSwjvN28stBE3xJu4oxSCyVhTsJnqBeliHUyp8=,tag:IhQeULWdFBuIvqGy9SEcTQ==,type:str]
|
||||||
unencrypted_suffix: _unencrypted
|
unencrypted_suffix: _unencrypted
|
||||||
version: 3.11.0
|
version: 3.11.0
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue