Environment Variables Management Tools Terbaik

by Marcus Chen
Environment Variables Management Tools Terbaik

Pernah nggak kamu deploy ke production, terus app langsung crash karena DATABASE_URL nggak ke-set? Atau lebih parah: kamu nemu file .env lama di folder Downloads yang isinya credential production — plaintext, tanpa enkripsi, duduk manis di sana.

Itu bukan cerita horor fiksi. Itu workflow banyak developer, termasuk gue sendiri waktu masih naif.

Masalahnya bukan cuma soal keamanan. Manajemen environment variables yang buruk bikin hal-hal ini jadi rutin:

  • Onboarding developer baru butuh 2 jam cuma buat ngumpulin nilai .env yang benar
  • Nilai di local, staging, dan production beda tapi nggak terdokumentasi
  • Secret bocor ke Git karena seseorang lupa tambah .env ke .gitignore
  • App jalan di mesin kamu tapi error di mesin teman satu tim

Artikel ini bahas environment variables management tools yang benar-benar gue pakai atau evaluasi — dari yang paling sederhana sampai yang cocok buat tim kecil.


Kenapa .env Biasa Sudah Tidak Cukup

File .env dengan library seperti dotenv itu titik awal yang bagus. Tapi dia punya batas:

  1. Nggak ada enkripsi — siapapun yang punya akses ke filesystem bisa baca isinya
  2. Nggak ada versioning — kamu nggak tahu siapa yang ubah API_KEY kemarin
  3. Sinkronisasi manual — tiap developer harus minta nilai terbaru lewat Slack/WhatsApp
  4. Nggak ada audit trail — kalau ada kebocoran, susah trace-nya

Setup .env standar kamu mungkin terlihat begini:

# .env
DATABASE_URL=postgres://user:password@localhost:5432/mydb
API_KEY=sk-abc123
JWT_SECRET=supersecretkey
NODE_ENV=development

Dan kamu load di Node.js:

// index.js
require('dotenv').config();

const db = require('./db');
db.connect(process.env.DATABASE_URL);

Ini jalan. Tapi begitu project kamu punya lebih dari 2 environment (local, staging, production) dan lebih dari 1 developer, setup ini mulai kewalahan.


Tool 1: direnv — Otomatis Load per Direktori

direnv adalah shell extension yang otomatis load dan unload environment variables berdasarkan direktori yang kamu masuk. Nggak perlu source .env manual lagi.

Install di Ubuntu/Debian:

sudo apt install direnv

Tambah ke shell kamu (contoh untuk bash):

# ~/.bashrc
eval "$(direnv hook bash)"

Restart terminal, lalu di folder project kamu:

# Buat file .envrc (bukan .env)
echo 'export DATABASE_URL=postgres://user:pass@localhost/mydb' > .envrc
echo 'export API_KEY=sk-local-abc123' >> .envrc

# Allow direnv untuk folder ini
direnv allow .

Sekarang tiap kali kamu cd ke folder itu, variabelnya otomatis ke-load. Keluar dari folder, variabelnya hilang.

Gotcha yang gue temuin: File .envrc juga harus masuk .gitignore. Kalau kamu mau share template tanpa nilai asli, buat .envrc.example yang di-commit ke repo.

# .envrc.example
export DATABASE_URL=
export API_KEY=
export JWT_SECRET=

Kelebihan direnv: ringan, nggak butuh server, cocok buat solo developer. Kekurangannya: sinkronisasi antar developer tetap manual.


Tool 2: dotenvx — dotenv yang Punya Enkripsi

dotenvx dari pembuat dotenv original. Ini versi yang lebih serius: support enkripsi, multiple environment, dan bisa jalan di CI/CD.

Install:

npm install @dotenvx/dotenvx --save-dev
# atau global
npm install -g @dotenvx/dotenvx

Buat file .env per environment:

# .env.development
DATABASE_URL=postgres://localhost/mydb_dev
API_KEY=sk-dev-key

# .env.production
DATABASE_URL=postgres://prod-server/mydb
API_KEY=sk-prod-key

Enkripsi file production:

dotenvx encrypt -f .env.production

Output-nya akan mengubah .env.production jadi sesuatu seperti ini:

#/-------------------[DOTENV_PUBLIC_KEY]--------------------/
#/            public-key encryption for .env files          /
#/       [how it works](https://dotenvx.com/encryption)     /
#/-----------------------------------------------------------/
DOTENV_PUBLIC_KEY="03a1b2c3d4..."

# .env.production
DATABASE_URL="encrypted:BDD7...rest_of_encrypted_value"
API_KEY="encrypted:AEF3...rest_of_encrypted_value"

File yang sudah dienkripsi aman di-commit ke Git. Private key-nya disimpan terpisah (di .env.keys yang jangan di-commit).

Jalankan app dengan environment spesifik:

dotenvx run --env-file=.env.production -- node index.js

Atau di package.json:

{
  "scripts": {
    "start:dev": "dotenvx run --env-file=.env.development -- node index.js",
    "start:prod": "dotenvx run --env-file=.env.production -- node index.js"
  }
}

Gotcha: Private key ada di .env.keys. Pastikan file ini ada di .gitignore dan kamu backup di tempat aman (password manager, misalnya). Kalau hilang, kamu nggak bisa decrypt.

# .gitignore
.env.keys
.env.production
.env.staging

Tool 3: Infisical — Self-Hosted Secret Manager

