Cloudflare Workers on NixOS
pnpm dev on a fresh Cloudflare Workers project.
Wrangler starts, then crashes. No such file or directory.
Welcome to NixOS.
Two things break. Both are fixable with a shell.nix.
Fix 1: Symlink the binary
The workerd binary that npm installs is a standard ELF
binary linked against /lib64/ld-linux-x86-64.so.2.
NixOS doesn't have that path. But the nix-packaged
wrangler includes a properly patched workerd.
Symlink over the broken one:
# Find the nix-patched workerd
_nix_workerd=$(find ${pkgs.nodePackages.wrangler}/lib \
-path "*/workerd-linux-64/bin/workerd" -type f)
# Replace npm's broken binary with a symlink
for broken in $(find node_modules \
-path "*/workerd-linux-64/bin/workerd" ! -type l); do
ln -sf "$_nix_workerd" "$broken"
done
Fix 2: Build cert hashes
Workerd uses BoringSSL, which looks for certificates as individual
files named by their hash (a1b2c3d4.0). NixOS ships one
big ca-bundle.crt. Split it and hash it:
certDir = pkgs.runCommand "workerd-certs" {
buildInputs = [ pkgs.openssl ];
} ''
mkdir -p $out && cd $out
# Split bundle into individual PEM files
awk 'BEGIN {n=0}
/-----BEGIN CERTIFICATE-----/ {n++; f=sprintf("cert-%03d.pem",n)}
f {print > f}' ${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt
# Create hash-based symlinks
for f in cert-*.pem; do
hash=$(openssl x509 -hash -noout -in "$f")
ln -s "$f" "''${hash}.0"
done
'';
Set SSL_CERT_DIR to this directory and workerd finds
every CA certificate it needs.
Put it together
A shell.nix that does both. The binary patch runs in
shellHook (after pnpm install creates
node_modules). The cert directory is built once by nix
and cached.
If you use Turborepo, add SSL_CERT_DIR to
globalPassThroughEnv in turbo.json so it
reaches the wrangler process.
Full shell.nix on GitHub