Cepat atau lambat, setiap program perlu diberi tahu beberapa hal: di mana letak sebuah berkas, database mana yang harus dihubungi, mode apa yang sedang dijalankan, password rahasianya apa. Kamu bisa saja menulis semua itu langsung di dalam kode — tapi begitu kamu melakukannya, programmu jadi terpaku ke satu susunan tertentu. Pindahkan ke mesin lain, dia langsung rusak. Environment variable adalah jawaban standar untuk masalah ini, dan di server Linux kamu bakal terus-menerus berurusan dengannya.
Idenya kecil, tapi hasilnya besar. Environment variable cuma sebuah nilai bernama yang hidup di sekitar program yang berjalan, bukan di dalam kode sumbernya. Begitu kamu paham cara mengaturnya, dari mana asalnya, dan bagaimana sebuah proses sebenarnya membacanya, banyak sekali urusan konfigurasi server yang berhenti terasa misterius.
Environment variable itu sebenarnya apa
Environment variable adalah pasangan NAMA=nilai yang dijaga oleh sistem operasi agar tersedia untuk program-program yang berjalan. Setiap proses di sistem Linux membawa sebuah kamus kecil berisi pasangan-pasangan ini — itulah environment-nya. Saat sebuah program mulai, dia bisa mencari nama mana pun di kamus itu lalu membaca nilainya.
Itu saja konsepnya. Sebuah nama, sebuah nilai, dan sebuah proses yang bisa membacanya:
ENVIRONMENT (sekumpulan pasangan nama=nilai)
┌─────────────────────────────────────┐
│ HOME=/home/jane │
│ PATH=/usr/local/bin:/usr/bin:/bin │
│ LANG=en_US.UTF-8 │
│ APP_ENV=production │
│ DATABASE_URL=postgres://... │
└─────────────────────────────────────┘
│
▼
program yang berjalan
membaca nilai yang dia butuhkan
Berdasarkan kebiasaan, nama environment variable ditulis dengan UPPER_SNAKE_CASE — semua huruf besar, antar-kata disambung garis bawah. Ini bukan aturan yang dipaksakan sistem, tapi semua orang mengikutinya, jadi nama seperti DATABASE_URL langsung kebaca sebagai “ini sebuah environment variable.”
Nilainya selalu berupa teks. Tidak ada angka, boolean, atau daftar dalam pandangan environment — cuma teks. Program yang ingin sebuah angka membaca teks "8080" lalu mengubahnya sendiri menjadi angka.
Kenapa mereka ada: memisahkan config dari kode
Alasan sebenarnya kenapa environment variable penting adalah sebuah prinsip yang layak diucapkan lantang: konfigurasi seharusnya hidup di luar kode. Program yang sama persis, byte demi byte, mestinya bisa berjalan di laptopmu, di server uji, dan di production — dan berperilaku benar di tiap tempat — tanpa mengubah satu baris pun. Yang berbeda di tiap tempat itu konfigurasinya, dan environment-lah tempat konfigurasi itu disimpan.
Bayangkan sebuah aplikasi web yang butuh koneksi database. Di laptopmu dia bicara ke database lokal; di production dia bicara ke database sungguhan dengan password sungguhan. Kalau string koneksinya ditanam di kode, kamu harus menyimpan dua versi program yang berbeda — itu resep untuk salah kirim versi. Sebagai gantinya, kode tinggal membaca sebuah variabel:
satu program, di mana saja
─────────────────────────────────────────
laptop DATABASE_URL = postgres://localhost/dev
uji DATABASE_URL = postgres://test-db/app
production DATABASE_URL = postgres://prod-db/app
Kode yang sama, tiga environment, nol perubahan. Itulah keuntungannya. Cara ini juga menjaga rahasia — password, API key — tetap di luar berkas sumbermu, yang memang sama sekali bukan tempatnya. Sebuah rahasia yang ikut tertanam di kode adalah rahasia yang bocor ke semua orang yang bisa membaca kode itu.
Environment variable tidak dienkripsi
Salah paham yang umum: menaruh password di environment variable tidak mengenkripsi atau menyembunyikannya. Nilainya tetap teks polos, bisa dibaca oleh prosesnya dan sering kali oleh siapa pun yang bisa memeriksa proses itu atau membaca berkas tempat kamu menyimpannya. Environment variable menjaga rahasia tetap di luar codebase dan version control — yang itu sungguh berharga — tapi di server itu sendiri kamu tetap melindunginya dengan izin berkas dan akses yang dibatasi, sama seperti kamu melindungi berkas sensitif lainnya.
Bagaimana sebuah proses mendapat environment-nya
Inilah bagian yang mengikat semuanya: sebuah proses mewarisi environment dari apa pun yang menjalankannya. Saat satu program meluncurkan program lain, anaknya menerima salinan environment milik induknya. Salinan itu berdiri sendiri — si anak bisa mengubah variabelnya sendiri tanpa memengaruhi induknya.
Rantai pewarisan inilah yang membuat shell-mu begitu penting. Saat kamu login, sebuah shell mulai dengan sebuah environment. Setiap perintah yang kamu jalankan dari shell itu adalah proses anak yang mewarisi salinannya. Jadi variabel yang kamu lihat di shell adalah variabel yang bakal dilihat perintah-perintahmu juga.
init / sistem
│ (menyiapkan environment dasar)
▼
shell login kamu
│ (mewarisinya, mungkin menambah)
▼
perintah yang kamu jalankan ← dapat salinan
│
▼
program apa pun yang dia luncurkan ← dapat salinan dari ITU
Karena tiap tingkat mendapat salinan, perubahan yang dibuat jauh di bawah tidak pernah merambat naik. Skrip yang menyetel sebuah variabel untuk dirinya sendiri tidak mengotori shell yang menjalankannya. Aliran satu arah ini justru yang kamu inginkan — membuat segalanya bisa ditebak.
Shell variable vs. variabel yang di-export
Inilah satu titik kebingungan paling umum, jadi mari kita tegaskan. Di dalam shell sebenarnya ada dua jenis variabel, dan bedanya adalah apakah proses anak bisa melihatnya.
Sebuah shell variable biasa hanya ada di dalam shell saat ini. Kamu menyetelnya seperti ini:
GREETING="halo"
echo "$GREETING" # mencetak: halo
Itu jalan, tapi GREETING bersifat pribadi untuk shell ini. Kalau kamu menjalankan program lain, dia sama sekali tidak melihat GREETING — variabel itu tidak pernah ditambahkan ke environment yang disalin ke anak-anaknya.
Supaya sebuah variabel menjadi bagian dari environment — agar proses anak mewarisinya — kamu export dia:
export GREETING="halo"
Sekarang GREETING adalah environment variable sungguhan. Perintah apa pun yang kamu jalankan setelah ini bakal menemukannya. Kamu juga bisa melakukannya dalam dua langkah, atau meng-export variabel yang sudah ada:
APP_ENV="production" # masih shell variable
export APP_ENV # sekarang dia ada di environment
Model berpikirnya: shell variable itu seperti catatan tempel di mejamu sendiri; meng-export-nya berarti menempelkan catatan itu ke dinding tempat semua orang yang lewat bisa membacanya.
Setel variabel untuk satu perintah saja
Kamu tidak selalu butuh perubahan permanen. Kamu bisa menambahkan sebuah variabel di depan satu perintah, dan itu berlaku hanya untuk satu kali jalan tersebut:
APP_ENV=production node server.jsDi sini APP_ENV disetel di environment proses node itu saja. Begitu perintahnya selesai, dia hilang — shell-mu tidak pernah punya APP_ENV sama sekali. Ini pas banget untuk tugas sekali pakai saat kamu tidak ingin meninggalkan setting berserakan.
Membaca dan memeriksa variabel
Untuk membaca satu variabel di shell, taruh $ di depan namanya. Untuk melihat semua yang sedang ada di environment-mu, ada beberapa perintah yang membantu:
echo "$HOME" # cetak nilai satu variabel
printenv PATH # cetak satu variabel, tanpa perlu $
printenv # tampilkan semua variabel yang di-export
env # ide yang sama — buang seluruh isi environment
printenv dan env hanya menampilkan variabel yang di-export — yaitu environment sungguhan. Kalau kamu menyetel sebuah shell variable biasa dan dia tidak muncul di printenv, itu petunjuk bahwa dia belum di-export dan program anak tidak bisa melihatnya. Perintah set (di bash) menampilkan shell variable juga, dan ini berguna saat kamu menelusuri kenapa sesuatu “tidak ada di situ”.
Tanda kutip itu penting saat kamu membaca sebuah nilai. Selalu bungkus $VAR dengan tanda kutip ganda — "$VAR" — ketika memakainya. Kalau nilainya mengandung spasi dan kamu lupa tanda kutipnya, shell memecahnya jadi beberapa potong dan kamu mendapat error yang membingungkan. Ini salah satu kebiasaan yang menyelamatkanmu dari berjam-jam pusing.
Variabel yang bakal kamu temui di mana-mana
Linux datang dengan sekumpulan environment variable standar yang hampir semuanya bergantung padanya. Beberapa yang layak langsung kamu kenali:
PATH— daftar direktori yang dipisah titik dua, tempat shell mencari saat kamu mengetik sebuah perintah. Saat kamu menjalankangit, shell menyusuri tiap direktori diPATHsampai menemukan program bernamagit. Kalau sebuah perintah “tidak ditemukan”, entriPATHyang hilang sering kali jadi penyebabnya.HOME— path ke direktori rumahmu, seperti/home/jane. Banyak program menyimpan config dan datanya relatif terhadapHOME.USER— nama user yang sedang aktif.SHELL— path ke shell login-mu.LANG/LC_*— setting bahasa dan locale (format tanggal, encoding karakter, urutan pengurutan).PWD— direktori kerja saat ini, selalu diperbarui saat kamu berpindah-pindah.TZ— zona waktu, ketika disetel.
PATH adalah yang paling sering kamu sentuh. Saat kamu memasang sebuah alat dan shell tidak bisa menemukannya, solusinya biasanya menambahkan direktorinya ke PATH:
export PATH="/opt/myapp/bin:$PATH"
Perhatikan triknya: kita taruh direktori baru paling depan, lalu menyambung PATH lama dengan $PATH. Itu mempertahankan semua yang sudah ada dan cuma menambahkannya di depan.
Membuat variabel bertahan: sementara vs. permanen
Semua yang kita lakukan sejauh ini hanya bertahan selama shell saat ini hidup. Tutup terminal atau logout, dan semua export tadi lenyap. Sering kali itu tidak masalah — kadang kamu memang ingin sebuah setting bersifat sementara. Tapi untuk konfigurasi yang dibutuhkan server setiap kali dia mulai, kamu butuh variabel itu bertahan.
Cara tradisionalnya adalah menaruh baris-baris export-mu di sebuah berkas startup shell yang dijalankan tiap kali shell dimulai. Untuk shell login yang interaktif, biasanya itu ~/.bashrc atau ~/.profile (berkas pastinya tergantung shell dan cara dia diluncurkan). Tambahkan baris seperti:
export EDITOR="nano"
…dan dia bakal tersetel di setiap shell baru sejak saat itu. Ini bagus untuk setting interaktif milikmu sendiri.
Tapi untuk proses server yang berjalan lama, mengandalkan berkas startup pribadi itu rapuh. Sebuah service yang dijalankan sistem saat boot tidak membaca ~/.bashrc-mu — dia bukan shell login, dan bahkan mungkin tidak berjalan sebagai dirimu. Pola yang lebih bersih untuk konfigurasi aplikasi adalah memberi prosesnya environment secara eksplisit: definisikan variabelnya di definisi service yang meluncurkannya, atau muat dari sebuah berkas config khusus saat proses mulai. Prinsipnya sama; kamu cuma memilih dari mana pasangan NAMA=nilai itu datang berdasarkan siapa yang menjalankan programnya.
Jangan commit berkas rahasiamu
Kebiasaan yang populer adalah menyimpan konfigurasi di sebuah berkas (sering dinamai .env) berisi baris-baris KEY=value, lalu memuatnya ke environment saat aplikasi mulai. Pola ini bagus — dengan satu aturan besi: jangan pernah commit berkas itu ke version control. Hampir selalu berkas itu berisi rahasia. Masukkan dia ke daftar abaikan, simpan sebuah .env.example aman berisi nilai contoh sebagai dokumentasi, dan taruh berkas aslinya hanya di mesin yang membutuhkannya, dilindungi izin berkas yang ketat. Banyak kebocoran data berawal dari berkas rahasia yang tanpa sengaja terdorong ke repositori publik.
Contoh nyata langkah demi langkah
Mari kita rangkai semuanya dengan sebuah sesi kecil. Bayangkan Jane sedang menyiapkan sebuah proses server secara manual untuk mengujinya:
# belum disetel apa-apa — output kosong
printenv APP_ENV
# setel, tapi cuma sebagai shell variable (belum di-export)
APP_ENV="staging"
printenv APP_ENV # masih kosong — anak tidak bisa melihatnya!
# sekarang export dia
export APP_ENV
printenv APP_ENV # staging
# aplikasi, diluncurkan dari shell ini, mewarisi APP_ENV
node server.js # di dalam aplikasi, APP_ENV terbaca "staging"
# timpa untuk satu kali jalan saja, tanpa mengubah shell
APP_ENV=production node server.js # jalan ini melihat "production"
printenv APP_ENV # kembali ke "staging" — timpaan tadi bersifat lokal
Tiap baris di sini adalah satu ide dari atas yang sedang bekerja: batas export, pewarisan ke proses anak, dan timpaan satu-perintah yang membiarkan shell tetap utuh. Begitu tarian kecil ini terasa alami, konfigurasi di server berhenti jadi tebak-tebakan.
Kenapa ini penting di server
Di laptopmu sendiri kamu mungkin masih bisa lolos dengan setting yang ditanam langsung, karena cuma ada satu kamu dan satu mesin. Di server, environment variable jadi hal pokok. Lewat merekalah artefak yang sama bisa di-deploy dan berjalan di staging maupun production, rahasia tetap di luar codebase, dan proses yang berjalan sebagai service mendapat persis konfigurasi yang dia butuhkan tanpa ada orang yang mengedit berkas dengan tangan. Hampir setiap alur deployment modern — dari satu VPS sampai sederet container — bersandar pada mekanisme sederhana NAMA=nilai yang satu ini.
Kalau kamu sudah cukup nyaman di command line Linux, environment variable adalah lapisan kendali berikutnya: bukan cuma menjalankan perintah, tapi membentuk dunia tempat perintah-perintah itu berjalan. Dan karena tiap user di sebuah server punya environment-nya sendiri, variabel yang sama bisa menyimpan nilai berbeda untuk user berbeda — satu alasan lagi kenapa mekanisme ini menskala dengan rapi.
Penutup
Ini gambaran utuhnya dalam satu tempat:
- Environment variable adalah pasangan
NAMA=nilaiyang dijaga OS agar tersedia untuk program yang berjalan; nilainya selalu teks, dan namanya ditulisUPPER_SNAKE_CASEberdasarkan kebiasaan. - Mereka ada untuk memisahkan konfigurasi dari kode — program yang sama berjalan di mana saja, dengan cuma environment-nya yang berubah — dan untuk menjaga rahasia tetap di luar berkas sumbermu.
- Sebuah proses mewarisi salinan environment induknya; perubahan mengalir satu arah, dari induk ke anak, tidak pernah balik naik.
- Shell variable biasa bersifat pribadi untuk shell saat ini; kamu
exportdia agar menjadi bagian dari environment yang diwarisi anak-anaknya. - Baca variabel dengan
$NAMA,printenv, danenv;PATH,HOME, sertaUSERadalah yang standar dan bakal terus kamu lihat. - Setel sementara di sebuah shell atau per perintah, atau permanen lewat berkas startup atau konfigurasi service itu sendiri — dan jangan pernah commit berkas rahasia ke version control.
Berikutnya, ada baiknya kita lihat bagaimana sebenarnya kamu menjangkau sebuah server untuk menyetel semua ini — menyambung dengan aman dari mesinmu ke mesin jauh lewat SSH, alat yang jadi rumah setiap administrator server.