Skip to content

feat: self-host Attic binary cache on glyph - #355

Merged
stackptr merged 3 commits into
mainfrom
feat/attic-cache
Mar 10, 2026
Merged

stackptr merged 3 commits into
mainfrom
feat/attic-cache

Conversation

@stackptr

@stackptr stackptr commented Mar 10, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Add Attic binary cache server on glyph, replacing Cachix
  • Expose cache publicly at cache.zx.dev via reverse proxy on spore
  • CI pushes build artifacts to Attic; local builds pull from the cache

Changes

File What
flake.nix Add attic input, cache.zx.dev substituter, signing public key
lib/hosts.nix Wire atticd NixOS module into host builder
lib/secrets/glyph.nix Register attic-credentials.age secret
hosts/glyph/services/attic.nix atticd service (port 8199, SQLite, chunked dedup, 30-day GC)
hosts/glyph/services/default.nix Import attic module, add DB to backup paths
hosts/spore/services/web/default.nix cache.zx.dev nginx virtualHost (client_max_body_size 0)
.github/workflows/ci.yml Replace cachix-action with attic login/use/push

Deployment steps

1. Create the agenix secret

# Generate JWT signing key
openssl rand -base64 48

# Encrypt as agenix secret (content: ATTIC_SERVER_TOKEN_HS256_SECRET_BASE64=<key>)
agenix -e hosts/glyph/secrets/attic-credentials.age

2. Deploy glyph and spore

just switch glyph
nixos-rebuild switch --flake .#spore --target-host root@spore --build-host localhost

3. Bootstrap the cache (on glyph)

# Create admin token and log in
attic login local http://localhost:8199 \
  $(sudo atticd-atticadm make-token \
    --sub "admin" \
    --validity "10y" \
    --push "*" --pull "*" --create-cache "*" --delete "*" \
    --configure-cache "*" --configure-cache-retention "*")

# Create the cache and generate signing keypair
attic cache create main
attic cache configure main --regenerate-keypair
attic cache configure main --public

# Verify the public key matches what's in flake.nix
attic cache info main

# Generate CI push token
sudo atticd-atticadm make-token \
  --sub "ci" \
  --validity "2y" \
  --push "main" --pull "main"

4. Configure GitHub secret

Add the CI token output as ATTIC_TOKEN in repo Settings > Secrets > Actions.

Verification

After merging and CI completes a build on main:

# Check if a derivation is in the cache
nix path-info --store https://cache.zx.dev .#nixosConfigurations.glyph.config.system.build.toplevel

# Watch for cache hits during a local build
nix build .#nixosConfigurations.glyph.config.system.build.toplevel -v 2>&1 \
  | grep "copying path.*from 'https://cache.zx.dev'"

Cachix cleanup (after verification)

Once Attic is confirmed working:

  • Remove CACHIX_AUTH_TOKEN GitHub repository secret
  • Remove stackptr.cachix.org from extra-substituters and extra-trusted-public-keys in flake.nix
  • Remove pkgs.cachix from devShell in flake.nix

🤖 Generated with Claude Code

@stackptr
stackptr enabled auto-merge (squash) March 10, 2026 21:44
stackptr and others added 3 commits March 10, 2026 15:01
Add atticd service on glyph (port 8199) with SQLite backend, chunked
deduplication, and 30-day garbage collection. Expose via cache.zx.dev
reverse proxy on spore. Replace Cachix with Attic in CI workflow.

- hosts/glyph/services/attic.nix: atticd service config
- hosts/spore/services/web: cache.zx.dev nginx virtualHost
- .github/workflows/ci.yml: attic login/use/push replaces cachix-action
- flake.nix: attic input + cache.zx.dev substituter
- lib/hosts.nix: wire atticd NixOS module into host builder
- lib/secrets/glyph.nix: register attic-credentials secret

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add the Attic cache signing key (main:sbkS1Xz6P4g66iyttRGj/...) to
extra-trusted-public-keys so local builds trust artifacts from
cache.zx.dev.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@stackptr
stackptr merged commit b11cbdc into main Mar 10, 2026
4 checks passed
This was referenced Mar 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant