Repository navigation
feat(docker): prototype shared Bun global store for independent SVForge apps #604
Copy link
Copy link
Closed as not planned
Closed as not planned
Copy link
Description
Goal
Allow independent Dockerized Bun/SVForge applications on one host to reuse physical package files at runtime, not only in build caches, with no predeclared monolithic dependency image. Package versions and transitive resolution combinations must remain isolated and deterministic.
Bun's opt-in Global Virtual Store is available starting in Bun 1.3.14 (not 1.3.13).
Architecture
- One common persistent Docker volume mounted at the same path in all installers and runtimes, e.g.
/bun-storewithBUN_INSTALL_CACHE_DIR=/bun-store,BUN_INSTALL_GLOBAL_STORE=1. - One distinct
node_modulesvolume per application, containing links, not shared as a writable folder across services. - Per-app installer job with
bun install --frozen-lockfile --production --linker isolatedafter dependency changes, writing to shared store and its own module volume. - Application runtime mounts shared store and its module volume read-only; its immutable app image contains built code and startup/migration assets. Continue with multistage Dockerfiles for app builds.
- Preserve optionality: no mandatory Docker volumes for SVForge's lightweight
basescaffold.
Proof obtained (2026-10-14)
Working prototype committed in experiments/shared-bun-store/:
- Two separate Bun applications, common
zod,clsx,tailwind-merge; different per-app packagesnanoidanddate-fns. - Both resolve zod@4.3.5 to exactly
/bun-store/links/zod@4.3.5-8bd7a35048fcdaac/node_modules/zod. - Shared store 48 MiB; per-app
node_moduleslink trees 16 KiB and 12 KiB (small-fixture numbers; not projected production savings). - Isolated Docker Compose smoke passes on Atlas and Nova, including HTTP requests, independent package imports, read-only shared runtime store, and no published host ports.
- Tests remove only their own uniquely named temporary Compose resources. No Nova production services were changed.
- Prior Docker layer inventory script discarded: it did not measure actual disk savings and is unnecessary for this approach.
Remaining work (do not claim production-ready)
- Convert one actual SVForge SvelteKit/adapter-node app to an immutable multistage image (build output without bundled production
node_modules) and an explicit installer job that uses the shared store. - Verify migrations, native modules and lifecycle/trusted packages, non-root permissions, readiness, rollback, coherent updates to lockfile/modules volume.
- Benchmark actual host disk usage and build times against the current app image, accounting for existing Docker layer sharing and Bun cache hardlinks. Include a second real consumer before globalizing.
- Decide whether and how to expose this as an opt-in production Compose recipe from SVForge without changing its local PostgreSQL setup (feat(dashboard): automatic local .env + Better Auth secret and Docker PostgreSQL setup #589).
- No production migration, publish, or merge before CI and review.
Acceptance criteria
- Real package files shared between two independent Docker containers.
- Identical global symlink target and working app HTTP tests, on Atlas and Nova.
- Project-local module trees and safe temporary smoke cleanup.
- Real SvelteKit application with multistage immutable build and separate installer.
- Disk/time comparison on real apps, native/migration tests, rollback validation.
- Reviewed choice of integration with SVForge and downstream deployment tools.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Activity
LudoLoops commentedon Oct 14, 2026
Initial read-only measurement on Nova (three Bun web images): 1569.8 MiB / 13 layers, 1130.8 MiB / 16 layers, 1071.5 MiB / 13 layers. Across this selected set there are 42 distinct layer digests and 0 shared layer digests. Images may still share layers with other host images. The first benchmarking script and three unit tests are committed as 8ce51c0 on
604-benchmark-shared-docker-layers(pushed); no PR opened because release PR #592 is already open. No Docker builds or production configuration changes have been made; measurable saved bytes require controlled before/after builds.[-]feat(docker): benchmark reusable SVForge image layers for SvelteKit projects[/-][+]feat(docker): prototype shared Bun global store for independent SVForge apps[/+]feat(docker): prove shared Bun store across app containers (#604)