Review Helipod: Deploy Next.js di PaaS Indonesia

Foto oleh Hugovanmeijeren via Wikimedia Commons (CC BY-SA 3.0)
Helipod adalah Platform-as-a-Service Indonesia: cluster Kubernetes terkelola yang disajikan sebagai deployment dashboard, dijalankan perusahaan yang terdaftar di Jakarta. Di VPS kamu sendiri yang memasang nginx, menulis Dockerfile, dan memperbarui sertifikat, sementara Helipod mengambil keputusan itu untukmu dan memberi logs, metrics, serta terminal di browser alih-alih SSH. Kamu menukar kemampuan memperbaiki di level host dengan kenyamanan tidak perlu memperbaikinya.
Bisa. Helipack, build engine milik Helipod, mendeteksi Next.js dari package.json, menentukan package manager dari lock file, menambal config kamu supaya memakai standalone output mode kalau belum disetel, lalu menghasilkan Dockerfile multi-stage dengan non-root user dan BuildKit build secrets. Helipod mempublikasikan Dockerfile hasil generate-nya, jadi kamu bisa membacanya sebelum mempercayainya. Rust, Ruby, dan Java tidak terdeteksi dan butuh Dockerfile buatanmu sendiri.
Bisa, dan itu alasan utama platform ini ada. Helipod memakai saldo prabayar dalam Rupiah serta menerima QRIS, transfer bank, virtual account, dan e-wallet langsung, jadi GoPay, OVO, Dana, atau ShopeePay sudah cukup. Top up mulai dari Rp 10.000, QR code-nya kedaluwarsa setelah sepuluh menit, dan saldonya dipotong harian — sehingga top up jadi bagian dari menjaga layanan tetap hidup.
Harga normal yang dipublikasikan mulai Rp 123.750 per bulan untuk Nano, yaitu 1 vCPU, 1 GB RAM, 15 GB storage, dan dua custom domain, sampai Rp 2.785.500 untuk Business dengan 22 vCPU dan 22 GB. Plan itu sebenarnya tiga puluh hari tarif pay-as-you-go harian dengan harga identik, bukan diskon atasnya. Promo muncul di situsnya dari waktu ke waktu, jadi baca halaman pricing dan bukan artikel blog yang masih memuat angka lama.
Karena Next.js meng-inline setiap variable NEXT_PUBLIC_ ke dalam JavaScript bundle saat next build berjalan, jadi nilai yang diterima browser sudah dibekukan pada saat build dan tidak dibaca dari environment. Dokumentasi Next.js menyatakan bahwa setelah di-build aplikasi tidak lagi merespons perubahan pada variable tersebut. Mengubah nilainya di tab Variables lalu restart pod tidak akan mengubah apa pun; kamu perlu redeploy supaya terjadi build baru.

