Add varlock flatten command for monorepo Docker builds#930
Conversation
Collapses the @import graph into a self-contained directory: external imports are mirrored under .env-imports/ by workspace-relative path and @import paths are rewritten. Local env files are skipped by default, conditionally-enabled imports are still copied, npm plugins in copied files get version-pinned, and local-path plugins are vendored.
|
The changes in this PR will be included in the next version bump.
|
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
varlock-website | 7afe476 | Commit Preview URL Branch Preview URL |
Jul 24 2026, 04:27 PM |
commit: |
|
Hey Wizards, got round to getting this tested in my setup, and got some feedback... Firstly I think this is a great clutch tool, off the bat its a winner 🔥 I tried One real gap that was noticed was the pinned-plugin-version auto-install doesn't work in a shell-less image. which leads me to my next question: is pre-resolving/pre-installing plugins at Perhaps under "Plugins in containers": "varlock's auto-install needs a shell to spawn into in distroless, shell-less base images this will pose a significant hurdle. If you're on one of those, pre-install plugins in a stage that has a shell ( Otherwise I really do appreciate the effort and labour or love you lot do with this awesome project. 💚 |
|
seeing the past two commits, you guys are awesome💚🔥 |
|
couldn't do it without you @aFuzzyBear !! |
Copies each npm @plugin() package into the output (.env-plugins/) and rewrites declarations to local paths, so the flattened dir resolves with no runtime install. Prefers the copy already in node_modules; downloads only plugins not installed locally.
971ecbf to
6394a07
Compare
…ed rule flatten now warns when a copied local package plugin declares runtime dependencies (they won't travel with the copy), mirroring the npm-vendor check. Documents that local plugins must be self-contained in the plugins guide.


What
New
varlock flattencommand that collapses a package's@importgraph into one self-contained directory (default.env-flat/), so the package can be deployed without the rest of the monorepo present, most commonly in the final stage of a Docker build.How it works
.env-imports/by workspace-relative path, and@importpaths are rewritten. Because both the package's own files and the imports preserve their directory structure, relative imports between copied files stay valid, and the output is position-independent.enabled=) are still copied with their conditions preserved, since production may enable imports the build machine does not..env.local/.env.*.localfiles are skipped by default (opt back in with--include-local) so machine-local secrets stay out of image layers.@plugin()declarations in copied external files get pinned to the currently installed version, letting the standalone binary auto-install them where the sibling'snode_modulesis gone. Local-path plugins are vendored into the output. Package-internal plugin declarations are left untouched.Plugins in shell-less / distroless images
Two changes so pinned plugins actually work in minimal runtime images:
tar(exec("tar -xzf ...")), which spawns/bin/sh. Distroless images have neither a shell nortar, sovarlock loadin the final stage failed withspawn /bin/sh ENOENT. Extraction is now native (zlib+ a small tar reader that runs in both Node and the compiled Bun binary), so official@varlock/*plugins auto-install at runtime with no extra setup. Verified byte-for-byte against systemtar, and end-to-end in the compiled binary with an emptyPATH+ fresh cache.flatten --vendor-plugins. Copies each npm@plugin()package into the output (.env-plugins/), rewriting the declarations to local paths. It uses the copy already in yournode_modules(no network), downloading only plugins that are not installed locally. The flattened directory then resolves with no runtime npm fetch, no shell, and no trust prompt. This is the only option that also covers third-party plugins and offline/air-gapped runtimes, which runtime auto-install cannot. Package-internal npm plugins are vendored too under this flag, since a distroless runtime has nonode_modulesto resolve from.Why not resolve-and-bake
Resolving values at flatten time would bake secrets into the artifact. This keeps runtime resolution (
varlock runin the container) working exactly as before; only the file layout changes.--vendor-pluginscopies plugin code at build time but still never resolves values.Docs: Docker guide rewritten around the new command (it was previously documented as "coming soon"), with a "Distroless and shell-less base images" section covering both fixes, plus a CLI reference entry and monorepos guide update.