Kalau kamu butuh solusi tim yang proper — dengan UI, audit log, dan sinkronisasi otomatis — Infisical adalah pilihan self-hosted yang paling mature saat ini.

Infisical bisa di-deploy di VPS kamu sendiri. Ini penting kalau kamu nggak mau secret perusahaan lewat server pihak ketiga.

Deploy dengan Docker Compose:

# Clone repo
git clone https://github.com/Infisical/infisical
cd infisical

# Copy dan edit config
cp .env.example .env
# Edit .env sesuai kebutuhan (database, domain, dll)

# Jalankan
docker compose -f docker-compose.prod.yml up -d

Setelah setup, kamu bisa inject secret langsung ke project via CLI:

# Install Infisical CLI
curl -1sLf 'https://dl.cloudsmith.io/public/infisical/infisical-cli/setup.deb.sh' | sudo bash
sudo apt install infisical

# Login
infisical login

# Init di project
infisical init

# Jalankan app dengan secret dari Infisical
infisical run -- node index.js

File infisical.json yang di-generate setelah init aman di-commit — dia cuma menyimpan project ID, bukan nilai secret-nya.

{
  "workspaceId": "abc123def456",
  "defaultEnvironment": "dev",
  "gitBranchToEnvironmentMapping": null
}

Fitur yang bikin Infisical worth it buat tim:

  • Secret versioning — bisa rollback ke versi sebelumnya
  • Audit log — siapa yang akses atau ubah secret kapan
  • Dynamic secrets — generate credential sementara (berguna untuk database)
  • Native integration dengan GitHub Actions, GitLab CI, Kubernetes

Gotcha dari pengalaman gue: Setup awal Infisical self-hosted butuh effort lebih. Minimal kamu perlu VPS dengan 2GB RAM. Kalau baru mulai solo, dotenvx lebih masuk akal dulu.


Tool 4: Doppler — Kalau Mau Cloud Tanpa Ribet Setup

Gue masukin ini karena banyak developer Indonesia yang nanya soal alternatif cloud. Doppler punya free tier yang cukup untuk project kecil.

Cara kerjanya mirip Infisical tapi hosted. Kamu define secret di dashboard, lalu inject ke app:

# Install Doppler CLI
curl -Ls https://cli.doppler.com/install.sh | sh

# Login dan setup
doppler login
doppler setup

# Jalankan app
doppler run -- node index.js

Kalau kamu pakai Docker:

# Dockerfile
FROM node:20-alpine

# Install Doppler CLI
RUN curl -Ls https://cli.doppler.com/install.sh | sh

WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .

CMD ["doppler", "run", "--", "node", "index.js"]

Catatan jujur: Doppler bagus, tapi kamu bergantung pada availability server mereka. Kalau mereka down, app kamu yang pakai doppler run saat startup juga bisa bermasalah. Selalu ada fallback strategy.


Perbandingan Cepat

Tool Enkripsi Self-hosted Tim Support Kompleksitas
direnv Rendah
dotenvx Terbatas Rendah
Infisical Tinggi
Doppler Sedang

Praktik Dasar yang Sering Dilupain

Tool apapun yang kamu pilih, beberapa hal ini tetap berlaku:

Selalu punya .env.example di repo:

# .env.example — file ini di-commit
DATABASE_URL=          # PostgreSQL connection string
API_KEY=               # External API key, minta ke tim
JWT_SECRET=            # Min 32 karakter random string
PORT=3000

Validasi environment variables saat startup, bukan saat dipakai. Pakai library seperti zod atau envalid:

// config.js
const { cleanEnv, str, port } = require('envalid');

const env = cleanEnv(process.env, {
  DATABASE_URL: str(),
  API_KEY: str(),
  JWT_SECRET: str({ docs: 'https://wiki.internal/secrets' }),
  PORT: port({ default: 3000 })
});

module.exports = env;

Kalau ada variabel yang kurang, app langsung crash dengan pesan error yang jelas — jauh lebih baik daripada crash saat request masuk.

Jangan hardcode nilai default yang sensitif:

// ❌ Jangan begini
const secret = process.env.JWT_SECRET || 'defaultsecret';

// ✅ Lebih baik begini
if (!process.env.JWT_SECRET) {
  throw new Error('JWT_SECRET harus di-set');
}
const secret = process.env.JWT_SECRET;

Yang Gue Lakuin Sekarang

Untuk project solo atau freelance kecil, gue pakai kombinasi direnv + dotenvx:

  • direnv untuk otomasi load di local development
  • dotenvx untuk enkripsi file .env.production yang bisa di-commit dengan aman

Untuk project dengan tim (meski kecil, 2-3 orang), gue setup Infisical di VPS yang sudah ada. Satu kali setup, audit log dan sinkronisasi jalan otomatis.

Langkah konkret yang bisa kamu mulai hari ini:

  1. Audit semua file .env di project kamu — ada yang ke-commit ke Git?
  2. Install dotenvx dan enkripsi file environment production kamu
  3. Buat atau update .env.example dengan dokumentasi tiap variabel
  4. Tambah validasi startup dengan envalid atau zod

Kalau kamu sudah di tahap itu dan butuh solusi tim yang proper, evaluasi Infisical. Docker Compose mereka cukup straightforward dan dokumentasinya bagus.

Environment variables management yang benar bukan overkill — itu hal yang kamu syukuri pas jam 2 pagi ketika production bermasalah dan kamu butuh trace perubahan config dari seminggu lalu.