Deploy Next.js ke VPS berarti menjalankan aplikasi di server milik sendiri
memakai Node.js, Nginx sebagai reverse proxy, dan proses manager seperti
systemd, alih-alih menyewa platform terkelola seperti Vercel. Caranya:
build dengan `output: "standalone"`, salin hasil build ke server, jalankan
lewat systemd, lalu pasang Nginx dan sertifikat TLS gratis dari Let's Encrypt.

**Ringkasan cepat:**

1. Build Next.js dengan `output: "standalone"` di `next.config.ts` untuk menghasilkan paket Node.js mandiri.
2. Salin manual folder `public/` dan `.next/static` ke `.next/standalone` - keduanya tidak otomatis disertakan.
3. Jalankan `server.js` hasil build lewat systemd atau PM2 agar tetap aktif dan otomatis restart setelah crash/reboot.
4. Pasang Nginx sebagai reverse proxy di depan Node.js (port 3000 tidak diekspos langsung ke internet).
5. Aktifkan TLS gratis dengan Certbot (Let's Encrypt), yang juga mengatur perpanjangan sertifikat otomatis.

## Kenapa Deploy Next.js ke VPS Sendiri, Bukan ke Vercel?

Alasan paling umum adalah kontrol biaya dan kontrol infrastruktur. Menurut
[dokumentasi resmi Vercel](https://vercel.com/docs/limits) (per Juli 2026), paket
Hobby dibatasi 100GB fast data transfer per bulan, 1 juta function
invocation per bulan, dan maksimal 100 deployment per hari. Begitu kuota
habis, dalam banyak kasus fitur akan dijeda sampai siklus billing
berikutnya. Paket berbayar (Pro) menaikkan batas ini tapi biayanya naik
seiring trafik.

> Paket Hobby Vercel dibatasi 100GB fast data transfer per bulan, 1 juta
> function invocation per bulan, dan maksimal 100 deployment per hari
> (dokumentasi resmi Vercel, per Juli 2026).

VPS sebaliknya punya struktur biaya flat per bulan tanpa peduli seberapa
besar trafik yang datang (selama masih dalam kapasitas server), sehingga
lebih dapat diprediksi untuk proyek jangka panjang dengan trafik yang terus
tumbuh. Trade-off-nya: semua hal yang biasanya otomatis di Vercel (TLS,
scaling, deployment pipeline) harus disiapkan manual.

<table>
  <thead>
    <tr>
      <th>Aspek</th>
      <th>VPS</th>
      <th>Vercel (paket Hobby)</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Struktur biaya</td>
      <td>Flat per bulan, tidak terikat kuota bandwidth</td>
      <td>Gratis sampai kuota, biaya naik seiring trafik di paket Pro</td>
    </tr>
    <tr>
      <td>Batas kuota</td>
      <td>Tidak ada batas bandwidth bawaan platform</td>
      <td>100GB fast data transfer/bulan, 1 juta function invocation/bulan, maks 100 deployment/hari</td>
    </tr>
    <tr>
      <td>Setup TLS, scaling, deployment</td>
      <td>Manual (Nginx, Certbot, systemd/PM2)</td>
      <td>Otomatis dikelola platform</td>
    </tr>
    <tr>
      <td>Paling cocok untuk</td>
      <td>Trafik menengah-tinggi, proyek jangka panjang</td>
      <td>Proyek kecil, prototipe cepat, tim tanpa waktu urus server</td>
    </tr>
  </tbody>
</table>

### Kapan Sebaiknya Tetap Pakai Vercel?

Untuk proyek kecil dengan trafik rendah, prototipe cepat, atau tim yang
tidak punya waktu mengurus server, Vercel (atau platform serupa) tetap
masuk akal karena menghilangkan seluruh beban operasional di bawah ini.
Deploy ke VPS baru sepadan ketika kontrol biaya jangka panjang atau
kebutuhan kustomisasi infrastruktur lebih penting daripada kenyamanan.

## Apa Itu Output "Standalone" dan Kenapa Penting untuk Deploy VPS?

`output: "standalone"` adalah opsi di `next.config.ts` yang membuat
`next build` menghasilkan paket Node.js mandiri di `.next/standalone`,
berisi hanya dependency yang benar-benar dipakai saat runtime, tanpa perlu
menyalin seluruh `node_modules` ke server produksi. Ini membuat ukuran
deployment jauh lebih kecil dibanding menyalin seluruh proyek.

Output standalone ini tetap berbeda dari [Build Adapters API yang
distabilkan Next.js 16.2](/blog/build-adapters-api-nextjs-untuk-non-vercel) -
adapter adalah kontrak integrasi untuk platform hosting membaca hasil
build secara terstruktur, sementara standalone adalah strategi packaging
minimal yang bisa langsung dijalankan dengan `node server.js` tanpa
adapter sama sekali, seperti yang dilakukan panduan ini.

Satu hal yang sering terlewat: Next.js **tidak** otomatis menyalin folder
`public/` dan `.next/static` ke dalam `.next/standalone`. Keduanya harus
disalin manual setelah build, atau aset statis dan gambar akan 404 di
production meski aplikasi tetap berjalan. Ini bukan bug, melainkan
perilaku yang didokumentasikan resmi di [dokumentasi Next.js soal opsi
`output`](https://nextjs.org/docs/app/api-reference/config/next-config-js/output):

> This minimal server does not copy the `public` or `.next/static` folders
> by default as these should ideally be handled by a CDN instead, although
> these folders can be copied to the `standalone/public` and
> `standalone/.next/static` folders manually, after which `server.js` file
> will serve these automatically.

## Bagaimana Cara Build dan Menyiapkan Next.js untuk VPS?

Urutan dasarnya:

```bash
npm ci
npm run build
cp -r public .next/standalone/public
cp -r .next/static .next/standalone/.next/static
```

Setelah itu, `.next/standalone` sudah berisi `server.js` yang bisa
dijalankan langsung dengan Node.js, tanpa perlu `next start` maupun
`node_modules` penuh:

```bash
cd .next/standalone
NODE_ENV=production PORT=3000 node server.js
```

Buka `http://<ip-vps>:3000` untuk memastikan server merespons sebelum
lanjut ke setup proses permanen.

### Variabel Environment

Next.js otomatis membaca `.env.production` saat `NODE_ENV=production`.
Untuk server standalone yang dijalankan lewat systemd atau PM2, environment
perlu diteruskan eksplisit lewat `EnvironmentFile` (systemd) atau
`--env-file` (PM2) karena proses tidak lagi berjalan dari direktori proyek
yang sama seperti saat development.

## Bagaimana Cara Menjalankan Next.js di VPS Secara Permanen dengan systemd?

Server yang dijalankan manual lewat `node server.js` akan mati begitu
terminal ditutup. Untuk produksi, proses ini perlu dikelola oleh systemd
(bawaan Linux) atau PM2 agar otomatis restart bila crash dan otomatis
menyala kembali setelah reboot server.

systemd dipakai sebagai contoh utama di panduan ini karena mayoritas VPS
yang dipakai untuk deploy aplikasi web memang berjalan di atas Linux —
sekitar 60% dari seluruh VPS secara global menggunakan Linux sebagai
sistem operasi (data Global Market Insights, dikutip [ScalaHosting,
2025](https://www.scalahosting.com/blog/vps-hosting-statistics/)), dan
systemd adalah process manager bawaan hampir semua distribusi Linux
modern (Ubuntu, Debian, CentOS/RHEL), sehingga tidak perlu instalasi
tambahan seperti PM2.

Contoh unit systemd minimal:

```ini
[Unit]
Description=Aplikasi Next.js
After=network.target

[Service]
Type=simple
User=www-data
WorkingDirectory=/var/www/nama-aplikasi
Environment=NODE_ENV=production
ExecStart=/usr/bin/node server.js
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
```

Aktifkan dengan:

```bash
sudo systemctl daemon-reload
sudo systemctl enable --now nama-aplikasi
```

Alternatif yang lebih mudah bagi yang belum familiar dengan systemd adalah
PM2 (`pm2 start server.js --name nama-aplikasi`), yang punya perintah
serupa (`pm2 save`, `pm2 startup`) untuk auto-start setelah reboot.

## Bagaimana Cara Setup Nginx sebagai Reverse Proxy dan TLS?

Node.js sebaiknya tidak diekspos langsung ke internet di port 3000. Nginx
berperan sebagai reverse proxy yang menerima trafik di port 80/443 lalu
meneruskannya ke aplikasi Node secara internal:

```nginx
server {
    listen 443 ssl http2;
    server_name domain-anda.com;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
```

Sertifikat TLS didapat gratis lewat Certbot (Let's Encrypt):

```bash
sudo certbot --nginx -d domain-anda.com
```

Certbot otomatis melengkapi konfigurasi `ssl_certificate` di atas dan
memasang penjadwalan perpanjangan otomatis, sehingga sertifikat tidak perlu
diperbarui manual setiap beberapa bulan.

## Ringkasan: Tiga Komponen Inti Deploy Next.js ke VPS

- Deploy Next.js ke VPS memakai tiga komponen inti: build `output: "standalone"`, proses manager (systemd/PM2) supaya server tetap hidup, dan Nginx sebagai reverse proxy plus TLS.
- Folder `public/` dan `.next/static` wajib disalin manual ke `.next/standalone` setelah build, karena Next.js tidak melakukannya otomatis.
- VPS cocok untuk trafik menengah-tinggi dengan biaya flat per bulan, sementara paket gratis Vercel dibatasi kuota bandwidth (100GB/bulan per 2026) yang bisa menghentikan situs sementara bila terlampaui.
- Situs ini sendiri (irfanramadhan.com) berjalan dengan pola yang sama: build standalone, systemd, dan Nginx reverse proxy di VPS. Butuh bantuan menyiapkan hal serupa? Lihat [layanan pengembangan web](/layanan) yang ditawarkan.
- Setelah situs live di VPS, langkah lanjutan yang sering terlewat adalah memastikan `sitemap.xml` dan `robots.txt` tetap dihasilkan benar dan bisa diakses crawler (termasuk crawler AI seperti GPTBot/ClaudeBot/PerplexityBot). Lihat [cara membuat sitemap.xml dan robots.txt dinamis di Next.js App Router](/blog/cara-membuat-sitemap-robots-txt-nextjs).
- Sitemap dan robots.txt membantu crawler menemukan dan mengakses halaman, tapi tidak menjelaskan isinya. Langkah pelengkap untuk membuat konten lebih mudah dipahami dan dikutip AI search engine adalah menambahkan structured data. Lihat [cara implementasi schema markup JSON-LD di Next.js](/blog/cara-implementasi-schema-markup-json-ld-nextjs).