Files
nixos/hosts/freun-dev/services.nix
2026-05-29 19:29:45 +03:00

479 lines
12 KiB
Nix

{
pkgs,
pkgs-unstable,
config,
inputs,
lib,
...
}:
let
immichDataDir = "/mnt/storage/immich";
syncthingDataDir = "/mnt/storage/syncthing";
smtp = {
host = "horologium.uberspace.de";
port = 587;
username = "noreply@${config.networking.domain}";
from = "noreply@${config.networking.domain}";
heloName = config.networking.domain;
};
secrets = config.age.secrets;
in
{
nixpkgs.config.allowUnfree = true;
imports = [
./glance.nix
];
virtualisation.podman.enable = true;
virtualisation.oci-containers.backend = "podman";
security.acme.defaults.environmentFile = secrets.hetzner.path;
modules.storageBoxMounts = {
${immichDataDir} = {
path = "/backup/immich";
user = "u407959";
uid = config.users.users.${config.services.immich.user}.uid;
gid = config.users.groups.${config.services.immich.user}.gid;
};
${syncthingDataDir} = {
path = "/backup/syncthing";
user = "u407959";
uid = config.users.users.${config.services.syncthing.user}.uid;
gid = config.users.groups.${config.services.syncthing.user}.gid;
};
};
services = {
postgresql.package = pkgs.postgresql_16;
octodns = {
enable = true;
records."".MX = {
ttl = 86400;
values = [ { exchange = "${smtp.host}."; } ];
};
defaults.CNAME.ttl = 60;
};
hastebin = {
enable = true;
subdomain = "bin";
renderers =
with pkgs;
let
hl = rustPlatform.buildRustPackage {
name = "syntax-renderer";
src = inputs.syntax-renderer;
cargoHash = "sha256-kZy+HVPcUfPDTBQZ8TQ/xlEEqmSIttzdGeRwX9EF4xU=";
};
in
{
hl = "${hl}/bin/syntax-renderer";
sha = writeShellScript "sha-renderer" ''
echo "Content-Type: text/plain"
echo "---"
${coreutils}/bin/sha256sum - | cut -d' ' -f1
'';
stl = writeShellScript "stl-renderer" ''
echo "Content-Type: model/stl"
echo "Content-Disposition: attachment; filename=$(basename "$1" .scad).stl"
echo "---"
${openscad}/bin/openscad --export-format stl -o - -
'';
};
cleanup.enable = true;
};
readeck = {
enable = true;
subdomain = "read";
settings.email = {
host = smtp.host;
port = smtp.port;
username = smtp.username;
encryption = "starttls";
from = smtp.from;
from_noreply = smtp.from;
};
};
donetick = {
enable = true;
subdomain = "do";
settings = {
email = {
host = smtp.host;
port = smtp.port;
email = smtp.username;
};
};
};
grafana = {
enable = true;
subdomain = "graph";
settings = {
server.http_port = 3005;
smtp = {
enabled = true;
host = smtp.host;
port = smtp.port;
user = smtp.username;
from_address = smtp.from;
};
};
};
owncast = {
enable = true;
subdomain = "stream";
};
gtrackmap = {
enable = false;
subdomain = "trackmap";
port = 3001;
};
invidious = {
enable = true;
subdomain = "vid";
extraSettingsFile = secrets.invidious.path;
settings = {
invidious_companion = [
{ private_url = "http://apu:8282/companion"; }
];
};
};
syncthing = {
enable = true;
subdomain = "sync";
dataDir = syncthingDataDir;
configDir = "/var/lib/syncthing";
};
tailscale.enable = true;
gotosocial = {
enable = true;
subdomain = "social";
settings = {
port = 3002;
smtp-host = smtp.host;
smtp-port = smtp.port;
smtp-username = smtp.username;
smtp-from = smtp.from;
instance-languages = [
"de"
"fi"
"en"
];
};
};
vaultwarden = {
enable = true;
subdomain = "pw";
config = {
YUBICO_CLIENT_ID = 86799;
SMTP_HOST = smtp.host;
SMTP_FROM = smtp.from;
SMTP_FROM_NAME = "Vaultwarden";
SMTP_USERNAME = smtp.username;
SMTP_PORT = smtp.port;
HELO_NAME = smtp.heloName;
};
};
workout-tracker = {
enable = true;
subdomain = "fit";
port = 3004;
};
workout-sync = {
enable = true;
subdomain = "ws";
};
immich = {
enable = true;
subdomain = "img";
mediaLocation = immichDataDir;
timezone = "Europe/Helsinki";
settings.job = {
thumbnailGeneration.concurrency = 8;
videoConversion.concurrency = 2;
};
};
dnote = {
enable = true;
subdomain = "note";
environment = {
SmtpHost = smtp.host;
SmtpPort = smtp.port;
SmtpUsername = smtp.username;
};
environmentFile = secrets.dnote.path;
};
tailscaledAdguardhome = {
enable = true;
subdomain = "dns";
port = 3006;
};
mealie = {
enable = true;
package = pkgs-unstable.mealie;
subdomain = "cook";
credentialsFile = secrets.mealie.path;
settings = {
SMTP_HOST = smtp.host;
SMTP_FROM_EMAIL = smtp.from;
SMTP_USER = smtp.username;
SMTP_PORT = smtp.port;
};
};
uptime-kuma = {
enable = true;
subdomain = "status";
settings = {
PORT = "3007";
};
};
mosquitto = {
enable = true;
subdomain = "mqtt";
listeners = [
{
users = {
homie = {
acl = [
"readwrite homie/#"
];
hashedPasswordFile = secrets."mosquitto/homie".path;
};
};
port = 8084;
settings = {
protocol = "websockets";
cafile = "/run/credentials/mosquitto.service/fullchain.pem";
certfile = "/run/credentials/mosquitto.service/fullchain.pem";
keyfile = "/run/credentials/mosquitto.service/key.pem";
};
}
{
users = {
homie = {
acl = [
"readwrite homie/#"
];
hashedPasswordFile = secrets."mosquitto/homie".path;
};
telegraf = {
acl = [
"read openhab/#"
"read homie/#"
"read shellies/#"
"read mokkimaatti/#"
];
hashedPasswordFile = secrets."mosquitto/telegraf".path;
};
openhab = {
acl = [
"readwrite openhab/#"
];
hashedPasswordFile = secrets."mosquitto/openhab".path;
};
shelly = {
acl = [
"readwrite shellies/#"
];
hashedPasswordFile = secrets."mosquitto/shelly".path;
};
mokkimaatti = {
acl = [
"readwrite mokkimaatti/#"
];
hashedPasswordFile = secrets."mosquitto/mokkimaatti".path;
};
};
}
];
openFirewall = true;
};
gitlab-runner = {
enable = true;
services = {
default = {
dockerImage = "alpine";
authenticationTokenConfigFile = secrets."gitlab-runner/default".path;
};
docker = {
dockerImage = "docker:stable";
dockerVolumes = [ "/var/run/docker.sock:/var/run/docker.sock" ];
authenticationTokenConfigFile = secrets."gitlab-runner/docker".path;
};
};
};
weechat = {
enable = true;
subdomain = "irc";
};
sillytavern = {
enable = true;
subdomain = "st";
listen = true;
whitelist = false;
port = 3100;
};
nginx.virtualHosts."isarepomaa.com" = {
forceSSL = true;
enableACME = true;
http2 = true;
locations."/".root = "/var/www/isas-portfolio";
};
hledger-web = {
enable = true;
subdomain = "ledger";
stateDir = "${syncthingDataDir}/ledger";
user = config.systemd.services.syncthing.serviceConfig.User;
group = config.systemd.services.syncthing.serviceConfig.Group;
extraOptions = [ "--forecast" ];
journalFiles = [
"main.ldg"
];
};
actual = {
enable = true;
package = pkgs-unstable.actual-server;
subdomain = "actual";
environmentFile = secrets.actual.path;
settings = {
port = 3200;
openId = {
discoveryURL = "https://${config.services.voidauth.subdomain}.${config.networking.domain}/oidc/.well-known/openid-configuration";
server_hostname = "https://${config.services.actual.subdomain}.${config.networking.domain}";
};
loginMethod = "openid";
allowedLoginMethods = [ "openid" ];
enforceOpenId = true;
userCreationMode = "login";
};
};
voidauth = {
enable = true;
subdomain = "auth";
environmentFile = secrets.voidauth.path;
settings = {
APP_PORT = 3300;
SMTP_HOST = smtp.host;
SMTP_FROM = smtp.from;
SMTP_PORT = smtp.port;
SMTP_USER = smtp.username;
};
};
gitea = {
enable = true;
subdomain = "git";
secrets = secrets.gitea.path;
};
gitea-actions-runner.instances = {
default = {
enable = true;
name = config.networking.domain;
labels = [
"linux_arm64"
"ubuntu-latest:docker://node:latest"
"nixos-latest:docker://git.freun.dev/repomaa/nixos/node:latest"
];
tokenFile = secrets.gitea-actions-runner.path;
url = "https://${config.services.gitea.subdomain}.${config.networking.domain}";
settings.container.network = "bridge";
};
};
searx = {
enable = true;
subdomain = "q";
port = 3400;
environmentFile = secrets.searx.path;
settings = {
general = {
instance_name = "freun.dev SearXNG";
};
server = {
public_instance = true;
image_proxy = true;
method = "GET";
secret_key = "$SEARX_SECRET_KEY";
};
engines = lib.mapAttrsToList (name: value: { inherit name; } // value) {
"google".disabled = true;
"duckduckgo".disabled = false;
"duckduckgo images".disabled = false;
"wolframalpha".disabled = false;
};
search = {
formats = [
"html"
"json"
];
};
enabled_plugins = [
"Basic Calculator"
"Hash plugin"
"Open Access DOI rewrite"
"Hostnames plugin"
"Unit converter plugin"
"Tracker URL remover"
];
};
};
open-webui = {
enable = true;
port = 3500;
environmentFile = secrets.open-webui.path;
environment = {
ENABLE_WEB_SEARCH = "True";
ENABLE_OLLAMA_API = "False";
};
subdomain = "owu";
};
webserver = {
acme.dnsChallenge = true;
tailscaleAuth.expectedTailnet = "tempel-vibes.ts.net";
};
};
virtualisation.oci-containers.containers.open-terminal = {
image = "ghcr.io/open-webui/open-terminal:latest";
autoStart = true;
ports = [ "127.0.0.1:3700:8000" ];
environmentFiles = [ config.age.secrets."open-terminal-api-key".path ];
environment = {
OPEN_TERMINAL_MULTI_USER = "true";
};
volumes = [
"open-terminal-data:/home/user"
];
};
virtualisation.docker.autoPrune.enable = true;
}