Builds that outlive the internet.
Apocache exists because a deployment should not fail just because somebody else’s registry, Git host, or package archive is having a bad day — or has disappeared entirely.
Why it was made
Designed by Warky Devs, Apocache was initially made as a backup tool: a way to keep the dependencies and source inputs needed to recover a project. It grew into a reproducibility tool because a dependency cache is useful, but not enough to rebuild a release years later. Packages get unpublished, registries go away, repositories are force-pushed, signing keys expire, and networks become unavailable. Apocache captures the external inputs a project actually relied on at a particular revision, verifies them, and stores them by content digest.
Use cases
When the apocalypse happens
Use the immutable snapshot already stored here. Apocache can restore it to caches or files, or serve its pinned Go, npm, and Cargo dependencies directly. The build uses the preserved inputs, not whatever upstream happens to provide today.
How it works
- Snapshot and verify a repository’s packages, metadata, and source dependencies.
- Store artifacts once in content-addressed, deduplicated storage.
- Restore or serve the named snapshot whenever you need a reproducible build.
apocache remote add tank https://apocache.example.com --token-env APOCACHE_TOKEN
apocache push my-project@latest
Examples
Set up a vault and register the npm upstream:
apocache init /tank/apocache
export APOCACHE_VAULT=/tank/apocache
apocache registry add npmjs https://registry.npmjs.org --ecosystem npm
Add a local working tree:
apocache repo add storefront --path ~/code/storefront
apocache snapshot storefront
apocache tag release-2.4.0 storefront@latest -m "2.4.0 release"
Or add a repository from Git:
apocache repo add storefront ssh://git@example.com/team/storefront.git --ref main
apocache snapshot storefront --ref v2.4.0
apocache verify storefront@latest --deep
Apocache detects supported dependency inputs from the registered repository, including go.mod, npm lockfiles, and Cargo.lock.
Rebuild a Go project with no upstream network access:
apocache restore my-project --snapshot release-2.4.0 --mode cache --output /tmp/gomodcache
GOMODCACHE=/tmp/gomodcache GOPROXY=off GOSUMDB=off go build ./...
Serve a pinned npm snapshot to CI:
npm ci --registry=https://apocache.example.com/r/my-project/release-2.4.0/npm/
Serve a snapshot locally for npm, Go, and Cargo:
apocache serve --snapshot release-2.4.0
npm ci --registry=http://127.0.0.1:4873
GOPROXY=http://127.0.0.1:4874 GOSUMDB=off go build ./...
CARGO_REGISTRIES_APOCACHE_INDEX=sparse+http://127.0.0.1:4875/ cargo build --offline
Keep a portable backup for another site:
apocache bundle my-project --snapshot release-2.4.0 --output my-project-release-2.4.0.apoc --compress-level 19
Docker Compose
Run one apocached container per vault. Keep the vault on host storage, not in the container layer or an anonymous volume. This example is for a server behind a TLS-terminating reverse proxy; keep metrics private.
services:
apocached:
image: git.warky.dev/wdevs/apocached:v0.1.0@sha256:replace-with-release-digest
restart: unless-stopped
user: "65532:65532"
environment:
APOCACHE_VAULT: /vault
APOCACHE_SERVER_BIND: 0.0.0.0:8080
APOCACHE_SERVER_METRICS_BIND: 0.0.0.0:9090
APOCACHE_SERVER_TLS_MODE: proxy
volumes:
- /srv/tank/apocache:/vault
ports:
- "8080:8080"
- "127.0.0.1:9090:9090"
read_only: true
tmpfs:
- /tmp
Initialize the host directory once before starting the service, and ensure its owner can be written by container uid 65532:
apocache init /srv/tank/apocache
docker compose up -d