diff --git a/common/default.nix b/common/default.nix index b1db7cf..79ffd5b 100644 --- a/common/default.nix +++ b/common/default.nix @@ -2,5 +2,6 @@ imports = [ ./caddy.nix ./cloudflare.nix + ./garage.nix ]; } diff --git a/common/garage.nix b/common/garage.nix new file mode 100644 index 0000000..98c5a19 --- /dev/null +++ b/common/garage.nix @@ -0,0 +1,105 @@ +{ + config, + pkgs, + ... +}: let + port_admin = 3460; + port_s3_api = 3461; + port_web = 3462; + port_k2v = 3463; + port_rpc = 3464; + domain_s3_api = "s3.garage.local"; + domain_web = "web.garage.local"; + + cfg = config.services.garage; +in { + services.garage = { + enable = true; + package = pkgs.garage_2; + settings = { + compression_level = 8; + replication_factor = 1; + + db_engine = "sqlite"; + metadata_fsync = true; + data_fsync = true; + data_dir = [ + { + capacity = "500G"; + path = "/var/lib/garage/data"; + } + { + capacity = "500G"; + path = "/hard/var/lib/garage/data"; + } + ]; + + admin = { + api_bind_addr = "[::]:${toString port_admin}"; + admin_token_file = config.sops.secrets."garage/admin_token".path; + metrics_token_file = config.sops.secrets."garage/metrics_token".path; + }; + + s3_api = { + s3_region = "garage"; + api_bind_addr = "[::]:${toString port_s3_api}"; + root_domain = ".${domain_s3_api}"; + }; + + s3_web = { + index = "index.html"; + bind_addr = "[::]:${toString port_web}"; + root_domain = ".${domain_web}"; + }; + + k2v_api = { + api_bind_addr = "[::]:${toString port_k2v}"; + }; + + rpc_bind_addr = "[::]:${toString port_rpc}"; + rpc_public_addr = "127.0.0.1:${toString port_rpc}"; + rpc_secret_file = config.sops.secrets."garage/rpc_secret".path; + }; + }; + + systemd.services.garage.serviceConfig = { + User = "garage"; + Group = "garage"; + }; + users = { + users.garage = { + isSystemUser = true; + group = "garage"; + packages = [ + (pkgs.symlinkJoin { + name = "awscli"; + paths = [pkgs.awscli2]; + buildInputs = [pkgs.makeWrapper]; + postBuild = '' + wrapProgram "$out/bin/aws" \ + --set-default 'AWS_ACCESS_KEY_ID' "$(cat ${config.sops.secrets."garage/admin_key".path})" \ + --set-default 'AWS_SECRET_ACCESS_KEY' "$(cat ${config.sops.secrets."garage/admin_secret".path})" \ + --set-default 'AWS_DEFAULT_REGION' '${config.services.garage.settings.s3_api.s3_region}' \ + --set-default 'AWS_ENDPOINT_URL' "http://localhost:${toString port_s3_api}" + ''; + }) + ]; + }; + groups.garage = {}; + }; + + services.caddy.virtualHosts = { + "${domain_s3_api}".extraConfig = '' + reverse_proxy http://localhost:${toString port_s3_api} + tls internal + ''; + "${domain_web}".extraConfig = '' + reverse_proxy http://localhost:${toString port_web} + tls internal + ''; + "*.${domain_web}".extraConfig = '' + reverse_proxy http://localhost:${toString port_web} + tls internal + ''; + }; +} diff --git a/secrets.nix b/secrets.nix index 59f6cc8..3846b80 100644 --- a/secrets.nix +++ b/secrets.nix @@ -36,6 +36,22 @@ with lib; { owner = config.services.anubis.instances."forgejo".user; }; + "garage/admin_key" = mkIf config.services.garage.enable { + owner = config.systemd.services.garage.serviceConfig.User; + }; + "garage/admin_secret" = mkIf config.services.garage.enable { + owner = config.systemd.services.garage.serviceConfig.User; + }; + "garage/admin_token" = mkIf config.services.garage.enable { + owner = config.systemd.services.garage.serviceConfig.User; + }; + "garage/metrics_token" = mkIf config.services.garage.enable { + owner = config.systemd.services.garage.serviceConfig.User; + }; + "garage/rpc_secret" = mkIf config.services.garage.enable { + owner = config.systemd.services.garage.serviceConfig.User; + }; + "guz/password" = { owner = config.users.users."guz".name; }; diff --git a/secrets.yaml b/secrets.yaml index 7c3782c..30e4dac 100644 --- a/secrets.yaml +++ b/secrets.yaml @@ -1,12 +1,5 @@ cloudflared: tunnel-env: ENC[AES256_GCM,data:jYtDMez3w5BzSH3/xwqEsAtPo6EMxx6dBcd3bnfdCOm/eZzampXPyUfPsqkO4mtL2dGmjT7W+3prGxrEQtC/Eu9R7ojCflbJBFyH8+BDusomQdqjr5d0Utur/oK7ElKgpl0OF17n8sOngxEXZBtWHTbKoL+v50QzHEO07hPHjhrF5n/P+0I78rXPn9OEvJ1B5u0dg3XxXg3l4rtmkYdSwu+2+cUh6pe0AWNTigkkwy70hwKKaz+5Lb5mAp1mpl4r7xaCUqvP,iv:PVmrMzTq2upZXgu5fHPQMis0cXNipMbXahevF1/zJSU=,tag:F75o8plR7XMAv1ngL65ntQ==,type:str] -guz: - password: ENC[AES256_GCM,data:zlO5xSFho7TXjFv62lgFir9SAgn+UE6XjdNEvIAgmQG9oDkthfgxO84wYdI0mQDwRIIs2PmSdBRfo0DPc3hji+ySCrItolPL8g==,iv:MZfhTxwfcbmXh5C6DkQhnY9NQGdE8zEwwvFOHQiUgKY=,tag:JjJN2bYcSXNN3ueGj5RNLg==,type:str] -keiko: - env-file: ENC[AES256_GCM,data:up0VMFlG92ZAmnDk1b3DNrGJ9zUoyu3pi5poP1cgaYMAaVotRtrQkDAWLPdMKrRaXZlMFhmR0Vmy4n5wauZwiUN6nhMQOEkLZ5QOa8wiyA93JTmu0982bvMeZ+dk1HTy7nU1UI1OaejjEoGFlFV5g06qGfXnC1CFHyqwM1WeTgI6Syv431q0wutz2J6lcDvyxOU8zem3zSOpf5fg,iv:hxixIs/OoUS8Cntr7yJXZxeo5PpyPGfQLfDROQ07mr4=,tag:YUgrrP/C0ZY/SIs/wszW/w==,type:str] -network: - ip: ENC[AES256_GCM,data:AkbNOQLXRKLYjU2ywg==,iv:xqdTPCUYiT/cPe2zAbBJ7fUiEMViW9LZND4j0DdydLY=,tag:tq6nA5fGH4/mAvF6InUFgQ==,type:str] - localIp: ENC[AES256_GCM,data:PK8THL9NW//2sal1,iv:9h3f255rIgedYToVaUGuQ9RzD33V8sczRWsZe+rTyC0=,tag:OoJbes6k0FqxXzGQ8ZG0aA==,type:str] forgejo: git-password: ENC[AES256_GCM,data:SDyFBCwTxnZ1E6R/8HZCBIBj4AREYfqWrgzSEQ6SA3BDGPFsHghiVmF+Jt4omdzUQSoCCblMBsAx0NQBbBJrCbEoBWtybRM7Cg==,iv:KbtjXW1F8YJeapVpEkf8AdXhojmhOQKxG8nCZv7vW4k=,tag:odrL53KeKLVD5AoQB14veA==,type:str] user1: @@ -15,14 +8,20 @@ forgejo: email: ENC[AES256_GCM,data:e6GOwBzRBxa00CHYHgV8,iv:oerF3kJWzjzOatND8Tngp3MADw2kaBKyigeFxtH/ypQ=,tag:1q093JG9hRDxs6OzOIU3vw==,type:str] anubis: hexFile: ENC[AES256_GCM,data:6hMIQUiSYYNkhrGGHHHIF6Ur+dQeXDuUTHZR4Tnl3O/T/phC7q881Gta6LCUJVvgQJ8hF2aKafggTUDsjcaI3g==,iv:3aGmqM8gV5YsdFNGCgZ4L9t8r9c0zubqZOE1eDBAong=,tag:/nB357mXDJJMRNoQ4E/KQQ==,type:str] +garage: + admin_key: ENC[AES256_GCM,data:ORtjXzJrbWITofjNpVsTHE1gHcwNhBcbMNM=,iv:99XCuu5hGa3ZnAqbOsmgjeMouC8EnTzsJ0HuOoHwKEE=,tag:eJVx+A8MJ4g1xXr2F5hTkg==,type:str] + admin_secret: ENC[AES256_GCM,data:7hMOXJwIr0pkCFBBh5vnDy//R9UwD+eTlddT1VGOpqYaA0andf0jRfGOr0efcX0x/EvlDOrfFqn8ME8icZRRbw==,iv:KGxqXhzNWFWiwBHRSP+aov2fCNHgFuUtpBF4nd40mGw=,tag:ixcehvjzs6CfVyAAl315dw==,type:str] + admin_token: ENC[AES256_GCM,data:hUwUTLJAOWZnh3vPdPuCfkFaqg5AeJ+drsDjOQypAvWOyddxBKmA5+7JQP0=,iv:iIB/U047lgLIIpeAckiuUZqnGFvi0Hgnke2nWGUhq1s=,tag:ms1T9SvfwNW6amqfsje0Vg==,type:str] + metrics_token: ENC[AES256_GCM,data:GOoxrzN5CKcKDVOmlDrKS5GcHRTezO3Qh0ewUYntYKXa+/XOomitNbYDu7M=,iv:32lcFmv4k9bFEg3aUCKJIDYOr2XUIC293DBW3QsVaDI=,tag:kW32nwBDcdMg/wdCq8P5Kw==,type:str] + rpc_secret: ENC[AES256_GCM,data:tONGXbC6y1X05a6wiWJ5VG0GYsfCGeqMJsH2IcxZtj7XKqymUcexYjhsbyOJ1Ljo2Re2bBdbtLJb6fsKBASUPQ==,iv:fDYWQ5IUVkQTLs9sB0Wfe1EGTbT7aF4LxGAE9deUkfE=,tag:bKrM3a4VihuptoppG4aaug==,type:str] +guz: + password: ENC[AES256_GCM,data:zlO5xSFho7TXjFv62lgFir9SAgn+UE6XjdNEvIAgmQG9oDkthfgxO84wYdI0mQDwRIIs2PmSdBRfo0DPc3hji+ySCrItolPL8g==,iv:MZfhTxwfcbmXh5C6DkQhnY9NQGdE8zEwwvFOHQiUgKY=,tag:JjJN2bYcSXNN3ueGj5RNLg==,type:str] +keiko: + env-file: ENC[AES256_GCM,data:up0VMFlG92ZAmnDk1b3DNrGJ9zUoyu3pi5poP1cgaYMAaVotRtrQkDAWLPdMKrRaXZlMFhmR0Vmy4n5wauZwiUN6nhMQOEkLZ5QOa8wiyA93JTmu0982bvMeZ+dk1HTy7nU1UI1OaejjEoGFlFV5g06qGfXnC1CFHyqwM1WeTgI6Syv431q0wutz2J6lcDvyxOU8zem3zSOpf5fg,iv:hxixIs/OoUS8Cntr7yJXZxeo5PpyPGfQLfDROQ07mr4=,tag:YUgrrP/C0ZY/SIs/wszW/w==,type:str] medama: anubis: hexFile: ENC[AES256_GCM,data:INM0j8uPSV60nEyGJ2/+nH1IDVL08hvBzTULBHPbChQVdYO+Z/UCI1aKCLoCwad0NAp+rAljYotZ0NxlxfjnmQ==,iv:y9F70r7erFOBe94rvv3/3P+N8SwFgW39hRcfP2SjFMA=,tag:PnjbQcCDbB/8XPJc+hM5dA==,type:str] sops: - kms: [] - gcp_kms: [] - azure_kv: [] - hc_vault: [] age: - recipient: age1sseqwwa7fc0ftry8njyuagdg28fkmtdwmj6m7p3etjsj83suee3shfzjyz enc: | @@ -33,8 +32,7 @@ sops: amRmVkVoS2RqeEs3OXZVeTlsZUVEV28K1WcbGJHT8LMah5b7NN1psiucTl1OfZYO 4T3RDSQMB3qj1TGQSdixjwRRKbMGtL3LXnvkNd+caVi5Z9OkF1O9Yg== -----END AGE ENCRYPTED FILE----- - lastmodified: "2025-04-05T16:54:29Z" - mac: ENC[AES256_GCM,data:Kl2iN6R3C3WcRgDTG71Ev1KEeDlO+/y1Jck8f6q10zbB5SxXk73wmDtxOSM+Loqan2WVVyd1cYc0Lk6PiA5hMaC1svt5tIuvGlW8G2tXZgZAXdBMuYTYlWkq4ti977KNy4PwbfmWHemWQDdH4io/4oX3G6ZONKhNfOuP6ooRCd4=,iv:goYEGnDjFEGr9Dx564vTvfJN8tnmER6LX2nkG7RqG80=,tag:v2ur4o5zhvQ0ksK7xOhzLw==,type:str] - pgp: [] + lastmodified: "2025-09-16T19:15:12Z" + mac: ENC[AES256_GCM,data:MhCHZ9QyaA6KlMmienux8Ceznew40vIEw+dACUJ8ewBXB3oGCDQI4dTPEAZH1C4NgVEJZOWUItv6mt8D/WbreoxuGuIkIOOSAeySuM6rUpy+aguTAMcVij9tqgqhoUMovq43YulOzt5pBirWzNtAOsfP6gQMVTjZAi9kiPmJJS0=,iv:6TzDpqPQ55juqjKT3Tlvo2fUd4xguvN8buoGA6oggmE=,tag:LFYv1edoFSmvZupvj3zzFA==,type:str] unencrypted_suffix: _unencrypted - version: 3.9.4 + version: 3.10.2