2023-07-28 09:59:47 +07:00
|
|
|
{ config
|
|
|
|
, lib
|
|
|
|
, pkgs
|
|
|
|
, ... }:
|
|
|
|
|
|
|
|
let
|
|
|
|
cfg = config.server;
|
|
|
|
synapseMetricsPort = 8009;
|
|
|
|
synapseMetricsAddr = "127.0.0.1";
|
|
|
|
collectListeners = names:
|
|
|
|
map
|
|
|
|
(x: "127.0.0.1:${toString x.port}")
|
|
|
|
(builtins.attrValues
|
|
|
|
(lib.filterAttrs (k: v: builtins.elem k names && v.enable) config.services.prometheus.exporters));
|
|
|
|
in {
|
|
|
|
# a bunch of services for personal use not intended for the public
|
2023-08-28 00:46:51 +07:00
|
|
|
# TODO: keycloakify this
|
2023-07-28 09:59:47 +07:00
|
|
|
services.grafana = {
|
|
|
|
enable = true;
|
|
|
|
settings = {
|
|
|
|
"auth.basic".enabled = false;
|
|
|
|
# nginx login is used so this is fine, hopefully
|
|
|
|
"auth.anonymous" = {
|
|
|
|
enabled = true;
|
|
|
|
# org_role = "Admin";
|
|
|
|
};
|
|
|
|
server.root_url = "https://home.${cfg.domainName}/grafana/";
|
|
|
|
server.domain = "home.${cfg.domainName}";
|
|
|
|
server.http_addr = "127.0.0.1";
|
|
|
|
server.protocol = "socket";
|
|
|
|
security.admin_user = "chayleaf";
|
|
|
|
security.admin_password = "$__file{/secrets/grafana_password_file}";
|
|
|
|
security.secret_key = "$__file{/secrets/grafana_key_file}";
|
|
|
|
};
|
|
|
|
};
|
|
|
|
services.nginx.upstreams.grafana.servers."unix:/${config.services.grafana.settings.server.socket}" = {};
|
|
|
|
|
2023-08-28 00:46:51 +07:00
|
|
|
# TODO:
|
|
|
|
# services.keycloak.plugins = [ pkgs.keycloak.plugins.keycloak-metrics-spi ];
|
|
|
|
services.keycloak.settings.metrics-enabled = true;
|
|
|
|
|
2023-07-28 09:59:47 +07:00
|
|
|
services.nginx.virtualHosts."home.${cfg.domainName}" = {
|
|
|
|
quic = true;
|
|
|
|
enableACME = true;
|
|
|
|
forceSSL = true;
|
|
|
|
basicAuthFile = "/secrets/home_password";
|
|
|
|
extraConfig = ''
|
|
|
|
satisfy any;
|
|
|
|
${lib.optionalString (cfg.lanCidrV4 != "0.0.0.0/0") "allow ${cfg.lanCidrV4};"}
|
|
|
|
${lib.optionalString (cfg.lanCidrV6 != "::/0") "allow ${cfg.lanCidrV6};"}
|
|
|
|
deny all;
|
|
|
|
'';
|
|
|
|
# locations."/.well-known/acme-challenge".extraConfig = "auth_basic off;";
|
|
|
|
locations."/".root = "/var/www/home.${cfg.domainName}/";
|
2023-08-24 18:27:05 +07:00
|
|
|
locations."/scan/".proxyPass = "http://${lib.quoteListenAddr config.services.scanservjs.settings.host}:${toString config.services.scanservjs.settings.port}/";
|
2023-07-28 09:59:47 +07:00
|
|
|
locations."/grafana/" = {
|
|
|
|
proxyPass = "http://grafana/";
|
|
|
|
proxyWebsockets = true;
|
|
|
|
};
|
|
|
|
locations."/grafana/public/".alias = "${config.services.grafana.settings.server.static_root_path}/";
|
2023-07-28 12:02:37 +07:00
|
|
|
locations."/printer/" = {
|
|
|
|
proxyPass = "http://127.0.0.1:631/";
|
|
|
|
proxyWebsockets = true;
|
|
|
|
};
|
2023-07-28 09:59:47 +07:00
|
|
|
};
|
|
|
|
services.nginx.virtualHosts."hydra.${cfg.domainName}" = {
|
|
|
|
quic = true;
|
|
|
|
enableACME = true;
|
|
|
|
forceSSL = true;
|
|
|
|
basicAuthFile = "/secrets/home_password";
|
|
|
|
extraConfig = ''
|
|
|
|
satisfy any;
|
|
|
|
${lib.optionalString (cfg.lanCidrV4 != "0.0.0.0/0") "allow ${cfg.lanCidrV4};"}
|
|
|
|
${lib.optionalString (cfg.lanCidrV6 != "::/0") "allow ${cfg.lanCidrV6};"}
|
|
|
|
deny all;
|
2023-08-04 08:30:16 +07:00
|
|
|
proxy_read_timeout 300;
|
|
|
|
proxy_connect_timeout 300;
|
|
|
|
proxy_send_timeout 300;
|
2023-08-09 23:43:17 +07:00
|
|
|
client_body_timeout 300;
|
|
|
|
send_timeout 300;
|
2023-07-28 09:59:47 +07:00
|
|
|
'';
|
|
|
|
locations."/".proxyPass = "http://${lib.quoteListenAddr config.services.hydra.listenHost}:${toString config.services.hydra.port}/";
|
2023-08-09 23:43:17 +07:00
|
|
|
locations."/static/".root = lib.mkIf config.services.hydra.enable "${config.services.hydra.package}/libexec/hydra/root/";
|
2023-07-28 09:59:47 +07:00
|
|
|
};
|
|
|
|
users.users.nginx.extraGroups = [ "grafana" ];
|
|
|
|
|
2023-08-09 23:43:17 +07:00
|
|
|
services.harmonia = {
|
2023-08-04 08:30:16 +07:00
|
|
|
enable = true;
|
|
|
|
signKeyPath = "/secrets/cache-priv-key.pem";
|
|
|
|
settings.bind = "[::1]:5000";
|
2023-08-09 23:43:17 +07:00
|
|
|
};
|
2023-08-04 08:30:16 +07:00
|
|
|
nix.settings.allowed-users = [ "nix-serve" "harmonia" "hydra" "hydra-www" ];
|
2023-10-17 20:25:03 +07:00
|
|
|
# make sure only hydra has access to this file
|
|
|
|
# so normal nix evals don't have access to builtins
|
|
|
|
nix.settings.extra-builtins-file = "/etc/nixos/extra-builtins.nix";
|
2023-07-28 21:15:28 +07:00
|
|
|
impermanence.directories = [
|
2023-10-17 20:25:03 +07:00
|
|
|
{ directory = /etc/nixos; user = "hydra"; group = "hydra"; mode = "0700"; }
|
2023-07-28 21:15:28 +07:00
|
|
|
];
|
2023-07-28 13:19:43 +07:00
|
|
|
nix.settings.allowed-uris = [
|
2023-07-28 13:51:25 +07:00
|
|
|
# required for home-manager
|
2023-07-28 13:19:43 +07:00
|
|
|
"https://git.sr.ht/~rycee/nmd/"
|
2023-07-28 13:51:25 +07:00
|
|
|
# required for server (I suppose since nvfetcher uses fetchTarball here...)
|
|
|
|
"https://github.com/searxng/searxng/"
|
2023-07-28 21:15:28 +07:00
|
|
|
# required for home config (nvfetcher again)
|
2023-07-28 14:12:55 +07:00
|
|
|
"https://api.github.com/repos/FAForever/"
|
2023-10-18 18:47:35 +07:00
|
|
|
# for nginx CF-Connecting-IP config generation
|
2023-10-18 19:36:18 +07:00
|
|
|
"https://www.cloudflare.com/ips-v4"
|
|
|
|
"https://www.cloudflare.com/ips-v6"
|
2023-07-28 13:19:43 +07:00
|
|
|
];
|
2023-07-28 09:59:47 +07:00
|
|
|
services.nginx.virtualHosts."binarycache.${cfg.domainName}" = {
|
|
|
|
quic = true;
|
|
|
|
enableACME = true;
|
2023-08-04 08:30:16 +07:00
|
|
|
forceSSL = true;
|
2023-07-28 09:59:47 +07:00
|
|
|
basicAuthFile = "/secrets/home_password";
|
2023-08-09 23:43:17 +07:00
|
|
|
locations."/".proxyPass = "http://${config.services.harmonia.settings.bind or "[::1]:5000"}";
|
2023-08-04 08:30:16 +07:00
|
|
|
locations."/".extraConfig = ''
|
|
|
|
proxy_set_header Host $host;
|
|
|
|
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;
|
2023-08-09 23:43:17 +07:00
|
|
|
location ~ "^/nar/([a-z0-9]{32})-.*\.narinfo$" {
|
|
|
|
proxy_pass http://127.0.0.1:5000/$1.narinfo$is_args$args;
|
|
|
|
}
|
|
|
|
'';
|
2023-08-04 08:30:16 +07:00
|
|
|
# zstd on;
|
|
|
|
# zstd_types application/x-nix-archive;
|
2023-07-28 09:59:47 +07:00
|
|
|
};
|
|
|
|
|
|
|
|
services.hydra = {
|
2023-10-08 08:24:29 +07:00
|
|
|
enable = true;
|
2023-07-28 09:59:47 +07:00
|
|
|
hydraURL = "home.${cfg.domainName}/hydra";
|
|
|
|
listenHost = "127.0.0.1";
|
|
|
|
minimumDiskFree = 30;
|
|
|
|
notificationSender = "noreply@${cfg.domainName}";
|
|
|
|
# smtpHost = "mail.${cfg.domainName}";
|
|
|
|
useSubstitutes = true;
|
|
|
|
};
|
2023-10-18 21:03:32 +07:00
|
|
|
# boot.binfmt.emulatedSystems = builtins.filter (x: x != pkgs.system) [ "aarch64-linux" "x86_64-linux" ];
|
2023-07-28 12:02:37 +07:00
|
|
|
nix.buildMachines = [
|
|
|
|
{
|
2023-07-28 13:19:43 +07:00
|
|
|
# there were some bugs related to not specifying the machine
|
|
|
|
# not sure they're still there, but it surely won't hurt
|
2023-07-28 12:02:37 +07:00
|
|
|
hostName = "localhost";
|
|
|
|
protocol = null;
|
2023-07-28 13:19:43 +07:00
|
|
|
maxJobs = 8;
|
2023-10-18 21:03:32 +07:00
|
|
|
supportedFeatures = [ "benchmark" "big-parallel" "ca-derivations" "local" "kvm" "nixos-test" ];
|
|
|
|
systems = [ "builtin" pkgs.system ];
|
2023-07-28 12:02:37 +07:00
|
|
|
}
|
2023-10-18 19:34:55 +07:00
|
|
|
{
|
|
|
|
hostName = cfg.laptopHostname;
|
2023-10-18 21:03:32 +07:00
|
|
|
maxJobs = 2;
|
2023-10-18 21:14:46 +07:00
|
|
|
# TODO: switch to ssh-ng https://github.com/NixOS/hydra/issues/688
|
|
|
|
protocol = "ssh";
|
2023-10-18 19:34:55 +07:00
|
|
|
systems = [ "x86_64-linux" ];
|
2023-10-18 21:03:32 +07:00
|
|
|
supportedFeatures = [ "benchmark" "big-parallel" "ca-derivations" "kvm" "nixos-test" ];
|
2023-10-18 21:14:46 +07:00
|
|
|
# hydra-queue-runner must have read access to this
|
2023-10-18 19:34:55 +07:00
|
|
|
sshKey = "/secrets/hydra-builder-key";
|
|
|
|
sshUser = "hydra-builder";
|
2023-10-18 20:24:52 +07:00
|
|
|
publicHostKey = cfg.laptopPublicKey;
|
2023-10-18 19:34:55 +07:00
|
|
|
}
|
2023-07-28 12:02:37 +07:00
|
|
|
];
|
2023-10-18 21:03:32 +07:00
|
|
|
nix.distributedBuilds = true;
|
2023-07-28 12:02:37 +07:00
|
|
|
# limit CI CPU usage since I'm running everything else off this server too
|
2023-07-29 01:19:56 +07:00
|
|
|
systemd.services.nix-daemon.serviceConfig.CPUQuota = "100%";
|
|
|
|
nix.daemonCPUSchedPolicy = "idle";
|
|
|
|
nix.daemonIOSchedClass = "idle";
|
2023-08-09 23:43:17 +07:00
|
|
|
systemd.services.hydra-evaluator = lib.mkIf config.services.hydra.enable {
|
2023-10-18 18:35:41 +07:00
|
|
|
# https://github.com/NixOS/hydra/issues/1186
|
|
|
|
environment.GC_DONT_GC = "1";
|
2023-08-09 23:43:17 +07:00
|
|
|
serviceConfig.CPUQuota = "100%";
|
|
|
|
serviceConfig.CPUSchedulingPolicy = "idle";
|
|
|
|
serviceConfig.IOSchedulingClass = "idle";
|
|
|
|
};
|
2023-07-28 12:02:37 +07:00
|
|
|
programs.ccache.enable = true;
|
2023-07-28 09:59:47 +07:00
|
|
|
|
|
|
|
services.nginx.statusPage = true;
|
|
|
|
services.gitea.settings.metrics.ENABLED = true;
|
|
|
|
services.akkoma.config.":prometheus"."Pleroma.Web.Endpoint.MetricsExporter" = {
|
|
|
|
enabled = true;
|
|
|
|
auth = [ ((pkgs.formats.elixirConf { }).lib.mkRaw ":basic") "prometheus" {
|
|
|
|
_secret = "/secrets/akkoma/prometheus_password";
|
|
|
|
} ];
|
|
|
|
ip_whitelist = ["127.0.0.1"];
|
|
|
|
path = "/api/pleroma/app_metrics";
|
|
|
|
format = (pkgs.formats.elixirConf { }).lib.mkRaw ":text";
|
|
|
|
};
|
|
|
|
services.prometheus = {
|
|
|
|
enable = true;
|
|
|
|
exporters = {
|
|
|
|
node = {
|
|
|
|
enable = true;
|
|
|
|
enabledCollectors = [ "logind" "systemd" ];
|
2023-07-28 21:56:34 +07:00
|
|
|
listenAddress = "127.0.0.1";
|
2023-07-28 09:59:47 +07:00
|
|
|
port = 9101; # cups is 9100
|
|
|
|
};
|
|
|
|
dovecot = {
|
|
|
|
enable = true;
|
|
|
|
scopes = [ "user" "global" ];
|
2023-07-28 21:56:34 +07:00
|
|
|
listenAddress = "127.0.0.1";
|
2023-07-28 09:59:47 +07:00
|
|
|
};
|
|
|
|
nextcloud = {
|
|
|
|
enable = true;
|
|
|
|
url = "https://cloud.${cfg.domainName}";
|
|
|
|
username = "nextcloud-exporter";
|
|
|
|
passwordFile = "/secrets/nextcloud_exporter_password";
|
2023-07-28 21:56:34 +07:00
|
|
|
listenAddress = "127.0.0.1";
|
|
|
|
};
|
|
|
|
nginx = {
|
|
|
|
enable = true;
|
|
|
|
listenAddress = "127.0.0.1";
|
2023-07-28 09:59:47 +07:00
|
|
|
};
|
|
|
|
nginxlog = {
|
|
|
|
enable = true;
|
|
|
|
group = "nginx";
|
|
|
|
settings.namespaces = [
|
|
|
|
{
|
|
|
|
name = "comments";
|
|
|
|
format = "{\"ip\":\"$remote_addr\",\"time\":\"$time_iso8601\",\"referer\":\"$http_referer\",\"body\":\"$request_body\",\"ua\":\"$http_user_agent\"}";
|
|
|
|
source.files = [ "/var/log/nginx/comments.log" ];
|
|
|
|
}
|
|
|
|
];
|
2023-07-28 21:56:34 +07:00
|
|
|
listenAddress = "127.0.0.1";
|
|
|
|
};
|
|
|
|
postfix = {
|
|
|
|
enable = true;
|
|
|
|
listenAddress = "127.0.0.1";
|
|
|
|
};
|
|
|
|
postgres = {
|
|
|
|
enable = true;
|
|
|
|
listenAddress = "127.0.0.1";
|
|
|
|
};
|
|
|
|
process = {
|
|
|
|
enable = true;
|
|
|
|
listenAddress = "127.0.0.1";
|
|
|
|
};
|
|
|
|
redis = {
|
|
|
|
enable = true;
|
|
|
|
listenAddress = "127.0.0.1";
|
|
|
|
};
|
|
|
|
rspamd = {
|
|
|
|
enable = true;
|
|
|
|
listenAddress = "127.0.0.1";
|
|
|
|
};
|
|
|
|
smartctl = {
|
|
|
|
enable = true;
|
|
|
|
listenAddress = "127.0.0.1";
|
2023-07-28 09:59:47 +07:00
|
|
|
};
|
|
|
|
};
|
|
|
|
checkConfig = "syntax-only";
|
|
|
|
scrapeConfigs = [
|
|
|
|
{
|
|
|
|
job_name = "local_frequent";
|
|
|
|
scrape_interval = "1m";
|
|
|
|
static_configs = [ {
|
|
|
|
targets = collectListeners [
|
|
|
|
"node"
|
|
|
|
"nginx"
|
|
|
|
"process"
|
|
|
|
];
|
|
|
|
labels.machine = "server";
|
|
|
|
} ];
|
|
|
|
}
|
|
|
|
{
|
|
|
|
job_name = "local_medium_freq";
|
|
|
|
scrape_interval = "15m";
|
|
|
|
static_configs = [ {
|
2023-07-28 12:02:37 +07:00
|
|
|
targets = [ "127.0.0.1:9548" "127.0.0.1:9198" ];
|
2023-07-28 09:59:47 +07:00
|
|
|
labels.machine = "server";
|
|
|
|
} ];
|
|
|
|
}
|
|
|
|
{
|
|
|
|
job_name = "local_infrequent";
|
|
|
|
scrape_interval = "1h";
|
|
|
|
static_configs = [ {
|
|
|
|
targets = collectListeners [
|
|
|
|
"dovecot"
|
|
|
|
"nextcloud"
|
|
|
|
"nginxlog"
|
|
|
|
"postfix"
|
|
|
|
"postgres"
|
|
|
|
"redis"
|
|
|
|
"rspamd"
|
|
|
|
"smartctl"
|
|
|
|
];
|
|
|
|
labels.machine = "server";
|
|
|
|
} ];
|
|
|
|
}
|
|
|
|
{
|
|
|
|
job_name = "gitea";
|
|
|
|
bearer_token_file = "/secrets/prometheus_bearer";
|
|
|
|
scrape_interval = "1h";
|
|
|
|
static_configs = [ {
|
|
|
|
targets = [ "git.${cfg.domainName}" ];
|
|
|
|
labels.machine = "server";
|
|
|
|
} ];
|
|
|
|
}
|
|
|
|
{
|
|
|
|
job_name = "router_frequent";
|
|
|
|
scrape_interval = "1m";
|
|
|
|
static_configs = [ {
|
|
|
|
targets = [
|
|
|
|
"retracker.local:9101"
|
|
|
|
"retracker.local:9256"
|
|
|
|
"retracker.local:9167"
|
|
|
|
];
|
|
|
|
labels.machine = "router";
|
|
|
|
} ];
|
|
|
|
}
|
|
|
|
{
|
|
|
|
job_name = "router_infrequent";
|
|
|
|
scrape_interval = "10m";
|
|
|
|
static_configs = [ {
|
|
|
|
targets = [
|
|
|
|
"retracker.local:9430"
|
|
|
|
"retracker.local:9547"
|
|
|
|
];
|
|
|
|
labels.machine = "router";
|
|
|
|
} ];
|
|
|
|
}
|
|
|
|
{
|
|
|
|
job_name = "synapse";
|
|
|
|
metrics_path = "/_synapse/metrics";
|
|
|
|
scrape_interval = "15s";
|
|
|
|
static_configs = [ {
|
|
|
|
targets = [ "${lib.quoteListenAddr synapseMetricsAddr}:${toString synapseMetricsPort}" ];
|
|
|
|
labels.machine = "server";
|
|
|
|
} ];
|
|
|
|
}
|
|
|
|
{
|
|
|
|
job_name = "akkoma";
|
|
|
|
metrics_path = "/api/pleroma/app_metrics";
|
|
|
|
scrape_interval = "10m";
|
|
|
|
basic_auth.username = "prometheus";
|
|
|
|
basic_auth.password_file = "/secrets/akkoma/prometheus_password";
|
|
|
|
static_configs = [ {
|
|
|
|
targets = [ "pleroma.${cfg.domainName}" ];
|
|
|
|
labels.machine = "server";
|
|
|
|
} ];
|
|
|
|
}
|
|
|
|
];
|
|
|
|
};
|
|
|
|
services.matrix-synapse.settings = {
|
|
|
|
enable_metrics = true;
|
|
|
|
federation_metrics_domains = [ "matrix.org" ];
|
|
|
|
/*
|
|
|
|
normally you're supposed to use
|
|
|
|
- port: 9000
|
|
|
|
type: metrics
|
|
|
|
bind_addresses: ['::1', '127.0.0.1']
|
|
|
|
|
|
|
|
but the NixOS module doesn't allow creating such a listener
|
|
|
|
*/
|
|
|
|
listeners = [ {
|
|
|
|
port = synapseMetricsPort;
|
|
|
|
bind_addresses = [ synapseMetricsAddr ];
|
|
|
|
type = "metrics";
|
|
|
|
tls = false;
|
|
|
|
resources = [ ];
|
|
|
|
} ];
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
# this uses elasticsearch, rip
|
|
|
|
services.parsedmarc = {
|
|
|
|
enable = true;
|
|
|
|
provision = {
|
|
|
|
localMail = {
|
|
|
|
enable = true;
|
|
|
|
hostname = cfg.domainName;
|
|
|
|
};
|
|
|
|
grafana = {
|
|
|
|
datasource = true;
|
|
|
|
dashboard = true;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};*/
|
|
|
|
|
2023-07-28 12:02:37 +07:00
|
|
|
networking.firewall.allowedTCPPorts = [ 631 ];
|
2023-07-28 09:59:47 +07:00
|
|
|
services.printing = {
|
|
|
|
enable = true;
|
|
|
|
allowFrom = [ cfg.lanCidrV4 cfg.lanCidrV6 ];
|
|
|
|
browsing = true;
|
|
|
|
clientConf = ''
|
|
|
|
ServerName home.${cfg.domainName}
|
|
|
|
'';
|
2023-07-28 12:02:37 +07:00
|
|
|
listenAddresses = [ "*:631" ];
|
2023-07-28 09:59:47 +07:00
|
|
|
defaultShared = true;
|
|
|
|
drivers = [ pkgs.hplip ];
|
|
|
|
startWhenNeeded = false;
|
|
|
|
};
|
|
|
|
services.avahi = {
|
|
|
|
enable = true;
|
|
|
|
hostName = "home";
|
|
|
|
publish.enable = true;
|
|
|
|
publish.addresses = true;
|
|
|
|
publish.userServices = true;
|
|
|
|
};
|
2023-08-24 18:27:05 +07:00
|
|
|
hardware.sane = {
|
|
|
|
enable = true;
|
|
|
|
extraBackends = with pkgs; [ hplipWithPlugin ];
|
|
|
|
};
|
|
|
|
nixpkgs.config.allowUnfreePredicate = pkg: lib.getName pkg == "hplip";
|
|
|
|
services.scanservjs.enable = true;
|
|
|
|
services.scanservjs.settings.host = "127.0.0.1";
|
|
|
|
services.scanservjs.settings.port = 3952;
|
2023-07-28 09:59:47 +07:00
|
|
|
}
|