From git push to Cloudflare Pages in 90 seconds
CI/CD pipeline lengkap dari commit ke production deploy dalam 90 detik. Setup yang saya pakai untuk 8 Astro project SMB. Reproducible step-by-step.
TL;DR
Target: git push → production live dalam 90 detik.
Stack:
- Astro 6 + Bun
- GitHub repository
- Cloudflare Pages (auto-deploy)
- No GitHub Actions needed (CF Pages handle CI)
Why 90 seconds matters
Untuk SMB Indonesia, deploy speed matter karena:
- Marketing copy update: butuh in 5 menit, bukan 30 menit
- Hot fix bug: production patch quick
- Iteration speed: lebih cepat deploy = lebih banyak iteration = lebih cepat learn
90 detik adalah sweet spot — cukup cepat untuk “instant” feel, masih ada time untuk build + cache.
Initial setup (one-time)
1. Create Astro project
bun create astro@latest my-project
cd my-project
git init
git add -A
git commit -m "Initial"
2. Create GitHub repo + push
gh repo create my-project --private --source=. --remote=origin --push
(Pakai GitHub CLI, atau create via web UI dan add remote manual.)
3. Connect to Cloudflare Pages
Via Cloudflare dashboard:
- Pages → Create application → Connect to Git
- Pilih GitHub repository
- Build settings:
- Framework preset: Astro
- Build command:
bun run build - Build output directory:
dist - Root directory: (leave default)
Setup time: 5-7 menit.
4. Konfigurasi build environment
Di CF Pages dashboard, project setting → Environment variables:
NODE_VERSION = 22.16.0
BUN_VERSION = 1.3.11
Atau create .node-version file di repo root:
22.16.0
CF Pages auto-detect Bun kalau Anda punya bun.lockb di repo.
Daily workflow
# Edit code
vim src/pages/index.astro
# Commit + push
git add -A
git commit -m "Update hero copy"
git push
# 90 detik kemudian: production live
CF Pages otomatis:
- Detect push to main branch
- Trigger build via build agent
- Run
bun install - Run
bun run build - Upload
dist/to edge network - Invalidate CDN cache
- Serve new version
Breakdown timing
Untuk Astro project medium (50K LOC, 30 dependencies):
| Step | Time |
|---|---|
| GitHub webhook trigger CF Pages | 2-3s |
| CF Pages build agent provision | 5-8s |
| Git clone | 4-6s |
bun install (cached) | 6-10s |
bun run build | 25-35s |
Upload dist/ ke edge | 10-15s |
| CDN cache invalidation | 5-8s |
| Total | 57-85 detik |
Sustainable di 70-90 detik range untuk 90% deploy.
Optimasi build time
1. Cache node_modules
CF Pages automatic cache between build kalau bun.lockb tidak berubah. Selalu commit bun.lockb.
2. Bun > npm
Untuk install + run scripts, Bun 2-3x lebih cepat dari npm di CF Pages environment. Worth tukar.
3. Astro production mode
Astro 6 default sudah production-optimized. Tidak perlu config tambahan.
4. Avoid heavy build-time dependency
Hapus dependency yang hanya untuk dev (e.g., test runner kalau Anda tidak pakai CI):
bun remove vitest @vitest/ui # kalau Anda tidak test di CF Pages build
5. Image optimization
astro-og-canvas (untuk OG image) bisa add 10-30 detik build time kalau Anda generate 100+ image. Solution: cache generated images.
---
// src/pages/og/[route].png.ts
export const { getStaticPaths, GET } = await OGImageRoute({
// ... existing config
cacheDir: './node_modules/.astro-og-cache', // cache rendered images
});
---
Build subsequent deploys 60-80% lebih cepat karena cache hit.
Multi-environment (staging + production)
Setup staging branch
git checkout -b staging
git push -u origin staging
Di CF Pages, project setting → Builds & deployments → “Preview deployments”:
- Production branch:
main - Preview branches:
staging,feature/*
Setiap push ke staging → deploy ke staging.pages.dev.
Setiap push ke feature/foo → deploy ke feature-foo.pages.dev.
Push ke main → production.
Custom domain per environment
mainbranch →kodekarawaci.web.idstagingbranch →staging.kodekarawaci.web.id
Setup di CF Pages → Custom domains → Add custom domain → pilih branch.
Webhook untuk deploy notification
Notify Anda saat deploy selesai (success/fail). Pakai Discord/Slack webhook.
// scripts/notify-deploy.mjs
import fetch from 'node-fetch';
const status = process.env.CF_PAGES_STATUS || 'unknown';
const branch = process.env.CF_PAGES_BRANCH || 'unknown';
const commitSha = process.env.CF_PAGES_COMMIT_SHA || '';
const message = {
content: `🚀 Deploy ${status} for branch \`${branch}\`\nCommit: \`${commitSha.slice(0, 7)}\`\n${process.env.CF_PAGES_URL}`
};
await fetch(process.env.DISCORD_WEBHOOK_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(message),
});
Add to package.json:
{
"scripts": {
"build": "astro build && node scripts/notify-deploy.mjs"
}
}
Notification arrives 90-120 detik after git push. Good for awareness.
Rollback strategy
Kalau deploy break production:
Option A: Revert commit
git revert HEAD
git push
90 detik kemudian, production reverted.
Option B: CF Pages dashboard rollback
CF Pages dashboard → Deployments → pilih previous deployment → “Rollback to this deployment”.
Instant rollback (no rebuild). Useful untuk urgent fix.
Common pitfall
Build fail karena environment mismatch
CF Pages build environment beda dari local Anda. Common cause:
- Node version mismatch (
.node-versiontidak commit) - Missing env variable (production env beda dari local
.env) - File case sensitivity (Mac case-insensitive, Linux case-sensitive)
Mitigation: test build locally dengan exact Node version yang CF Pages pakai sebelum push.
Slow first deploy
Pertama kali deploy after add new dependency, build agent perlu install all (no cache). Bisa take 2-3 menit.
Subsequent deploy yang reuse cache: kembali ke 90 detik.
Branch deployment limit
CF Pages free tier: 500 deploy/bulan. Setiap push (semua branch) count.
Solution: untuk preview branch, pakai [ci skip] di commit message kalau Anda tidak butuh preview deploy.
Yang sering Anda lupa
Custom 404: pages yang tidak match route harus return 404, bukan empty page. Pakai src/pages/404.astro.
Sitemap: untuk SEO, generate via @astrojs/sitemap. Auto-include semua route.
Cache control: CF Pages default cache HTML 0 detik, asset 365 hari. Override via _headers file kalau perlu:
# _headers
/api/*
Cache-Control: no-cache
/assets/*
Cache-Control: public, max-age=31536000, immutable
Konteks Indonesia
CF Pages punya 4 PoP Indonesia (Jakarta, Surabaya, Medan, Denpasar). Customer Anda di Indonesia akan fetch dari PoP terdekat — latency 5-30ms.
Untuk klien yang customer mostly Tangerang/Jakarta: actual user experience sangat baik.
Verdict
Recommended untuk Astro project SMB Indonesia.
Setup once, ship forever. Tidak ada surprise. Predictable timing. Free tier sangat generous (500 deploys/bulan + unlimited bandwidth).
Hindari over-engineering: GitHub Actions untuk SMB Astro project usually overkill — CF Pages built-in CI handle semua dengan baik.
Ditulis oleh Asti Larasati