mirror of
https://github.com/Swarsel/.dotfiles.git
synced 2026-04-14 13:19:09 +02:00
feat[server]: add hydra
This commit is contained in:
parent
669a512cdf
commit
52cc78a848
21 changed files with 652 additions and 164 deletions
|
|
@ -483,7 +483,7 @@ in
|
|||
};
|
||||
|
||||
Service = {
|
||||
ExecStart = "${pkgs._1password-gui}/bin/1password";
|
||||
ExecStart = "${pkgs._1password-gui-beta}/bin/1password";
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ in
|
|||
}
|
||||
];
|
||||
};
|
||||
|
||||
programs.ssh = {
|
||||
knownHosts = {
|
||||
nixbuild = {
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ in
|
|||
_1password.enable = true;
|
||||
_1password-gui = {
|
||||
enable = true;
|
||||
package = pkgs._1password-gui-beta;
|
||||
polkitPolicyOwners = [ "${mainUser}" ];
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{ lib, config, globals, dns, confLib, ... }:
|
||||
{ lib, config, pkgs, globals, dns, confLib, ... }:
|
||||
let
|
||||
inherit (confLib.gen { name = "attic"; port = 8091; }) serviceName serviceDir servicePort serviceAddress serviceDomain serviceProxy proxyAddress4 proxyAddress6;
|
||||
inherit (config.swarselsystems) mainUser isPublic sopsFile;
|
||||
|
|
@ -36,8 +36,33 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ servicePort ];
|
||||
|
||||
services.atticd = {
|
||||
enable = true;
|
||||
# NOTE: remove once https://github.com/zhaofengli/attic/pull/268 is merged
|
||||
package = pkgs.attic-server.overrideAttrs
|
||||
(oldAttrs: {
|
||||
patches = (oldAttrs.patches or [ ]) ++ [
|
||||
(pkgs.writeText "remove-s3-checksums.patch" ''
|
||||
diff --git a/server/src/storage/s3.rs b/server/src/storage/s3.rs
|
||||
index 1d5719f3..036f3263 100644
|
||||
--- a/server/src/storage/s3.rs
|
||||
+++ b/server/src/storage/s3.rs
|
||||
@@ -278,10 +278,6 @@ impl StorageBackend for S3Backend {
|
||||
CompletedPart::builder()
|
||||
.set_e_tag(part.e_tag().map(str::to_string))
|
||||
.set_part_number(Some(part_number as i32))
|
||||
- .set_checksum_crc32(part.checksum_crc32().map(str::to_string))
|
||||
- .set_checksum_crc32_c(part.checksum_crc32_c().map(str::to_string))
|
||||
- .set_checksum_sha1(part.checksum_sha1().map(str::to_string))
|
||||
- .set_checksum_sha256(part.checksum_sha256().map(str::to_string))
|
||||
.build()
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
'')
|
||||
];
|
||||
});
|
||||
environmentFile = config.sops.templates."attic.env".path;
|
||||
settings = {
|
||||
listen = "[::]:${builtins.toString servicePort}";
|
||||
|
|
@ -59,12 +84,10 @@ in
|
|||
bucket = serviceName;
|
||||
# attic must be patched to never serve pre-signed s3 urls directly
|
||||
# otherwise it will redirect clients to this localhost endpoint
|
||||
endpoint = "http://127.0.0.1:3900";
|
||||
endpoint = "http://127.0.0.1:3900"; # garage port
|
||||
} else {
|
||||
type = "local";
|
||||
path = serviceDir;
|
||||
# attic must be patched to never serve pre-signed s3 urls directly
|
||||
# otherwise it will redirect clients to this localhost endpoint
|
||||
};
|
||||
|
||||
garbage-collection = {
|
||||
|
|
@ -73,11 +96,11 @@ in
|
|||
};
|
||||
|
||||
chunking = {
|
||||
nar-size-threshold = if config.swarselmodules.server.garage then 0 else 64 * 1024; # 64 KiB
|
||||
nar-size-threshold = if config.swarselmodules.server.garage then 0 else 64 * 1024; # garage using s3
|
||||
|
||||
min-size = 16 * 1024; # 16 KiB
|
||||
avg-size = 64 * 1024; # 64 KiB
|
||||
max-size = 256 * 1024; # 256 KiBize = 262144;
|
||||
min-size = 16 * 1024;
|
||||
avg-size = 64 * 1024;
|
||||
max-size = 256 * 1024;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
@ -109,7 +132,7 @@ in
|
|||
};
|
||||
virtualHosts = {
|
||||
"${serviceDomain}" = {
|
||||
enableACME = true;
|
||||
useACMEHost = globals.domains.main;
|
||||
forceSSL = true;
|
||||
acmeRoot = null;
|
||||
oauth2.enable = false;
|
||||
|
|
@ -118,6 +141,11 @@ in
|
|||
proxyPass = "http://${serviceName}";
|
||||
extraConfig = ''
|
||||
client_max_body_size 0;
|
||||
client_body_timeout 600s;
|
||||
proxy_connect_timeout 600s;
|
||||
proxy_send_timeout 600s;
|
||||
proxy_read_timeout 600s;
|
||||
proxy_request_buffering off;
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{ self, lib, config, pkgs, dns, globals, confLib, ... }:
|
||||
let
|
||||
inherit (confLib.gen { name = "croc"; }) serviceName serviceDomain proxyAddress4 proxyAddress6;
|
||||
inherit (confLib.gen { name = "croc"; proxy = config.node.name; }) serviceName serviceDomain proxyAddress4 proxyAddress6;
|
||||
servicePorts = [
|
||||
9009
|
||||
9010
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@ let
|
|||
garageAdminPort = 3903;
|
||||
garageK2VPort = 3904;
|
||||
|
||||
adminDomain = "${subDomain}admin.${baseDomain}";
|
||||
webDomain = "${subDomain}web.${baseDomain}";
|
||||
adminDomain = "${subDomain}-admin.${baseDomain}";
|
||||
webDomain = "${subDomain}-web.${baseDomain}";
|
||||
in
|
||||
{
|
||||
options = {
|
||||
|
|
@ -71,12 +71,14 @@ in
|
|||
}
|
||||
];
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ servicePort 3901 3902 3903 3904 ];
|
||||
|
||||
nodes.stoicclub.swarselsystems.server.dns.${baseDomain}.subdomainRecords = {
|
||||
"${subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
|
||||
"${subDomain}admin" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
|
||||
"${subDomain}web" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
|
||||
"${subDomain}-admin" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
|
||||
"${subDomain}-web" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
|
||||
"*.${subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
|
||||
"*.${subDomain}web" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
|
||||
"*.${subDomain}-web" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
|
||||
};
|
||||
|
||||
sops = {
|
||||
|
|
@ -307,10 +309,6 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
security.acme.certs."${webDomain}" = {
|
||||
domain = "*.${webDomain}";
|
||||
};
|
||||
|
||||
nodes.${serviceProxy}.services.nginx = {
|
||||
upstreams = {
|
||||
${serviceName} = {
|
||||
|
|
@ -331,7 +329,7 @@ in
|
|||
};
|
||||
virtualHosts = {
|
||||
"${adminDomain}" = {
|
||||
enableACME = true;
|
||||
useACMEHost = globals.domains.main;
|
||||
forceSSL = true;
|
||||
acmeRoot = null;
|
||||
oauth2.enable = false;
|
||||
|
|
@ -342,7 +340,7 @@ in
|
|||
};
|
||||
};
|
||||
"*.${webDomain}" = {
|
||||
useACMEHost = webDomain;
|
||||
useACMEHost = globals.domains.main;
|
||||
forceSSL = true;
|
||||
acmeRoot = null;
|
||||
oauth2.enable = false;
|
||||
|
|
@ -354,7 +352,7 @@ in
|
|||
};
|
||||
"${serviceDomain}" = {
|
||||
serverAliases = [ "*.${serviceDomain}" ];
|
||||
enableACME = true;
|
||||
useACMEHost = globals.domains.main;
|
||||
forceSSL = true;
|
||||
acmeRoot = null;
|
||||
oauth2.enable = false;
|
||||
|
|
@ -363,6 +361,11 @@ in
|
|||
proxyPass = "http://${serviceName}";
|
||||
extraConfig = ''
|
||||
client_max_body_size 0;
|
||||
client_body_timeout 600s;
|
||||
proxy_connect_timeout 600s;
|
||||
proxy_send_timeout 600s;
|
||||
proxy_read_timeout 600s;
|
||||
proxy_request_buffering off;
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
|
|
|||
133
modules/nixos/server/hydra.nix
Normal file
133
modules/nixos/server/hydra.nix
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
{ inputs, lib, config, globals, dns, confLib, ... }:
|
||||
let
|
||||
inherit (confLib.gen { name = "hydra"; port = 8002; }) serviceName servicePort serviceUser serviceGroup serviceAddress serviceDomain serviceProxy proxyAddress4 proxyAddress6;
|
||||
inherit (config.swarselsystems) sopsFile;
|
||||
in
|
||||
{
|
||||
options = {
|
||||
swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
|
||||
};
|
||||
config = lib.mkIf config.swarselmodules.server.${serviceName} {
|
||||
|
||||
nodes.stoicclub.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
|
||||
"${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
|
||||
};
|
||||
|
||||
globals.services.${serviceName} = {
|
||||
domain = serviceDomain;
|
||||
inherit proxyAddress4 proxyAddress6;
|
||||
};
|
||||
|
||||
sops = {
|
||||
secrets = {
|
||||
nixbuild-net-key = { mode = "0600"; };
|
||||
hydra-pw = { inherit sopsFile; owner = serviceUser; group = serviceGroup; mode = "0440"; };
|
||||
};
|
||||
templates = {
|
||||
"hydra-env" = {
|
||||
content = ''
|
||||
HYDRA_PW="${config.sops.placeholder.hydra-pw}"
|
||||
'';
|
||||
owner = serviceUser;
|
||||
group = serviceGroup;
|
||||
mode = "0440";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.hydra = {
|
||||
enable = true;
|
||||
package = inputs.hydra.packages.${config.node.arch}.hydra;
|
||||
port = servicePort;
|
||||
hydraURL = "https://${serviceDomain}";
|
||||
listenHost = "*";
|
||||
notificationSender = "hydra@${globals.domains.main}";
|
||||
minimumDiskFreeEvaluator = 20; # 20G
|
||||
minimumDiskFree = 20; # 20G
|
||||
useSubstitutes = true;
|
||||
smtpHost = globals.services.mailserver.domain;
|
||||
buildMachinesFiles = [
|
||||
"/etc/nix/machines"
|
||||
];
|
||||
extraConfig = ''
|
||||
using_frontend_proxy 1
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.services.hydra-user-setup = {
|
||||
description = "Create admin user for Hydra";
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
User = "hydra";
|
||||
EnvironmentFile = [
|
||||
config.sops.templates.hydra-env.path
|
||||
];
|
||||
};
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
requires = [ "hydra-init.service" ];
|
||||
after = [ "hydra-init.service" ];
|
||||
environment = lib.mkForce config.systemd.services.hydra-init.environment;
|
||||
script = ''
|
||||
set -eu
|
||||
if [ ! -e ~hydra/.user-setup-done ]; then
|
||||
/run/current-system/sw/bin/hydra-create-user admin --full-name 'admin' --email-address 'admin@${globals.domains.main}' --password "$HYDRA_PW" --role admin
|
||||
touch ~hydra/.user-setup-done
|
||||
fi
|
||||
'';
|
||||
};
|
||||
|
||||
environment.persistence."/persist".directories = lib.mkIf config.swarselsystems.isImpermanence [
|
||||
];
|
||||
|
||||
nix = {
|
||||
settings.builders-use-substitutes = true;
|
||||
distributedBuilds = true;
|
||||
buildMachines = [
|
||||
{
|
||||
hostName = "localhost";
|
||||
protocol = null;
|
||||
system = config.node.arch;
|
||||
supportedFeatures = [ "kvm" "nixos-test" "big-parallel" "benchmark" ];
|
||||
maxJobs = 4;
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ servicePort ];
|
||||
|
||||
programs.ssh = {
|
||||
extraConfig = ''
|
||||
StrictHostKeyChecking no
|
||||
'';
|
||||
};
|
||||
|
||||
nodes.${serviceProxy}.services.nginx = {
|
||||
upstreams = {
|
||||
${serviceName} = {
|
||||
servers = {
|
||||
"${serviceAddress}:${builtins.toString servicePort}" = { };
|
||||
};
|
||||
};
|
||||
};
|
||||
virtualHosts = {
|
||||
"${serviceDomain}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
acmeRoot = null;
|
||||
oauth2.enable = false;
|
||||
locations = {
|
||||
"/" = {
|
||||
proxyPass = "http://${serviceName}";
|
||||
extraConfig = ''
|
||||
client_max_body_size 0;
|
||||
proxy_set_header X-Request-Base /hydra;
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
let
|
||||
inherit (config.swarselsystems) sopsFile;
|
||||
inherit (confLib.gen { name = "mailserver"; dir = "/var/lib/dovecot"; user = "virtualMail"; group = "virtualMail"; port = 443; }) serviceName serviceDir servicePort serviceUser serviceGroup serviceDomain serviceProxy proxyAddress4 proxyAddress6;
|
||||
inherit (config.repo.secrets.local.mailserver) user1 alias1_1 alias1_2 alias1_3 alias1_4 user2 alias2_1 user3;
|
||||
inherit (config.repo.secrets.local.mailserver) user1 alias1_1 alias1_2 alias1_3 alias1_4 user2 alias2_1 alias2_2 user3;
|
||||
baseDomain = globals.domains.main;
|
||||
in
|
||||
{
|
||||
|
|
@ -31,7 +31,7 @@ in
|
|||
{ directory = "/var/sieve"; user = serviceUser; group = serviceGroup; mode = "0770"; }
|
||||
{ directory = "/var/dkim"; user = "rspamd"; group = "rspamd"; mode = "0700"; }
|
||||
{ directory = serviceDir; user = serviceUser; group = serviceGroup; mode = "0700"; }
|
||||
{ directory = "/var/lib/postgresql"; user = "postgres"; group = "postgres"; mode = "0750"; }
|
||||
# { directory = "/var/lib/postgresql"; user = "postgres"; group = "postgres"; mode = "0750"; }
|
||||
{ directory = "/var/lib/rspamd"; user = "rspamd"; group = "rspamd"; mode = "0700"; }
|
||||
{ directory = "/var/lib/roundcube"; user = "roundcube"; group = "roundcube"; mode = "0700"; }
|
||||
{ directory = "/var/lib/redis-rspamd"; user = "redis-rspamd"; group = "redis-rspamd"; mode = "0700"; }
|
||||
|
|
@ -63,6 +63,7 @@ in
|
|||
hashedPasswordFile = config.sops.secrets.user2-hashed-pw.path;
|
||||
aliases = [
|
||||
"${alias2_1}@${baseDomain}"
|
||||
"${alias2_2}@${baseDomain}"
|
||||
];
|
||||
sendOnly = true;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{ lib, config, pkgs, globals, dns, confLib, ... }:
|
||||
let
|
||||
inherit (confLib.gen { name = "minecraft"; port = 25565; dir = "/opt/minecraft"; }) serviceName servicePort serviceDir serviceDomain proxyAddress4 proxyAddress6;
|
||||
inherit (confLib.gen { name = "minecraft"; port = 25565; dir = "/opt/minecraft"; proxy = config.node.name; }) serviceName servicePort serviceDir serviceDomain proxyAddress4 proxyAddress6;
|
||||
inherit (config.swarselsystems) mainUser;
|
||||
worldName = "${mainUser}craft";
|
||||
in
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ with dns.lib.combinators; {
|
|||
SOA = {
|
||||
nameServer = "soa";
|
||||
adminEmail = "admin@${globals.domains.main}"; # this option is not parsed as domain (we cannot just write "admin")
|
||||
serial = 2025120501; # update this on changes for secondary dns
|
||||
serial = 2025120506; # update this on changes for secondary dns
|
||||
};
|
||||
|
||||
useOrigin = false;
|
||||
|
|
|
|||
|
|
@ -31,5 +31,13 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
services.openssh = {
|
||||
settings = {
|
||||
AllowUsers = [
|
||||
"builder"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ in
|
|||
PresharedKeyFile = config.sops.secrets."wireguard-${serverName}-${config.node.name}-presharedKey".path;
|
||||
Endpoint = "server.${serverName}.${globals.domains.main}:${toString servicePort}";
|
||||
# Access to the whole network is routed through our entry node.
|
||||
# PersistentKeepalive = 25;
|
||||
PersistentKeepalive = 25;
|
||||
AllowedIPs =
|
||||
let
|
||||
wgNetwork = globals.networks."${serverNetConfigPrefix}-wg";
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue