Untuk pemula gaptek — ada gambar di tiap langkah
Deploy web dengan banyak environment variable
Banyak aplikasi web butuh lebih dari satu rahasia: alamat database, kunci API, secret login, kredensial email, dan lain-lain. Panduan ini melanjutkan tutorial deploy ke VPS dan fokus pada cara menata semua variabel itu dengan rapi dan aman.
Tertata rapi
Kelompokkan puluhan variabel agar mudah dibaca.
Aman
Rahasia tidak pernah ikut ter-commit ke GitHub.
Mudah di-update
Ganti secret & muat ulang tanpa downtime.
Kenali environment variable yang dibutuhkan
Environment variable adalah pengaturan rahasia/khusus yang dibaca aplikasi saat berjalan — misalnya alamat database atau kunci API. Tiap baris berbentuk NAMA=nilai. Sebelum deploy, daftar dulu semua yang dipakai aplikasimu. Biasanya tertulis di README atau di file .env.example.
Pastikan rahasia tidak ikut ter-commit
Pertama, tambahkan file .env ke .gitignore di proyekmu supaya Git mengabaikannya. Ini langkah paling penting — sekali secret bocor ke GitHub, anggap sudah bocor selamanya.
# .gitignore
.env
.env.local
.env.*.local
node_modules
.nextCek dari komputermu bahwa .env memang sudah diabaikan sebelum melakukan push:
kamu@laptop:~/webapp$ git status --ignoredIgnored files: (use "git add -f <file>..." to include) .env # bagus — .env muncul di daftar Ignored, bukan UntrackedSiapkan .env.example sebagai cetak biru
Buat file .env.example yang berisi semua nama variabel tapi tanpa nilai rahasia. File ini boleh di-commit dan berguna sebagai "daftar belanja": nanti di server kamu tinggal menyalinnya dan mengisi nilainya. Kelompokkan dengan komentar agar rapi.
# .env.example — TEMPLATE (boleh di-commit, TANPA nilai rahasia)
# --- Aplikasi ---
NODE_ENV=production
PORT=3000
APP_URL=https://domainkamu.com
# --- Database (Postgres) ---
DATABASE_URL=postgres://user:password@host:5432/namadb
# --- Autentikasi ---
AUTH_SECRET=
SESSION_MAX_AGE=604800
# --- Layanan pihak ketiga ---
STRIPE_SECRET_KEY=
RESEND_API_KEY=
OPENAI_API_KEY=AUTH_SECRET dan STRIPE_SECRET_KEY sengaja dikosongkan. Yang dibagikan hanya kerangkanya, bukan isinya.Buat file .env asli di VPS
Sekarang masuk ke VPS lewat SSH (lihat panduan utama), lalu masuk ke folder aplikasi dan salin template menjadi file .env asli:
deploy@vps:~$ cd ~/webappdeploy@vps:~$ cp .env.example .envdeploy@vps:~$ nano .env # isi setiap nilai, lalu Ctrl+O untuk simpan, Ctrl+X keluarDi dalam editor, isi nilai sebenarnya. Kelompokkan dengan komentar yang sama seperti template agar mudah dibaca walau variabelnya banyak:
1# --- Aplikasi ---2NODE_ENV=production3PORT=30004APP_URL=https://domainkamu.com5 6# --- Database ---7DATABASE_URL=postgres://blog:R4hasi4@localhost:5432/blogdb8 9# --- Autentikasi ---10AUTH_SECRET=Hxk9c2... (hasil generate di langkah 5)11SESSION_MAX_AGE=60480012 13# --- Layanan pihak ketiga ---14STRIPE_SECRET_KEY=sk_live_51Nabc...15RESEND_API_KEY=re_8sQ...16OPENAI_API_KEY=sk-proj-...= dan jangan pakai tanda kutip kecuali nilainya mengandung spasi. Tulis PORT=3000, bukan PORT = 3000.Generate secret yang benar-benar acak
Untuk nilai seperti AUTH_SECRET, jangan mengarang sendiri ("rahasia123"). Buat string acak yang panjang langsung di server dengan satu perintah, lalu tempelkan hasilnya ke .env:
deploy@vps:~$ openssl rand -base64 32Hxk9c2QvN0p7m3R8tY1aLz6kPq...VbQwE= # salin baris hasilnya ke AUTH_SECRET di file .envMuat semua env lewat PM2
Daripada mengetik puluhan variabel satu per satu, beri tahu PM2 untuk membaca seluruh file .env sekaligus. Buat file ecosystem.config.js di folder aplikasi:
// ecosystem.config.js — PM2 membaca env dari file ini
module.exports = {
apps: [
{
name: 'webapp',
script: 'pnpm',
args: 'start',
cwd: '/home/deploy/webapp',
// muat semua variabel dari file .env di server
env_file: '.env',
// (opsional) override / tambahan langsung di sini
env: {
NODE_ENV: 'production',
},
},
],
}Dengan env_file: '.env', semua variabel tadi otomatis tersedia untuk aplikasimu — tidak perlu disebut satu-satu.
Jalankan aplikasi & pastikan env terbaca
Jalankan aplikasi memakai file konfigurasi tadi, simpan agar otomatis hidup saat server reboot, lalu cek bahwa variabelnya benar-benar dimuat:
deploy@vps:~$ pm2 start ecosystem.config.js[PM2] Applying action restartProcessId on app [webapp][PM2] App [webapp] launched (1 instances)deploy@vps:~$ pm2 save[PM2] Saving current process list... deploy@vps:~$ pm2 env 0NODE_ENV: productionDATABASE_URL: postgres://blog:****@localhost:5432/blogdbAUTH_SECRET: Hxk9c2****STRIPE_SECRET_KEY: sk_live_****pm2 env 0 menampilkan semua env yang dilihat proses nomor 0. Kalau ada variabel yang kosong atau hilang, periksa lagi ejaan namanya di .env.Update atau ganti secret tanpa downtime
Suatu saat kamu perlu mengganti API key atau menambah variabel baru. Caranya: edit .env, lalu muat ulang PM2 dengan flag --update-env supaya nilai terbaru ikut terbaca.
deploy@vps:~$ nano .env# ubah nilai yang perlu, simpandeploy@vps:~$ pm2 reload webapp --update-envUse --update-env to update environment variables[PM2] Reloading process 0[PM2] webapp reloaded — env diperbaruiAgar tiap deploy selalu memuat env terbaru, masukkan baris reload itu ke dalam skrip deploy.sh kamu:
#!/usr/bin/env bash
set -e
cd ~/webapp
git pull
pnpm install
pnpm build
# muat ulang sambil update variabel env terbaru
pm2 reload ecosystem.config.js --update-env
echo "Deploy berhasil — env terbaru sudah dimuat!"Masalah umum & solusinya
| Gejala | Penyebab & solusi |
|---|---|
| Aplikasi error "undefined" saat akses variabel | Variabel belum terbaca. Jalankan pm2 reload webapp --update-env, dan cek ejaan nama di .env. |
| Perubahan .env tidak berefek | PM2 masih pakai nilai lama. Selalu tambahkan flag --update-env saat reload. |
| Nilai dengan spasi terpotong | Bungkus dengan tanda kutip: PESAN="Halo dunia". |
| Secret tidak sengaja ter-push ke GitHub | Anggap bocor: ganti semua key terkait sekarang, lalu pastikan .env ada di .gitignore. |
| Env beda untuk staging & produksi | Pakai file terpisah seperti .env.production dan tunjuk env_file ke file yang sesuai. |
Selesai! Aplikasimu kini berjalan dengan puluhan environment variable yang tertata rapi, aman dari GitHub, dan mudah di-update kapan saja.