Deploy Astro on Cloudflare Pages — Zero-Server Static Power
Astro + Cloudflare Pages is the cheapest, fastest stack on the web: free hosting, global edge CDN, automatic HTTPS, and deploys that take under a minute. Here's the complete setup, including custom domains and DNS.
This very site is the proof: Astro, built to static files, served from Cloudflare’s edge network for exactly $0 per month. If you’re shipping a content site, a landing page, or a documentation hub, this is the stack to beat — and here’s the entire playbook, including the parts everyone forgets (custom domains, DNS records, environment variables).
Why this pairing wins
- Astro compiles to pure HTML/CSS — no server, no database, nothing to patch.
- Cloudflare Pages serves it from 330+ cities, with automatic HTTPS, Brotli compression, and cache headers tuned for static assets.
- GitHub integration means every push to
mainrebuilds and redeploys. An AI agent can publish articles by committing Markdown — no dashboards, no SSH.
Step 1 — Build the site
npm create astro@latest -- --template minimal
npm run build # produces dist/
For a content site, add the sitemap and RSS integrations — both are build-time only:
npx astro add sitemap
npm i @astrojs/rss
Set the canonical URL in astro.config.mjs — this drives the sitemap and feeds:
export default defineConfig({
site: 'https://discover.jellypuff.link',
output: 'static',
});
Step 2 — Connect GitHub
Push the repo to GitHub, then in the Cloudflare dashboard:
- Workers & Pages → Create → Pages → Connect to Git.
- Pick the repo, set the build config:
| Setting | Value |
|---|---|
| Production branch | main |
| Build command | npm run build |
| Build output directory | dist |
| Node.js version | 22 |
- Save. Cloudflare installs dependencies and builds automatically.
Step 3 — Attach a custom domain
Your site is live at https://<project>.pages.dev immediately. To serve it on discover.jellypuff.link:
- Pages → your project → Custom domains → Set up a custom domain.
- Enter
discover.jellypuff.link. - Cloudflare offers to create the DNS record automatically — because the zone is on Cloudflare, it’s one click. This creates a CNAME
discover→<project>.pages.dev(proxied, orange cloud). - Wait for the certificate — usually a few minutes, up to ~15.
If you add the DNS record manually (e.g. in another DNS provider), it’s exactly: Type: CNAME · Name:
discover· Target:<project>.pages.dev· Proxy: ON
Step 4 — Environment variables
Only what the site needs. For a static Astro site: usually nothing at build time if URLs are baked in. If you ever need secrets at build time (private APIs, draft-mode flags), set them in Pages → Settings → Environment variables — never in the repo.
| Variable | Where | Example |
|---|---|---|
PUBLIC_SITE_URL |
Pages env (optional) | https://discover.jellypuff.link |
PUBLIC_-prefixed variables are inlined into the client bundle at build time — never put secrets in those.
Step 5 — GitHub Actions (the exact workflow)
Skip the dashboard integration if you prefer everything in git — use the official action:
name: Deploy to Cloudflare Pages
on:
push:
branches: [main]
workflow_dispatch:
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 22, cache: npm }
- run: npm ci
- run: npm run build
- uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: pages deploy dist --project-name=discover
Create the two secrets in GitHub → Settings → Secrets:
CLOUDFLARE_API_TOKEN— API token withCloudflare Pages:Editpermission.CLOUDFLARE_ACCOUNT_ID— found in the dashboard sidebar / Workers & Pages.
What production looks like
- Lighthouse: 95+ across the board when you keep JS minimal (this site ships three tiny islands).
- TTFB: sub-100 ms globally — the edge does the work.
- Rollbacks: every deployment is immutable; roll back from the dashboard in one click.
- Cost: $0 hosting, $0 bandwidth, $0 SSL. Your only bill is the domain name.
Ship it — the internet’s fastest free stack is now yours.
Written by
JellyPuff Media
Editor-in-Chief
Auckland-based publisher covering AI, self-hosting and tech in New Zealand.
Keep reading
Related articles
From Zero to First Cloudflare Worker in 20 Minutes
No account? No problem. Ship a live serverless API on Cloudflare's free tier in 20 minutes — install Wrangler, write a Worker, deploy, and test it with curl.