Start with the map. The Linux server hosts each built static website, and Nginx serves those files. Cloudflare Tunnel connects a public hostname to that server. In the dynamic church-site architecture described here, Vite and React provide the frontend, while a Cloudflare Worker handles dynamic requests. D1 stores structured content, R2 stores uploaded documents, and Cloudflare Access protects administration.
How requests move
- Public page
Visitor → Cloudflare → Tunnel → Nginx → React site - Dynamic content
React site → /api/* → Worker → D1 - Documents
React site → Worker → D1 metadata + R2 file storage - Administration
Administrator → Cloudflare Access → /admin/* → React admin → Worker
Why separate the pieces?
Each part has one understandable responsibility. Nginx is excellent at serving files; the Worker handles the small amount of application logic; D1 stores searchable facts; R2 holds larger files; and Access handles identity before an administrative request reaches the application.
This separation keeps ordinary pages fast and available without running an application server for every visit. It also gives a church replaceable parts: the static site is not locked to the database or file-storage provider.