Introduction
Compiling LaTeX to PDF on Cloudflare Workers seems straightforward until you realize the runtime has no operating system, no disk, and cannot spawn processes. This post documents the journey from that constraint to a working service, using Tectonic, careful security boundaries, and a few hard-learned deployment lessons.
What Happened
The author wanted a job tracker that could tailor a CV to a description and output a PDF. Since the app runs at the edge, the compile must leave the Worker. Tectonic was chosen for its on-demand file fetching, automatic pass looping, and secure defaults. The service runs in a Cloud Run container, facing hurdles like missing shared libraries, glibc version mismatches, and a warm-up cache bug where || true suppressed a critical failure, leaving the image with only 8 KB of cached data instead of 45 MB. Security was threaded through every decision: temp directories, path traversal prevention, and bearer-token authentication.
Why This Matters
Cloudflare Workers are V8 isolates with no disk or process spawning, so TeX engines must run elsewhere. The post explains why offloading compilation via HTTP is the right pattern, how shell-escape risks are neutralized with --untrusted, and why failing closed on missing auth tokens prevents silent security gaps. Lessons on asserting outcomes, documenting architecture decisions, and keeping deployments portable apply beyond LaTeX compilation.
Key Takeaways
- TeX engines require a full OS and cannot run in Cloudflare Workers' isolate environment
- Tectonic's on-demand file fetching and --untrusted flag provide security for untrusted documents
- Temp directories created with mkdtemp solve naming collisions but are not security boundaries
- Bearer token auth with constant-time comparison prevents unauthorized compilation
- Deployment on Cloud Run revealed glibc, library, and permission pitfalls that tutorials often omit
- A tolerated || true failure can silently leave caches tiny, causing timeouts in production
- Documenting architecture decisions and failing closed on missing config are essential for secure, portable services
Conclusion
An edge runtime promises what your code won't do: no disk, no processes, no surprises. When a feature needs those capabilities, the right move isn't to fight the isolate but to offload that work via a single authenticated HTTP call. By front-loading risk, asserting outcomes, and documenting decisions, the service stays secure, portable, and maintainable—even as the underlying platform changes.




Discussion
Join the conversation
Thoughtful reactions, questions, and follow-up ideas help shape the next story.