loading...

Vercel (Zeit's Now) builders cache for docker-compose

av_82 profile image AV ・2 min read

If you happened to use Vercel (formely Now from Zeit.co) and docker-compose, there's a simple tweak to decrease startup times when launching multiple components which are running now dev inside the container.

version: "3"
services:
  next_frontend:
    context: ./next-app
    volumes:
      - now_cache:/root/.cache/co.zeit.now/dev/builders
  serverless_backend:
    context: ./now-app
    volumes:
      - now_cache:/root/.cache/co.zeit.now/dev/builders
volumes:
  now_cache:

This allows docker to reuse installed builders in a similar way it's done on Vercel's platform, when building new versions of the component.

Startup times before the tweak:

 ▾ ~/code/app
   docker-compose up | ts -s '%.S'
yarn run v1.22.4
$ /app/node_modules/.bin/now dev
02.670810 > Now CLI 19.0.0 — https://zeit.co/feedback
10.620778 > Ready! Available at http://localhost:3000

Startup times after the tweak:

 ▾ ~/code/app
   docker-compose up | ts -s '%.S'
yarn run v1.22.4
$ /app/node_modules/.bin/now dev
02.580774 > Now CLI 19.0.0 — https://zeit.co/feedback
02.886081 > Ready! Available at http://localhost:3000

It won't help with the startup time for your first build, but will speed up all the consequent starts.

Below is a brief explanation on why and how this works.


The way now dev works is by emulating a build "sandbox" similar to that which builds your projects in the Vercel's cloud. This sandbox does a lot of heavy lifting for such things as turning your /api or /public folder to a deployable serverless app and enrich your dev experience with such hooks as now-build or now-start in a package.json, providing an identical zero-config environment regardless if you're running your app locally or in the cloud.

Some of these features, though, are quite heavy in terms of the start costs. So, as usual, caching is involved. The cache is centralised for all the projects using now on your machine, regardless of CLI version. The cache itself contains a couple of interesting things: yarn executable and builders which has been previously detected in use by now CLI.

As this cache is global, docker-compose knows nothing about it and each and every app start is a cold one. Mounting a persistent volume to that folder allows the cache to function exactly as intended.

It's also possible to mount your ~/.cache/co.zeit.now to reuse the already existing cache for your currently logged-in user. That'll likely not work for your CI/CD pipeline though.

Please, be aware that this builders cache is not explicitly documented, so the behavior may potentially change in future.

Posted on by:

Discussion

markdown guide