Cloudflare workerd - generating configs ahead of time
If you're not familiar with Cloudflare Workers already, it's a serverless platform that leverages the V8 runtime & isolate model to provide super fast execution at a nanoservice level. In September 2022, the runtime was made publicly available as workerd
. The launch blog provides some background & context, and I highly recommend giving it a read.
The Cloudflare Workers command-line utility, Wrangler, takes a TOML configuration file & transform that into the JSON metadata that the Workers' API is expecting. With workerd
, you write the configuration file in Cap'n Proto text format.
Update: for an example of generating configs programmatically with a Cap'n Proto SDK, take a look at https://github.com/KianNH/capnproto-rust-workerd-configs
Cap'n Proto configuration file
using Workerd = import "/workerd/workerd.capnp";
const config :Workerd.Config = (
services = [
(name = "main", worker = .mainWorker),
],
sockets = [
# Serve HTTP on port 8080.
( name = "http",
address = "*:8080",
http = (),
service = "main"
),
]
);
const mainWorker :Workerd.Worker = (
serviceWorkerScript = embed "hello.js",
compatibilityDate = "2022-09-16",
);
For the full list of available options, I'll refer you to the Cap'n Proto schema for now as it's not relevant to this post.
As you can see in the mainWorker
block, the Worker script is embedded - this means that when you run workerd serve config.capnp
, it'll be looking for hello.js
on disk as well. That might work for your use-case, but for larger deployments you'll want to distribute just a configuration file.
There's a few options available to us:
- Use
workerd compile
to generate a binary configuration file with the script already embedded, or embed it into a newworkerd
binary entirely! - Use Cap'n Proto in a language of your choice, such as C++ or Rust, to generate the configuration file.
We'll cover using workerd compile
and revisit serialisation from another program in the future.
Using workerd compile
The easiest way to get started with workerd
is by using the binary distributed on npm - so we'll assume you have a recent version of Node installed.
If we run npx workerd compile --help
, there's one option that is particularly relevant.
--config-only
Only write the encoded binary config to stdout. Do not attach it to an
executable. The encoded config can be used as input to the "serve"
command, without the need for any other files to be present.
--config-only
will, rather than creating a new workerd
executable with the configuration file embedded, just give us the binary configuration file sent to stdout.
We'll use one of workerd
's samples to test it, helloworld.
$ npx workerd compile --config-only ./samples/helloworld/config.capnp > ./config.bin
$ npx workerd serve --binary ./config.bin
If we visit localhost:8080
, since the config specifies to listen on all addresses at port 8080, we'll see "Hello World"!
You now have a configuration file that we can distribute alongside workerd
without having to also ship the Worker script with it.