Roadmap Belajar

Astro dari Nol sampai Portal Berita di AWS

Dari komponen .astro pertama sampai memindahkan portal berita yang sudah hidup โ€” ratusan ribu artikel, membership berbayar, dan jutaan request per jam โ€” dari CodeIgniter 3 ke Astro, tanpa mematikan situs lama satu hari pun.

Tiga hal yang paling menentukan dibahas tuntas: paywall yang tidak bisa dilewati sekaligus tetap bisa di-cache di CDN, dua jalur data โ€” Kysely langsung ke MySQL dan consume API โ€” beserta kapan masing-masing benar, dan deployment di AWS di belakang Cloudflare.

Durasi
~18 minggu
Beban
~8 jam/minggu
Prasyarat
Pernah ngoding, paham HTTP & SQL
Target akhir
Portal berita berbayar di AWS

Untuk siapa roadmap ini

"Dari nol" di sini berarti nol Astro, bukan nol pemrograman. Kamu diasumsikan sudah pernah menulis kode di bahasa apa pun โ€” kemungkinan besar PHP โ€” dan paham dasar HTTP serta SQL. TypeScript dibahas secukupnya di Fase 0: enam konstruksi yang benar-benar dipakai, bukan kursus TypeScript lengkap.

Konteks yang dipakai sepanjang roadmap ini konkret: sebuah portal berita dan data perusahaan berbasis CodeIgniter 3 dengan membership berbayar, melayani sekitar 1,25 juta request per jam โ€” 750 ribu dilayani Cloudflare, 500 ribu lolos ke origin. Angka-angka itu dipakai untuk menghitung kapasitas, biaya, dan target sepanjang roadmap.

Versi acuan: Astro 7.2 (Astro 6 rilis Maret 2026, Astro 7 rilis Juni 2026). Beberapa hal berubah dan membuat tutorial lama menyesatkan: output: "hybrid" sudah dihapus, <ViewTransitions /> menjadi <ClientRouter />, content collections wajib memakai Content Layer API, dan Node 22.12 jadi syarat minimum. Kalau sebuah tutorial menyuruhmu cukup menaruh berkas Markdown di src/content/blog/ tanpa content.config.ts, tutorial itu ditulis untuk Astro 4 ke bawah.

Bentuk roadmap ini

BagianFaseMenjawab
Cara Astro bekerja0 โ€“ 1Island, routing, dan model rendering yang menentukan sisanya
Dari mana datanya2 โ€“ 4MySQL lewat Kysely, API, dan bagian interaktif
Membership & uang5 โ€“ 7Paywall, Midtrans, dan keamanan yang menjaganya
Melayani jutaan orang8 โ€“ 11Cache Cloudflare, migrasi dari CI3, AWS, dan performa

Urutannya disengaja. Fase 10 adalah bagian yang paling sering dicari duluan โ€” tapi deploy ke AWS sebelum cache-nya benar hanya memindahkan tagihan, dan memasang paywall sebelum memahami server islands akan menghasilkan paywall yang bisa dilewati dengan Ctrl+U. Jangan lompat ke Fase 10.

0

Fondasi: Node, TypeScript & Cara Pikir Astro

1,5 minggu Astro 7Node 22pnpmTypeScriptisland

Tujuan: punya proyek Astro yang berjalan, bisa membaca berkas .astro tanpa tersandung sintaks, dan paham kenapa arsitektur island membuat portal beritamu bisa di-cache utuh di CDN โ€” sesuatu yang tidak bisa dilakukan CI3 tanpa menulis ulang cara sesinya bekerja.

Setup sekali jalan

node --version          # wajib v22.12.0 atau lebih baru
corepack enable pnpm

pnpm create astro@latest portal-berita
cd portal-berita
pnpm astro add vue node
pnpm add kysely mysql2 zod
pnpm dev

Empat hal yang harus benar sejak hari pertama