Foto oleh Hugovanmeijeren via Wikimedia Commons (CC BY-SA 3.0)
Ringkasan Utama
Helipod adalah Platform-as-a-Service Indonesia yang membangun repository Next.js menjadi container tanpa Dockerfile, menagih dalam Rupiah lewat QRIS alih-alih kartu kredit internasional, dan memberi subdomain helipod.app gratis lengkap dengan SSL. Plan yang dipublikasikan mulai Rp 123.750 per bulan, dan batas per pod yang didokumentasikan adalah empat vCPU.
Yang menentukan pilihan hosting di Indonesia jarang soal fitur. Yang menentukan adalah apakah kamu bisa membayarnya. Developer yang cuma punya kartu debit BCA dan saldo GoPay tidak bisa mendaftar di sebagian besar platform yang membuat deploy Next.js terasa menyenangkan, karena platform itu meminta kartu kredit internasional dan menagih dalam Dollar. Helipod dibangun untuk menjawab pertanyaan itu dengan satu QR code.
Ini review berbasis dokumentasi dan hitungan, bukan laporan operasional enam bulan. Saya membaca halaman pricing Helipod, halaman fitur Helipack, dan panduan deploy mereka sendiri, mencocokkan angka-angka yang dipublikasikan satu sama lain, lalu memeriksa perilaku Next.js yang mereka jelaskan terhadap dokumentasi Next.js. Kalau sebuah klaim datang dari Helipod dan bukan dari saya, akan saya sebutkan.
Helipod adalah control plane Kubernetes terkelola yang dibungkus sebuah deployment dashboard, dan artikel pengantar mereka sendiri menyebutnya persis seperti itu: aplikasimu berjalan di cluster yang dikonfigurasi dan dioperasikan tim Helipod. Ingress, TLS, health check, restart policy, dan image registry sudah diputuskan untukmu. Perusahaannya terdaftar di Jakarta, dan platform ini mencantumkan Indonesia, Singapura, Malaysia, Thailand, Filipina, Vietnam, dan India sebagai wilayah yang dilayani. Deploy pertama kurang lebih seperti ini:
Tidak ada satu pun command di daftar itu, dan di situlah seluruh nilai jualnya. Tapi perlu jujur soal apa yang sebenarnya hilang: bukan Docker, karena Docker tetap ada, melainkan bagian di mana kamu menulis Dockerfile, menjaga certbot tetap memperbarui sertifikat, dan mengingat server block nginx mana yang memegang port 3000.
Helipack adalah build engine internal Helipod dan bagian paling menarik dari platform ini. Ia mendeteksi framework dari package.json, composer.json, requirements.txt, go.mod, dan file config, menentukan package manager dari lock file — npm, yarn, pnpm, atau bun — lalu menghasilkan Dockerfile multi-stage. Untuk repository Next.js, ia menambal config Next.js kamu supaya memakai standalone output mode kalau kamu belum menyetelnya sendiri, baru kemudian build. Helipod mempublikasikan Dockerfile hasil generate-nya, dan itu tidak biasa dalam arti yang baik, jadi layak dibaca perlahan:
# The Dockerfile Helipod publishes as its own Next.js output, abridged.
# Read it once: it tells you what your build may and may not rely on.
FROM node:20-alpine AS base
RUN apk add --no-cache libc6-compat tini git
WORKDIR /app
FROM base AS deps
COPY package.json package-lock.json ./
RUN --mount=type=cache,target=/root/.npm \
npm ci --prefer-offline --no-audit --no-fund
# The lock file is copied on its own, so this layer is rebuilt only when
# dependencies change. Do not gitignore the lock file — you lose the cache.
FROM base AS builder
COPY --from=deps /app/node_modules ./node_modules
COPY . .
ENV NEXT_TELEMETRY_DISABLED=1
ENV NODE_OPTIONS="--max-old-space-size=4096"
RUN --mount=type=cache,target=/root/.npm \
--mount=type=secret,id=build_env,dst=/app/.env \
npm run build
# Your dashboard Variables arrive here as a BuildKit secret mounted at
# /app/.env — readable by next build, never baked into an image layer.
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
RUN addgroup --system --gid 1001 nodejs && \
adduser --system --uid 1001 nextjs
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
COPY --from=builder --chown=nextjs:nodejs /app/public ./public
USER nextjs
EXPOSE 3000
ENV PORT=3000 HOSTNAME=0.0.0.0
ENTRYPOINT ["/sbin/tini", "--"]
CMD ["node", "server.js"]
# Only the standalone output, .next/static and public are carried forward.
# No node_modules in the runtime image, and nothing you wrote outside those
# three paths exists once the pod is running.Dua baris di file itu lebih penting daripada sisanya. Build secret yang di-mount di /app/.env adalah cara Variables dari dashboard sampai ke next build tanpa tersimpan di image layer, dan itu cara yang benar. Lalu stage runner hanya membawa tiga hal: standalone output, folder static, dan public. Dokumentasi Next.js menjelaskan bentuk yang sama — standalone menghasilkan folder yang bisa jalan tanpa install node_modules, ditambah server.js minimal, dan menegaskan bahwa public serta folder static tidak ikut ter-copy otomatis karena CDN yang diharapkan menyajikannya. Helipack meng-copy keduanya untukmu.
Yang terdeteksi adalah Node.js, PHP, Python, dan Go: Next.js, Nuxt, Remix, Astro, Express, dan NestJS; Laravel dan Symfony; Django, FastAPI, dan Flask; Gin dan Echo. Rust, Ruby, dan Java tidak terdeteksi sama sekali, dan FAQ Helipod sendiri menyuruh kamu membawa Dockerfile sendiri untuk ketiganya. Itu jawaban yang jujur, tapi artinya janji zero config punya batas bahasa, dan sebaiknya kamu pastikan berada di sisi mana sebelum merencanakan migrasi.
Ini jebakannya, dan ini bukan kesalahan Helipod. Sebuah deployment dashboard menampilkan environment variables seolah-olah semuanya setelan runtime: satu tab, satu kolom teks, tombol Save, tombol Restart. Next.js tidak memperlakukan semuanya begitu. Variable dengan prefix NEXT_PUBLIC_ di-inline ke dalam JavaScript bundle saat next build berjalan, jadi nilai yang diterima browser sudah dibekukan pada saat build dan tidak lagi hidup di environment.
Dokumentasi Next.js menyebutnya terang-terangan: setelah di-build, aplikasimu tidak akan lagi merespons perubahan pada environment variable tersebut. Mengubah nilai NEXT_PUBLIC_ di tab Variables lalu restart pod tidak mengubah apa pun, karena nilai lamanya sudah ikut ter-compile ke bundle yang kamu sajikan. Yang kamu butuhkan adalah build baru, yang di Helipod berarti redeploy. Set semua variable build-time sebelum deploy pertama, dan perlakukan perubahannya sebagai perubahan kode.
Kegagalan yang berkaitan sudah didokumentasikan Helipod dan sebaiknya kamu tahu sebelum mengalaminya. Helipack menambal config kamu untuk menambahkan standalone output, dan pada file config yang terlalu kompleks untuk ditambal ia menyerah dengan error yang bilang standalone tidak ditemukan. Solusinya adalah menyetelnya sendiri lalu commit — dan itu memang yang akan saya lakukan sejak deploy pertama, karena build yang bergantung pada regex orang lain menulis ulang config saya adalah build yang tidak bisa saya reproduksi di local.
Zero config itu default yang bagus dan plafon yang buruk. Escape hatch-nya satu file, helipack.json, di root repository, dan setiap key di dalamnya menimpa default Helipack. Ini hampir seluruh permukaan yang perlu kamu tahu untuk sebuah service Node:
// helipack.json, repository root. Every key overrides a Helipack default.
{
"run": {
"port": 3000,
"before": "npx prisma migrate deploy",
"after": "node scripts/warm-cache.js"
},
"health": {
"path": "/api/health",
"duration": 30
},
"packages": {
"apk": ["ffmpeg"]
},
"env": {
"TZ": "Asia/Jakarta",
"NODE_ENV": "production"
}
}Tiga key di antaranya punya sisi tajam. run.before itu gerbang, bukan saran: kalau command-nya keluar dengan exit code bukan nol, deployment dinyatakan gagal dan pod tidak pernah jalan, jadi langkah yang wajar saja gagal perlu ditambahi || true secara eksplisit. health.duration adalah masa tenggang sebelum health check dimulai dan default-nya 15 detik, yang tidak cukup untuk cold start yang menghangatkan cache atau memuat model — naikkan, atau pod kamu akan di-restart terus tanpa kamu sadari. Lalu build.dockerfile memungkinkan kamu menunjuk Dockerfile sendiri dan mematikan proses generate sepenuhnya, dan itulah jalan keluar kalau deteksi otomatisnya sudah tidak cukup. Kalau satu nilai disetel di lebih dari satu tempat, urutannya begini:
Urutan itu berguna, bukan kebetulan. Kamu bisa commit default development yang wajar berdampingan dengan kode, lalu menimpa hanya nilai production di dashboard, tanpa file config kedua dan tanpa percabangan di dalam aplikasi.

