feat: atticd to S3

This commit is contained in:
2026-06-05 12:42:55 +00:00
parent a30d1a93dd
commit 341e3a0e1c
4 changed files with 49 additions and 37 deletions
+32 -26
View File
@@ -1,11 +1,9 @@
{ ... }: { { ... }: {
pkgs,
lib, lib,
config, config,
... ...
}: let }: let
cfg = config.hectic.services.attic; cfg = config.hectic.services.attic;
environmentFile = "/var/lib/atticd/credentials.env";
in { in {
options.hectic.services.attic = { options.hectic.services.attic = {
enable = lib.mkEnableOption "Attic binary cache server"; enable = lib.mkEnableOption "Attic binary cache server";
@@ -27,40 +25,48 @@ in {
description = "Local port atticd binds to behind the reverse proxy."; description = "Local port atticd binds to behind the reverse proxy.";
}; };
}; environmentFile = lib.mkOption {
type = lib.types.path;
config = lib.mkIf cfg.enable { description = ''
systemd.services.atticd-credentials = { SOPS-backed environment file containing Attic JWT and object-storage
description = "Generate persistent atticd credentials"; credentials.
before = [ "atticd.service" ];
wantedBy = [ "atticd.service" ];
serviceConfig = {
Type = "oneshot";
StateDirectory = "atticd";
UMask = "0077";
};
script = ''
if [ -s ${environmentFile} ]; then
exit 0
fi
install -m 0700 -d /var/lib/atticd
secret="$(${lib.getExe pkgs.openssl} genrsa -traditional 4096 | ${pkgs.coreutils}/bin/base64 -w0)"
cat > ${environmentFile} <<EOF
ATTIC_SERVER_TOKEN_RS256_SECRET_BASE64="$secret"
EOF
chmod 0600 ${environmentFile}
''; '';
}; };
storage = {
bucket = lib.mkOption {
type = lib.types.str;
description = "Hetzner Object Storage bucket name used by Attic.";
};
endpoint = lib.mkOption {
type = lib.types.str;
description = "S3-compatible HTTPS endpoint for Hetzner Object Storage.";
};
region = lib.mkOption {
type = lib.types.str;
description = "Region name for Hetzner Object Storage.";
};
};
};
config = lib.mkIf cfg.enable {
services.atticd = { services.atticd = {
enable = true; enable = true;
environmentFile = environmentFile; environmentFile = cfg.environmentFile;
settings = { settings = {
listen = "${cfg.listenAddress}:${toString cfg.port}"; listen = "${cfg.listenAddress}:${toString cfg.port}";
allowed-hosts = [ cfg.hostName ]; allowed-hosts = [ cfg.hostName ];
api-endpoint = "https://${cfg.hostName}/"; api-endpoint = "https://${cfg.hostName}/";
compression.type = "zstd"; compression.type = "zstd";
storage = {
type = "s3";
bucket = cfg.storage.bucket;
endpoint = cfg.storage.endpoint;
region = cfg.storage.region;
};
}; };
}; };
}; };
+10 -1
View File
@@ -1,10 +1,19 @@
{ {
domain, domain,
... ...
}: { ... }: { }: {
config,
...
}: {
hectic.services.attic = { hectic.services.attic = {
enable = true; enable = true;
hostName = "cache.${domain}"; hostName = "cache.${domain}";
environmentFile = config.sops.secrets."atticd/environment".path;
storage = {
bucket = "cache-hectic-lab";
endpoint = "https://hel1.your-objectstorage.com";
region = "hel1";
};
}; };
services.nginx.virtualHosts."cache.${domain}" = { services.nginx.virtualHosts."cache.${domain}" = {
+1
View File
@@ -117,6 +117,7 @@ in {
"init-postgresql" = { "init-postgresql" = {
key = "init-postgresql"; key = "init-postgresql";
}; };
"atticd/environment" = {};
"ssl/porkbun/${domain}/domain.cert.pem" = { "ssl/porkbun/${domain}/domain.cert.pem" = {
group = "nginx"; group = "nginx";
mode = "0440"; mode = "0440";
+4 -8
View File
File diff suppressed because one or more lines are too long