HalKenapa
TypeScript preset strictMelonggarkan nanti mudah; mengetatkan di 200 berkas hampir tidak pernah terjadi
pnpm-lock.yaml di-commitSetara composer.lock; tanpanya build produksi tidak reprodusibel
Alias @/* di tsconfig.jsonMenghapus ../../../ yang bikin refactor menyakitkan
Hanya src/lib/ yang menyentuh databaseFilter status = 'terbit' tidak bisa terlupa di satu halaman

Materi

โœ“ Checkpoint

Kamu bisa menjelaskan kenapa halaman artikel Astro bisa dilayani dari edge Cloudflare sementara halaman CI3 yang sama tidak โ€” dan menunjuk baris kode mana penyebabnya.

1

Routing, Layout & Model Rendering

2 minggu file-based routingserver islandsmiddlewareActions

Tujuan: paham model rendering Astro cukup dalam untuk mengambil keputusan yang benar per halaman โ€” dan menguasai server islands, satu fitur yang membuat paywall dan cache CDN bisa hidup berdampingan.

Keputusan per halaman

HalamanModelCache
ArtikelOn-demands-maxage=300 + Cache-Tag
BerandaOn-demands-maxage=60
Blok paywallServer islandprivate, no-store
Dashboard memberOn-demandprivate, no-store
Tentang, S&Kprerender = trueStatis

Materi

โœ“ Checkpoint

Kamu bisa membuat halaman yang di-cache di edge selama lima menit tapi menampilkan blok berbeda untuk member dan non-member โ€” dan membuktikannya dengan curl.

2

MySQL dengan Kysely

2 minggu Kyselymysql2kysely-codegenEXPLAINread replica

Tujuan: memindahkan seluruh kueri CI3 Query Builder ke Kysely dengan tipe yang diturunkan dari skema aslimu, dan memahami aritmetika koneksi yang menentukan batas atas autoscaling-mu nanti.

Peta cepat dari CI3

// CodeIgniter 3
$this->db->select('a.id, a.judul')->from('artikel a')
         ->where('a.status', 'terbit')->order_by('a.terbit_pada', 'DESC')
         ->limit(20)->get()->result();
// Kysely โ€” bentuknya sama, tapi nama tabel & kolom diperiksa compiler
await db.selectFrom("artikel as a").select(["a.id", "a.judul"])
        .where("a.status", "=", "terbit").orderBy("a.terbit_pada", "desc")
        .limit(20).execute();

Aritmetika yang menentukan segalanya

total koneksi = connectionLimit ร— jumlah task ECS MAKSIMUM
              + koneksi CI3 selama transisi
              + cron, admin, BI
              < max_connections RDS

Materi

โœ“ Checkpoint

Kamu bisa menjalankan kysely-codegen terhadap skema CI3-mu, menulis ulang tiga kueri tersibuk sebagai Kysely, dan menyebutkan angka connectionLimit yang benar untuk portalmu beserta alasannya.

3

Jalur API

1,5 minggu endpointZodcache berlapiscircuit breaker

Tujuan: menguasai jalur data yang kedua โ€” Astro sebagai penyedia dan konsumen API โ€” dan bisa menjawab dengan tepat kapan API adalah keputusan yang benar dan kapan ia lapisan yang tidak menyelesaikan apa pun.

Argumen yang perlu diluruskan lebih dulu: API tidak mengurangi jumlah koneksi database โ€” ia memindahkan pool-nya. Yang menentukan benar-tidaknya adalah di mana Astro berjalan: di ECS sebagai proses panjang, pool sudah terpusat dan API cuma menambah satu hop; di Lambda, kekhawatirannya nyata dan jawabannya RDS Proxy, bukan API buatan sendiri. Alasan yang benar untuk membangun API ada, dan dibahas di fase ini.

Materi

โœ“ Checkpoint

Kamu bisa membangun halaman yang mengambil dua sumber data secara paralel, tetap merender dalam tiga detik meski salah satunya menggantung sepuluh detik, dan menurunkan TTL cache-nya saat itu terjadi.

4

Island Vue & Interaktivitas

1,5 minggu Vueclient:*nanostoresClientRouter

Tujuan: menambahkan tabel data, grafik, dan komponen interaktif tanpa membengkakkan JavaScript yang sampai ke pembaca โ€” dengan anggaran yang ditegakkan otomatis di CI, bukan diingat orang.

Anggaran JavaScript

HalamanAnggaran (gzip)
Artikelโ‰ค 45 KB
Berandaโ‰ค 60 KB
Data perusahaanโ‰ค 140 KB
Dashboard memberโ‰ค 180 KB

Materi

โœ“ Checkpoint

Kamu bisa membangun tabel data perusahaan yang bisa disortir dan difilter, tetap berfungsi tanpa JavaScript, dan tidak melewati anggaran JS halamannya.

5

Membership, Auth & Paywall

2 minggu sesibcryptpaywallRBACrate limit

Tujuan: memindahkan member CI3 tanpa satu pun dari mereka perlu reset password, dan membangun paywall yang isinya benar-benar tidak pernah meninggalkan server untuk pembaca yang tidak berhak.

Paywall yang mengirim seluruh artikel lalu menutupinya dengan CSS bukan paywall. Ctrl+U membukanya, mode baca peramban membukanya, dan ekstensi yang menghapusnya tersedia gratis. Fase ini membangun yang sesungguhnya.

Materi

โœ“ Checkpoint

curl tanpa cookie ke artikel premium tidak menemukan satu pun kalimat dari paragraf kesepuluh โ€” dan hash password $2y$ dari PHP terverifikasi di Node lalu naik kelas diam-diam saat member login.

6

Midtrans & Langganan

1,5 minggu SnapwebhookSHA-512idempotensidunning

Tujuan: alur pembayaran yang benar meski webhook datang dua kali, terbalik urutannya, atau tidak datang sama sekali โ€” dan penagihan berulang yang tidak kehilangan pelanggan gara-gara kartu kedaluwarsa.

Aturan yang tidak bisa ditawar

AturanKalau dilanggar
Halaman "sukses" bukan bukti pembayaranSiapa pun bisa membuka URL-nya tanpa membayar
gross_amount dari database, bukan klienLangganan setahun seharga seribu rupiah
Verifikasi tanda tangan atas raw bodySiapa pun bisa mengaktifkan langganan dengan curl
Pemrosesan idempotenSatu pembayaran memperpanjang langganan dua kali
Webhook dikecualikan dari WAFPembayaran diblokir tanpa jejak di log aplikasi

Materi

โœ“ Checkpoint

Mengirim notifikasi webhook yang sama tiga kali hanya memajukan langganan_sampai sekali, dan settlement yang tiba sebelum pending tidak menurunkan status yang sudah aktif.

7

Keamanan

1,5 minggu CSPsanitasi HTMLCSRFastro:envsupply chain

Tujuan: menutup jalur serangan yang benar-benar ada di portal berita โ€” HTML artikel dari tiga generasi editor, endpoint buatan sendiri tanpa CSRF, dan rahasia yang bisa bocor ke bundel klien lewat satu impor.

Satu pertukaran yang harus kamu putuskan sadar: CSP bawaan Astro tidak kompatibel dengan <ClientRouter /> dari Fase 4. Untuk portal berbayar, saranku CSP yang menang โ€” transisi halaman adalah kenyamanan, XSS di halaman yang memegang sesi berbayar adalah pengambilalihan akun.

Materi

โœ“ Checkpoint

Membuat PR yang mengimpor server key Midtrans ke komponen Vue akan menggagalkan build, dan daftar payload XSS standar tidak ada satu pun yang lolos sanitizer-mu.

8

Cloudflare: Cache, Edge & WAF

2 minggu Cache RulesCache-TagTiered CacheR2Tunnel

Tujuan: menaikkan cache hit ratio dari 60% ke 92โ€“95%, memangkas beban origin lima sampai enam kali lipat, dan memastikan seluruh lapisan Cloudflare tidak bisa dilewati begitu saja.

Target yang bisa diukur

SekarangSetelah fase ini
Cache hit ratio60%92โ€“95%
Request ke origin500.000 / jam~75.000 / jam
Rata-rata req/detik ke origin139~21
Egress AWS~10,8 TB/bulan~1,6 TB/bulan

Satu hal yang sering luput diperiksa: kalau ALB-mu punya IP publik yang bisa dihubungi langsung, seluruh WAF, rate limit, dan bot protection-mu opsional โ€” dan cf-connecting-ip yang kamu pakai untuk rate limiting bisa dipalsukan. Situsnya bekerja sempurna meski salah, jadi tidak ada yang menyadarinya.

Materi

โœ“ Checkpoint

Halaman artikel mengembalikan cf-cache-status: HIT termasuk dengan parameter ?utm_source=, jalur /akun selalu BYPASS, dan menghubungi IP origin langsung tidak menghasilkan apa pun.

9

Migrasi dari CodeIgniter 3

2 minggu stranglerredirect 301Google Newsutf8mb4cutover

Tujuan: memindahkan portal yang sudah hidup, sepotong demi sepotong, dengan rollback semudah menonaktifkan satu aturan Cloudflare โ€” tanpa kehilangan satu pun URL yang sudah terindeks.

Urutan pemindahan

TahapYang dipindahKenapa urutan ini
1Halaman statisMembuktikan pipeline deploy bekerja
2Login, daftar, akunSesi bersama harus hidup sebelum yang lain
3Halaman artikelVolume terbesar; di sini keuntungan cache muncul
4Beranda & kategoriSetelah artikel terbukti stabil
5โ€“6Data perusahaan, lalu langgananYang menyentuh uang paling akhir
7โ€“8Panel redaksi, lalu matikan CI3Setelah berminggu-minggu tanpa trafik

Materi

โœ“ Checkpoint

Seluruh daftar URL lama dari log akses mengembalikan 301 ke tujuan akhir tanpa rantai, dan uji paritas terhadap seribu URL nyata tidak menghasilkan satu pun selisih pada status, kanonik, dan JSON-LD.

10

Deploy di AWS

2 minggu ECS FargateDockerRDSGitHub ActionsCloudWatch

Tujuan: menjalankan Astro di AWS dengan deploy tanpa satu pun 5xx, rollback dalam dua menit, dan kapasitas yang dihitung dari angka trafikmu โ€” bukan ditebak.

Hitungan kapasitas

Ke origin setelah cache diperbaiki : ~24 req/detik rata-rata
Puncak (2,5โ€“3ร—)                    : ~70 req/detik
  45 req/dtk halaman ร— 35 ms       = 1,58 detik-CPU/detik
  25 req/dtk island  ร—  8 ms       = 0,20 detik-CPU/detik
                                   รท target 60%
                                   = 3 task, + margin AZ = 5

Batas ATAS bukan dari CPU, tapi dari max_connections RDS.

Materi

โœ“ Checkpoint

Menjalankan uji beban sambil melakukan deploy menghasilkan nol 5xx, dan container yang menerima SIGTERM di tengah request lambat menyelesaikannya lalu keluar dengan kode 0.

11

Performa & Capstone

1,5 minggu Core Web VitalsServer-Timingk6runbookcapstone

Tujuan: membuktikan portalnya cepat dengan data lapangan pembaca sungguhan, mengetahui di mana titik patahnya, dan menyelesaikan capstone yang menggabungkan seluruh roadmap.

Target akhir

MetrikTarget
Cache hit ratio> 90%
p95 render origin< 150 ms
p95 server island< 50 ms
JS halaman artikel< 45 KB gzip
LCP / CLS (lapangan)< 2,5 dtk / < 0,1
Uji beban 2ร— puncakNol 5xx
Kebocoran isi premiumNol

Materi

โœ“ Checkpoint

Seluruh perintah verifikasi di halaman capstone berjalan hijau โ€” kebenaran, cache, pembayaran, keamanan, performa, dan operasional.

Rekomendasi best practice

Delapan belas aturan yang muncul berulang di seluruh roadmap ini. Kalau kamu hanya sempat mengingat satu halaman, ingat yang ini.

  1. Halaman yang di-cache tidak boleh menyentuh cookie. Satu pembacaan sesi mengubah halaman jadi personal โ€” dan kalau kamu lupa mematikan cache-nya, halaman satu member tersaji ke member lain.
  2. Isi berbayar tidak pernah diambil kalau haknya belum terbukti. Bukan diambil lalu disembunyikan. Kueri isi lengkap hanya berjalan setelah hak.boleh === true.
  3. Server island untuk yang personal, halaman untuk yang sama bagi semua orang. Ini satu-satunya cara paywall dan cache CDN hidup berdampingan.
  4. Pasang ASTRO_KEY tetap sebelum deploy pertama. Tanpanya, tiap rolling deploy menghasilkan lima menit island yang gagal โ€” dan sudah pulih saat kamu memeriksanya.
  5. Kirim ID sebagai props island, bukan data. Melewati 2048 byte membuat Astro beralih ke POST, yang tidak di-cache browser sama sekali.
  6. Hanya src/lib/ yang menyentuh database. Bukan kerapian: ia yang membuat filter status = 'terbit' tidak bisa terlupa, dan yang membuat jalur data bisa diubah nanti tanpa menyentuh halaman.
  7. Batasi operasi tulis lewat WHERE, bukan lewat if. WHERE id = ? AND penulis_id = ? membuat baris orang lain tidak pernah ditemukan โ€” pertahanan yang tidak bisa lupa dipasang.
  8. Hitung connectionLimit untuk jumlah task maksimum. Autoscaling yang tidak memperhitungkan ini akan menjatuhkan database tepat saat trafik memuncak.
  9. Transaksi hanya berisi kueri database, dan sependek mungkin. Satu panggilan HTTP di dalamnya bisa menahan baris terkunci selama lima detik dan menghabiskan pool.
  10. Timeout di setiap lapisan, mengecil ke dalam. Cloudflare > ALB > Node > kueri. Kalau lapisan dalam lebih longgar, klien menyerah sementara kuerinya tetap bekerja untuk tidak ada siapa-siapa.
  11. Validasi di batas sistem, selalu. Tipe TypeScript dihapus saat build; hanya Zod yang benar-benar memeriksa data dari API, form, cookie, dan variabel lingkungan.
  12. Verifikasi tanda tangan webhook atas raw body, dengan perbandingan waktu-tetap. Dan jangan pernah mengonversi gross_amount โ€” ia string.
  13. Webhook harus idempoten dan dikecualikan dari WAF. Ia akan datang dua kali, dan managed rules akan memblokirnya tanpa jejak di log aplikasimu.
  14. stale-while-revalidate dan stale-if-error yang panjang adalah jaring pengamanmu. Origin tumbang total tetap menyisakan portal yang menyajikan artikel dari edge.
  15. Purge by tag, jangan Purge Everything. Di trafikmu, mengosongkan cache berarti mengirim 16 kali beban normal ke origin sekaligus.
  16. Kunci origin-mu. IP yang bisa dihubungi langsung membuat seluruh lapisan Cloudflare โ€” WAF, rate limit, bot protection โ€” jadi opsional.
  17. Migrasi skema harus kompatibel dua arah selama CI3 masih hidup. Menghapus satu kolom lebih awal mengubah rollback dari "ubah satu aturan" jadi "pulihkan database".
  18. Matikan cron di sistem lama saat cutover. Ini yang paling sering terlupa, dan akibatnya newsletter ganda โ€” atau penagihan ganda.

Kesalahan yang paling mahal

KesalahanAkibatnyaDibahas di
Halaman personal ditandai public di CDNData satu member tersaji ke member lainFase 1, 8
Isi premium dikirim lalu disembunyikan CSSPaywall bisa dilewati Ctrl+UFase 5
Endpoint JSON lupa memeriksa hakPaywall bocor lewat pintu belakangFase 3, 5
gross_amount dari input klienLangganan setahun seharga seribu rupiahFase 6
Webhook diblokir WAFPembayaran tidak tercatat, tanpa jejak di logFase 6, 8
Halaman "sukses" mengaktifkan langgananSiapa pun bisa berlangganan gratisFase 6
IP origin bisa dihubungi langsungSeluruh WAF terlewati; rate limit jebolFase 8
ASTRO_KEY tidak tetapIsland gagal tiap deploy, pulih sendiriFase 1, 10
keepAliveTimeout < idle timeout ALB502 acak tanpa jejak di log aplikasiFase 10
Sesi di memori prosesMember ter-logout acakFase 5
Migrasi di entrypoint containerDua belas task menjalankannya bersamaanFase 2, 10
Health check ALB menyentuh databaseGangguan sebagian jadi pemadaman totalFase 10
Cron di dalam service webJob berjalan sebanyak jumlah taskFase 10
Redirect 302 untuk migrasi URLSinyal peringkat tidak berpindah; trafik turun perlahanFase 9
Konversi charset pada data yang sudah rusakKerusakan terkunci permanenFase 9
sql.raw() menerima input dari luarInjeksi SQLFase 7

Satu hal yang tidak akan diselesaikan infrastruktur: halaman yang butuh empat puluh kueri dan mengirim dua megabita HTML tetap mahal di runtime mana pun, di belakang CDN mana pun. Ukur dulu, baru belanja โ€” dan di roadmap ini, "ukur" berarti EXPLAIN, Server-Timing, dan cache hit ratio, bukan perasaan.

Aturan main

  1. Bangun, jangan cuma baca. Setiap materi di sini punya latihan konkret di akhirnya; latihan itu yang membuatnya melekat.
  2. Ukur sebelum dan sesudah. Hampir setiap klaim performa di roadmap ini bisa kamu buktikan sendiri dalam sepuluh menit โ€” lakukan.
  3. Pakai angka portalmu sendiri. Angka trafik, waktu render, dan biaya di sini adalah contoh. Yang menentukan keputusanmu adalah milikmu.
  4. Satu perubahan pada satu waktu. Menaikkan versi Astro dan mengubah adapter bersamaan membuat hasilnya tidak bisa dibaca.
  5. Uji di pnpm preview, bukan pnpm dev. Bug yang hanya muncul di produksi hampir selalu sudah terlihat di sana.
  6. Jangan lompat ke Fase 10. Deploy ke AWS sebelum cache-nya benar hanya memindahkan tagihan.
  7. Hapus resource AWS setelah berlatih. RDS, NAT Gateway, dan ElastiCache ditagih per jam, dipakai atau tidak.
  8. Uji pemulihan cadangan, jangan cuma membuatnya. Cadangan yang tidak pernah dipulihkan bukan cadangan.

Sebelum & sesudah ini

Roadmap ini mengandaikan kamu sudah pernah menulis kode dan paham dasar HTTP serta SQL. Kalau belum pernah ngoding sama sekali, mulai dari Python Dasar untuk Pemula. Kalau kamu ingin mendalami sisi AWS-nya lebih jauh โ€” IAM, IaC, observability โ€” AWS untuk AI Engineer membahasnya dengan sudut pandang berbeda. Dan kalau kamu penasaran bagaimana bahasa lain menyelesaikan masalah yang sama di skala yang sama, Go dari Nol sampai Enterprise dan Laravel dari Nol sampai Enterprise menempuh jalur paralel dengan pertukaran yang sangat berbeda.