Harga dipublikasikan dalam Rupiah dan dihitung harian, dan plan-plan itu adalah tarif yang sama dijual dalam paket tiga puluh hari. Kolom yang paling penting justru yang terakhir, karena angka vCPU dan RAM sebuah plan adalah kuota bersama yang dibagi ke pod-pod kamu, sementara satu pod dibatasi empat vCPU, delapan GB RAM, dan tiga puluh GB storage — dengan ukuran container image ikut dihitung di dalam storage itu.
| Plan | Harga normal per bulan | vCPU / RAM bersama | Storage dan custom domain |
|---|---|---|---|
| Nano | Rp 123.750 | 1 vCPU / 1 GB | 15 GB, 2 domain |
| Micro | Rp 250.500 | 2 vCPU / 2 GB | 30 GB, 5 domain |
| Starter | Rp 672.000 | 5,5 vCPU / 5,5 GB | 80 GB, 10 domain |
| Pro | Rp 1.366.500 | 11 vCPU / 11 GB | 170 GB, 20 domain |
| Business | Rp 2.785.500 | 22 vCPU / 22 GB | 350 GB, 50 domain |
Tarif harian yang dipublikasikan di sebelah plan-plan itu adalah Rp 150 per 0,125 vCPU, Rp 200 per 128 MB RAM, Rp 75 per GB storage, dan Rp 100 per custom domain. Kalikan Nano — delapan unit CPU, delapan unit RAM, lima belas GB, dua domain — dan hasilnya Rp 4.125 per hari, yang tepat Rp 123.750 untuk tiga puluh hari. Hitungan yang sama juga jatuh persis pada angka publikasi Micro dan Starter. Jadi plan bukan diskon atas pay-as-you-go: plan adalah tiga puluh hari pay-as-you-go dengan tarif identik. Saat saya melihat, situsnya juga sedang memasang potongan setengah harga untuk paket satu bulan, dan itu promo, bukan harga normal — tabel di atas adalah harga normal.
Penagihannya berupa saldo prabayar, bukan invoice. Kamu top up dari panel billing lewat QRIS, transfer bank, virtual account, atau e-wallet langsung, mulai dari Rp 10.000, QR code-nya kedaluwarsa setelah sepuluh menit, dan saldonya dipotong setiap hari. QRIS adalah fakta yang membuat platform ini relevan: satu standar QR nasional yang diterima semua wallet dan bank di Indonesia berarti GoPay, OVO, Dana, atau ShopeePay sudah cukup, tanpa kartu dan tanpa kurs yang harus kamu jelaskan ke bagian keuangan. Konsekuensinya, top up jadi bagian dari urusan uptime. Tidak ada dokumen yang saya baca menjelaskan apa yang terjadi pada pod yang sedang jalan ketika saldo habis, jadi saya lebih memilih menyisakan buffer beberapa minggu dan satu reminder di kalender daripada mengetahuinya secara empiris.
Ini bagian yang tidak akan diberitahu halaman vendor, jadi saya tulis di sini. Empat hal tentang Helipod masih belum jelas setelah saya membaca semua yang mereka publikasikan:
# Two ways to read the Dockerfile Helipack wrote for you.
# 1. Deployments -> Build logs in the dashboard, where it is printed.
# 2. On a local build, ask Helipack to leave it on disk:
export HELIPACK_KEEP_DOCKERFILE=1
# ...then build. The file is kept as .helipack.Dockerfile in the repo root.
# Nothing published states which datacentre your pod lands in, so measure it
# from the network your users are on — a phone tether in Semarang, not your
# office fibre. Run it a dozen times before you trust the number.
curl -s -o /dev/null \
-w "dns %{time_namelookup} tls %{time_appconnect} ttfb %{time_starttransfer} total %{time_total}\n" \
https://your-project.helipod.app/Sebelum menitipkan apa pun ke platform yang region-nya tidak dipublikasikan, deploy satu pod hello-world dan ukur dari jaringan yang benar-benar dipakai pengguna kamu. Time to first byte dari HP dengan data seluler di Surabaya adalah angka yang penting, dan tesnya cuma lima menit tapi umurnya lebih panjang daripada klaim marketing mana pun soal kedekatan lokasi.

Batas yang jujur bukan soal kemampuan, tapi soal siapa yang memegang pager. Di platform terkelola, kamu menukar kemampuan memperbaiki sendiri dengan kenyamanan tidak perlu memperbaiki. Empat jenis workload yang tidak akan saya tukar seperti itu:
Untuk sisanya — front end Next.js, sebuah API, environment staging, preview per branch, tool internal yang tidak ada orang mau mengurusnya — pertukarannya menguntungkan, dan alasan untuk memakai VPS makin lemah setiap kali ada sertifikat yang harus diperbarui jam tiga pagi.
Aturan saya setelah membaca semuanya: Helipod adalah jawaban yang tepat ketika kendala utamanya adalah pembayaran atau perhatian, dan jawaban yang salah ketika kendalanya adalah kontrol. Penagihan QRIS dan Dockerfile yang tidak perlu kamu tulis menyelesaikan dua masalah nyata yang tidak diselesaikan platform mana pun yang menagih dalam Dollar bagi developer Indonesia. Pastikan variable build-time selesai sebelum deploy pertama, baca Dockerfile hasil generate Helipack supaya kamu tahu isi image kamu, dan ukur sendiri latency-nya alih-alih percaya pada bendera di landing page.
Sumber dan bacaan lanjutan