diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 20dabe71..4c9c188e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,15 +29,19 @@ jobs: - uses: cachix/install-nix-action@v31 with: github_access_token: ${{ secrets.GITHUB_TOKEN }} - - uses: cachix/cachix-action@v16 - with: - name: stackptr - authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} + - name: Configure Attic cache + run: | + nix profile install github:zhaofengli/attic#attic-client + attic login rc https://cache.zx.dev ${{ secrets.ATTIC_TOKEN }} + attic use rc:main - run: nix flake check - - name: Build NixOS system + - name: Build system configuration run: | if [ "${{ matrix.system }}" = "aarch64-darwin" ]; then nix build .#darwinConfigurations.${{ matrix.host }}.system else nix build .#nixosConfigurations.${{ matrix.host }}.config.system.build.toplevel fi + - name: Push to Attic + if: github.ref == 'refs/heads/main' + run: attic push rc:main ./result diff --git a/flake.lock b/flake.lock index 7368de6c..791b7cbe 100644 --- a/flake.lock +++ b/flake.lock @@ -45,6 +45,31 @@ "type": "github" } }, + "attic": { + "inputs": { + "crane": "crane", + "flake-compat": "flake-compat", + "flake-parts": "flake-parts", + "nix-github-actions": "nix-github-actions", + "nixpkgs": [ + "nixpkgs" + ], + "nixpkgs-stable": "nixpkgs-stable" + }, + "locked": { + "lastModified": 1758711588, + "narHash": "sha256-0nZlCCDC5PfndsQJXXtcyrtrfW49I3KadGMDlutzaGU=", + "owner": "zhaofengli", + "repo": "attic", + "rev": "12cbeca141f46e1ade76728bce8adc447f2166c6", + "type": "github" + }, + "original": { + "owner": "zhaofengli", + "repo": "attic", + "type": "github" + } + }, "brew-src": { "flake": false, "locked": { @@ -62,6 +87,21 @@ "type": "github" } }, + "crane": { + "locked": { + "lastModified": 1751562746, + "narHash": "sha256-smpugNIkmDeicNz301Ll1bD7nFOty97T79m4GUMUczA=", + "owner": "ipetkov", + "repo": "crane", + "rev": "aed2020fd3dc26e1e857d4107a5a67a33ab6c1fd", + "type": "github" + }, + "original": { + "owner": "ipetkov", + "repo": "crane", + "type": "github" + } + }, "disko": { "inputs": { "nixpkgs": [ @@ -83,6 +123,22 @@ } }, "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1747046372, + "narHash": "sha256-CIVLLkVgvHYbgI2UpXvIIBJ12HWgX+fjA8Xf8PUmqCY=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "9100a0f413b0c601e0533d1d94ffd501ce2e7885", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-compat_2": { "flake": false, "locked": { "lastModified": 1767039857, @@ -99,6 +155,27 @@ } }, "flake-parts": { + "inputs": { + "nixpkgs-lib": [ + "attic", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1751413152, + "narHash": "sha256-Tyw1RjYEsp5scoigs1384gIg6e0GoBVjms4aXFfRssQ=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "77826244401ea9de6e3bac47c2db46005e1f30b5", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-parts_2": { "inputs": { "nixpkgs-lib": [ "nixpkgs" @@ -120,7 +197,7 @@ }, "git-hooks-nix": { "inputs": { - "flake-compat": "flake-compat", + "flake-compat": "flake-compat_2", "gitignore": "gitignore", "nixpkgs": [ "nixpkgs" @@ -273,6 +350,27 @@ "type": "github" } }, + "nix-github-actions": { + "inputs": { + "nixpkgs": [ + "attic", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1737420293, + "narHash": "sha256-F1G5ifvqTpJq7fdkT34e/Jy9VCyzd5XfJ9TO8fHhJWE=", + "owner": "nix-community", + "repo": "nix-github-actions", + "rev": "f4158fa080ef4503c8f4c820967d946c2af31ec9", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nix-github-actions", + "type": "github" + } + }, "nix-homebrew": { "inputs": { "brew-src": "brew-src" @@ -343,6 +441,22 @@ } }, "nixpkgs-stable": { + "locked": { + "lastModified": 1751741127, + "narHash": "sha256-t75Shs76NgxjZSgvvZZ9qOmz5zuBE8buUaYD28BMTxg=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "29e290002bfff26af1db6f64d070698019460302", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-25.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-stable_2": { "locked": { "lastModified": 1772822230, "narHash": "sha256-yf3iYLGbGVlIthlQIk5/4/EQDZNNEmuqKZkQssMljuw=", @@ -361,8 +475,9 @@ "root": { "inputs": { "agenix": "agenix", + "attic": "attic", "disko": "disko", - "flake-parts": "flake-parts", + "flake-parts": "flake-parts_2", "git-hooks-nix": "git-hooks-nix", "golink": "golink", "home-manager": "home-manager", @@ -374,7 +489,7 @@ "nix-index-database": "nix-index-database", "nixos-hardware": "nixos-hardware", "nixpkgs": "nixpkgs", - "nixpkgs-stable": "nixpkgs-stable", + "nixpkgs-stable": "nixpkgs-stable_2", "systems": "systems", "zx-dev": "zx-dev" } diff --git a/flake.nix b/flake.nix index 2b49ddb7..d90c6220 100644 --- a/flake.nix +++ b/flake.nix @@ -43,6 +43,10 @@ inputs.nixpkgs.follows = "nixpkgs"; inputs.systems.follows = "systems"; }; + attic = { + url = "github:zhaofengli/attic"; + inputs.nixpkgs.follows = "nixpkgs"; + }; zx-dev = { url = "github:stackptr/zx.dev"; inputs.nixpkgs.follows = "nixpkgs"; @@ -115,9 +119,11 @@ nixConfig = { experimental-features = ["nix-command" "flakes"]; extra-substituters = [ + "https://cache.zx.dev" "https://stackptr.cachix.org" ]; extra-trusted-public-keys = [ + "main:sbkS1Xz6P4g66iyttRGj/o8aPODE6bVG9oKT98/ULKI=" "stackptr.cachix.org-1:5e2q7OxdRdAtvRmHTeogpgJKzQhbvFqNMmCMw71opZA=" ]; }; diff --git a/hosts/glyph/secrets/attic-credentials.age b/hosts/glyph/secrets/attic-credentials.age new file mode 100644 index 00000000..7d240764 Binary files /dev/null and b/hosts/glyph/secrets/attic-credentials.age differ diff --git a/hosts/glyph/services/attic.nix b/hosts/glyph/services/attic.nix new file mode 100644 index 00000000..19e2d1ae --- /dev/null +++ b/hosts/glyph/services/attic.nix @@ -0,0 +1,36 @@ +{config, ...}: { + age.secrets.attic-credentials = { + file = ./../secrets/attic-credentials.age; + mode = "440"; + owner = "atticd"; + group = "atticd"; + }; + + services.atticd = { + enable = true; + environmentFile = config.age.secrets.attic-credentials.path; + + settings = { + listen = "[::]:8199"; + + database.url = "sqlite:///var/lib/atticd/server.db?mode=rwc"; + + storage = { + type = "local"; + path = "/var/lib/atticd/storage"; + }; + + chunking = { + nar-size-threshold = 65536; + min-size = 16384; + avg-size = 65536; + max-size = 262144; + }; + + garbage-collection = { + interval = "12 hours"; + default-retention-period = "30 days"; + }; + }; + }; +} diff --git a/hosts/glyph/services/default.nix b/hosts/glyph/services/default.nix index 4dc145b3..be23d643 100644 --- a/hosts/glyph/services/default.nix +++ b/hosts/glyph/services/default.nix @@ -4,6 +4,7 @@ ... }: { imports = [ + ./attic.nix ./avahi.nix ./dns.nix ./filebrowser.nix @@ -84,6 +85,7 @@ rc.backup = { enable = true; paths = [ + "/var/lib/atticd/server.db" "/var/lib/basic-memory" "/var/lib/open-webui" "/var/lib/roon-server/backup" diff --git a/hosts/spore/services/web/default.nix b/hosts/spore/services/web/default.nix index 87b2d997..66952981 100644 --- a/hosts/spore/services/web/default.nix +++ b/hosts/spore/services/web/default.nix @@ -86,6 +86,17 @@ proxyWebsockets = true; }; }; + "cache.zx.dev" = { + forceSSL = true; + useACMEHost = "zx.dev"; + locations."/" = { + proxyPass = "http://glyph.rove-duck.ts.net:8199"; + extraConfig = '' + client_max_body_size 0; + proxy_read_timeout 300; + ''; + }; + }; "jellyfin.zx.dev" = { forceSSL = true; useACMEHost = "zx.dev"; diff --git a/lib/hosts.nix b/lib/hosts.nix index 2d37a484..68407e57 100644 --- a/lib/hosts.nix +++ b/lib/hosts.nix @@ -11,6 +11,7 @@ inputs @ { llm-profile, nix-index-database, zx-dev, + attic, disko, golink, ... @@ -76,6 +77,7 @@ inputs @ { { nixpkgs.overlays = overlays; } + attic.nixosModules.atticd golink.nixosModules.default zx-dev.nixosModules.default ]; diff --git a/lib/secrets/glyph.nix b/lib/secrets/glyph.nix index c9b2dc6a..f45bd768 100644 --- a/lib/secrets/glyph.nix +++ b/lib/secrets/glyph.nix @@ -8,4 +8,5 @@ in { "hosts/glyph/secrets/context7-api-key.age".publicKeys = keys; "hosts/glyph/secrets/open-webui-env.age".publicKeys = keys; "hosts/glyph/secrets/graphite-auth-token.age".publicKeys = keys; + "hosts/glyph/secrets/attic-credentials.age".publicKeys = keys; }