Skip to content
← All decisions

Choosing a host that cannot revoke my access

accepted

Context

I am a frontend engineer in Tehran. For most people the deploy target is a preference. For me it is a constraint that can be withdrawn without notice and for reasons unrelated to my code.

Vercel and Netlify refuse deploys from Iranian IPs. That is the starting position, not an edge case.

Options considered

Cloudflare Pages. My first choice, and wrong on a point of fact: Pages does not run Next.js in server mode at all. @cloudflare/next-on-pages is deprecated on npm and points at the OpenNext adapter.

Cloudflare Workers via @opennextjs/cloudflare. Genuinely capable — App Router, RSC, server actions, ISR, 'use cache'. Three problems. The free tier allows 10ms CPU per request, which a React server render does not fit in, and caps the worker bundle at 3 MiB gzipped when real OpenNext workers commonly measure 3.1–3.4. *.workers.dev is DNS-poisoned to 10.10.34.36 inside Iran, so I could not open my own portfolio from my own city. And whether I can create and pay for an account from here was unverifiable in either direction — nothing I found confirmed or denied it.

Cloudflare Workers via vinext. Cloudflare's own current recommendation. Disqualified by one line in its support matrix: next/font is "runtime CDN loading only; no self-hosting or subsetting." Self-hosted Vazirmatn exists precisely because the Google Fonts CDN is unreliable from Iran. It is also self-described as not production-ready.

Liara with a Docker standalone build. An Iranian host. Reachable, payable, and a path I have already shipped on.

Decision

Liara, output: 'standalone', multi-stage node:22-alpine, non-root.

The deciding argument is not performance, it is availability. A platform that can lose me on sanctions grounds is a single point of failure sitting underneath everything else I build. Choosing the fashionable platform and discovering that at the wrong moment is a worse outcome than accepting a slower one now.

Rejecting Cloudflare's own recommended tool on one line of its support matrix is the part of this I would defend in an interview. Reading support matrices instead of blog posts is the job.

Tradeoffs accepted

  • International latency. An Iranian host is slower for a reviewer in Berlin or San Francisco. Mitigated by making the site static-first and small, so the cost is mostly TTFB rather than payload, and a CDN can be layered in front later without touching the app.
  • No edge compute. I give up the platform primitives entirely. For a prerendered portfolio this costs nothing today; for a product with real traffic it would be a genuine limitation.
  • Self-managed container concerns. Image size, base image CVEs, Node version pinning are mine now. That is a real ongoing cost, not a one-time setup.

I also want to be honest that this is a constraint I am making a virtue of. If I could deploy to a global edge from here, I probably would.

Result

Deployable from my own machine, viewable from my own city, on infrastructure that no policy change elsewhere can take away. The architecture is deliberately portable: the app itself has no adapter, so moving to a Node host anywhere is three files.

The environment made the argument for me while I was building this. Scaffolding the repo, curl to the font CDN failed at the TLS layer from this machine while the npm registry resolved fine — so I vendored the Latin typeface out of an npm tarball instead. That is not a hypothetical about availability. That is Tuesday.

What I would do differently

I would have run the feasibility check first. I designed a full Cloudflare architecture — adapter, wrangler config, a worker-size build gate, a _headers file to replace the security headers that silently stop applying to prerendered pages — before establishing that I could open the result from Tehran. That is an hour of design thrown away for want of a ten-minute test.

The general rule I took from it: when a dependency can be revoked for reasons unrelated to engineering, verify access before designing on top of it.