Cara Setup Dev Environment Lokal yang Bersih
Kamu pernah ngalamin ini: laptop baru, semangat setup project, terus tiga bulan kemudian environment-nya udah kayak kapal pecah. Python 3.9 bentrok sama 3.11, Node versinya entah dari mana, dan setiap kali npm install muncul error yang berbeda-beda. Ujungnya? Reinstall OS. Lagi.
Gue udah ngalamin siklus itu terlalu sering sampai akhirnya muak dan nyari cara yang lebih sistematis. Artikel ini adalah hasil dari trial-and-error bertahun-tahun — cara setup dev environment lokal yang bisa kamu replikasi di mesin baru dalam waktu di bawah satu jam.
Masalah Utama: Environment yang Tidak Reproducible
Root cause dari environment berantakan biasanya satu: instalasi ad-hoc. Kamu install tool A karena tutorial bilang begitu, tool B karena butuh sekarang, dan enam bulan kemudian kamu nggak ingat kenapa ada binary aneh di /usr/local/bin.
Solusinya bukan pakai lebih banyak tool — tapi punya satu sumber kebenaran untuk semua dependency di mesin kamu. Kita akan pakai kombinasi:
- mise (pengganti nvm, pyenv, rbenv — satu tool untuk semua runtime)
- Docker untuk service (database, Redis, dll) supaya nggak polusi sistem
- direnv untuk environment variable per-project
- Dotfiles di Git supaya setup bisa diulang
Step 1: Install mise untuk Manage Runtime
mise (baca: "meez") adalah runtime version manager yang handle Node, Python, Ruby, Go, dan puluhan runtime lain dari satu CLI. Bye nvm, bye pyenv.
# Install mise
curl https://mise.run | sh
# Tambah ke shell (contoh untuk zsh)
echo 'eval "$(~/.local/bin/mise activate zsh)"' >> ~/.zshrc
source ~/.zshrc
# Verifikasi
mise --version
Setelah itu, install runtime yang kamu butuhkan:
# Install Node LTS
mise use --global node@lts
# Install Python
mise use --global python@3.12
# Cek semua yang terinstall
mise list
Yang bikin mise beda: dia support file .mise.toml per-project. Jadi kalau satu project butuh Node 18 dan project lain butuh Node 20, mise handle itu otomatis waktu kamu cd ke foldernya.
# .mise.toml di root project kamu
[tools]
node = "20.11.0"
python = "3.11.8"
Commit file ini ke repo. Teammate kamu tinggal mise install dan langsung dapat versi yang sama.
Gotcha yang gue hit: Kalau kamu punya nvm atau pyenv yang masih aktif di .zshrc, mereka bisa konflik sama mise. Hapus atau comment dulu baris export NVM_DIR dan sejenisnya sebelum lanjut.
Step 2: Docker untuk Service Lokal
Jangan install PostgreSQL, MySQL, atau Redis langsung ke sistem. Pakai Docker. Alasannya simpel: kamu bisa spin up dan tear down service tanpa ninggalin jejak di sistem, dan bisa punya versi berbeda untuk project berbeda.
Install Docker Desktop (macOS/Windows) atau Docker Engine (Linux):
# Linux (Ubuntu/Debian)
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
# Logout dan login lagi supaya group apply
Untuk tiap project, buat docker-compose.yml di root folder:
# docker-compose.yml
services:
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: dev
POSTGRES_PASSWORD: dev
POSTGRES_DB: myapp_dev
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
postgres_data:
Jalankan dengan:
# Start service di background
docker compose up -d
# Cek status
docker compose ps
# Stop semua service
docker compose down
Data PostgreSQL persist di Docker volume, jadi nggak hilang waktu container di-restart. Kalau mau reset total, docker compose down -v.
Gotcha: Port conflict. Kalau kamu punya dua project yang sama-sama expose port 5432, salah satu bakal gagal start. Solusinya: pakai port berbeda di docker-compose.yml untuk tiap project, misalnya 5433 untuk project kedua.
Step 3: direnv untuk Environment Variable
Jangan hardcode credentials di code. Jangan juga taruh .env di Git (kecuali .env.example). Pakai direnv — tool yang otomatis load environment variable dari file .envrc waktu kamu masuk ke folder project.
# Install direnv
# macOS
brew install direnv
# Linux
curl -sfL https://direnv.net/install.sh | bash
# Tambah ke shell
echo 'eval "$(direnv hook zsh)"' >> ~/.zshrc
source ~/.zshrc
Buat file .envrc di root project:
# .envrc
export DATABASE_URL="postgresql://dev:dev@localhost:5432/myapp_dev"
export REDIS_URL="redis://localhost:6379"
export SECRET_KEY="local-dev-secret-jangan-pakai-di-production"
export DEBUG=true
Lalu allow direnv untuk baca file itu:
direnv allow .
Sekarang setiap kali kamu cd ke folder project, variable itu otomatis ter-load. Keluar dari folder, variable hilang. Bersih.
Tambahkan .envrc ke .gitignore, tapi commit .envrc.example dengan nilai placeholder supaya teammate tahu variable apa yang dibutuhkan:
# .envrc.example
export DATABASE_URL="postgresql://user:password@localhost:5432/dbname"
export REDIS_URL="redis://localhost:6379"
export SECRET_KEY="ganti-dengan-secret-kamu"
export DEBUG=true
Step 4: Struktur Folder yang Konsisten
Ini yang sering diremehkan. Kalau semua project kamu ada di tempat yang konsisten, tooling jadi lebih mudah dikonfigurasi dan kamu nggak buang waktu nyari file.
Struktur yang gue pakai:
~/
├── dev/
│ ├── work/ # project kantor atau client
│ │ └── project-a/
│ ├── personal/ # side project sendiri
│ │ └── project-b/
│ └── oss/ # kontribusi open source
│ └── some-lib/
├── dotfiles/ # konfigurasi yang di-Git
└── bin/ # script custom kamu
Semua project ada di ~/dev/. Gampang di-backup, gampang di-exclude dari backup, dan path-nya predictable.
Step 5: Dotfiles di Git
Ini yang bikin setup baru jadi cepat. Semua konfigurasi shell, editor, dan tool kamu taruh di satu repo Git.
File yang penting untuk di-track:
~/dotfiles/
├── .zshrc # atau .bashrc
├── .gitconfig
├── .gitignore_global
├── mise/
│ └── config.toml # global mise config
└── install.sh # script untuk symlink semua file
Contoh install.sh sederhana:
#!/usr/bin/env bash
set -e
DOTFILES_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Buat symlink untuk setiap file
ln -sf "$DOTFILES_DIR/.zshrc" "$HOME/.zshrc"
ln -sf "$DOTFILES_DIR/.gitconfig" "$HOME/.gitconfig"
ln -sf "$DOTFILES_DIR/.gitignore_global" "$HOME/.gitignore_global"
echo "Dotfiles linked!"
Push repo ini ke GitHub (private kalau ada credential di sana, meski sebaiknya nggak ada). Di mesin baru, tinggal:
git clone git@github.com:username/dotfiles.git ~/dotfiles
cd ~/dotfiles
bash install.sh
Dan kamu udah punya environment yang familiar.
Gotcha: Jangan taruh API key atau password di dotfiles yang di-push ke Git, bahkan repo private sekalipun. Pakai tool seperti pass atau 1Password CLI untuk secret management yang proper.
Bonus: Script Bootstrap untuk Mesin Baru
Kalau mau setup mesin baru lebih cepat lagi, buat satu script bootstrap yang install semua dependency dasar:
#!/usr/bin/env bash
# bootstrap.sh — jalankan sekali di mesin baru
set -e
echo "==> Installing Homebrew (macOS only)"
if [[ "$OSTYPE" == "darwin"* ]]; then
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
brew install git curl wget
fi
echo "==> Installing mise"
curl https://mise.run | sh
echo 'eval "$(~/.local/bin/mise activate zsh)"' >> ~/.zshrc
echo "==> Installing Docker (Linux)"
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker "$USER"
fi
echo "==> Installing direnv"
if [[ "$OSTYPE" == "darwin"* ]]; then
brew install direnv
else
curl -sfL https://direnv.net/install.sh | bash
fi
echo "==> Cloning dotfiles"
git clone git@github.com:username/dotfiles.git ~/dotfiles
cd ~/dotfiles && bash install.sh
echo "Done! Restart terminal kamu."
Simpan ini di repo dotfiles kamu juga. Lain kali ganti laptop, satu command dan kamu udah siap kerja.
Yang Gue Lakuin Sekarang
Setup yang gue describe di atas udah gue pakai lebih dari dua tahun di tiga laptop berbeda (dua Linux, satu macOS). Waktu setup mesin baru sekarang sekitar 45 menit — kebanyakan nunggu download, bukan nunggu gue mikir "ini tadi install apa ya".
Kalau kamu baru mulai, jangan langsung implement semuanya. Prioritas:
- Mulai dari mise — ini yang paling langsung solve masalah version conflict.
- Tambah Docker Compose ke project yang butuh database.
- Setup direnv waktu kamu mulai frustrasi manage
.envmanual. - Buat dotfiles repo setelah konfigurasi kamu mulai stabil.
Cara setup dev environment lokal yang baik bukan soal pakai tool paling canggih — tapi soal konsistensi dan reproducibility. Environment yang bisa kamu rebuild dalam satu jam jauh lebih berharga daripada environment yang "works on my machine" tapi nggak ada yang tahu kenapa. Untuk insights lebih lanjut tentang automation dan reproducibility, cara riset keyword Indonesia gratis bisa membantu kamu menemukan resources dan best practices yang relevan.
Kalau kamu stuck di salah satu step, drop di komentar. Gue baca semua.