Setup Development Environment Linux dari Nol

by Marcus Chen

Sebagian besar tutorial setup development environment Linux berhenti di sudo apt install build-essential. Selesai. Selamat, katanya, kamu sudah siap coding.

Kenyataannya? Tiga minggu kemudian kamu debug kenapa Python 3.10 bentrok dengan 3.12, Node versi proyek lama nolak jalan, dan dotfile kamu berserakan tanpa struktur. Saya pernah di sana. Artikel ini bukan tutorial "install ini terus install itu" — ini adalah opini saya tentang cara setup yang benar-benar bisa dipakai jangka panjang.

Kita akan bahas dari fondasi distro, manajemen versi runtime, shell yang produktif, sampai dotfile management. Semua berbasis pengalaman nyata, bukan copy-paste dari dokumentasi resmi.

Pilih Distro yang Tidak Akan Bikin Kamu Menyesal

Ubuntu LTS atau Debian stable. Titik.

Saya tahu ada yang mau debat soal Arch, NixOS, atau Fedora. Kalau kamu sudah punya opini kuat soal ini, kamu tidak butuh saran saya. Tapi kalau kamu baru setup environment serius untuk kerja, Ubuntu 24.04 LTS (Noble Numbat) adalah pilihan paling aman per 2024. Package repository-nya luas, StackOverflow penuh solusi, dan LTS berarti kamu tidak akan dipaksa upgrade di tengah sprint.

Debian 12 (Bookworm) juga solid — lebih konservatif, package-nya sedikit lebih tua, tapi stabil seperti batu. Saya pakai Debian di server self-hosted, Ubuntu di laptop development.

Satu hal yang sering diabaikan: pastikan kamu pakai 64-bit dan aktifkan enkripsi disk saat instalasi. LUKS full-disk encryption. Kalau laptop kamu hilang, kamu tidak perlu panik soal source code klien.

Fondasi: Package Manager dan Build Tools

Setelah instalasi bersih, langkah pertama bukan install IDE. Ini dulu:

sudo apt update && sudo apt upgrade -y
sudo apt install -y \
  build-essential \
  curl \
  wget \
  git \
  gnupg \
  ca-certificates \
  lsb-release \
  software-properties-common \
  apt-transport-https \
  unzip \
  jq \
  htop \
  tmux

build-essential itu paket meta yang isinya GCC, G++, Make, dan header Linux. Banyak tool yang compile dari source butuh ini. jq kelihatan sepele tapi kamu akan berterima kasih saat parsing JSON dari API di terminal. tmux — kita bahas nanti.

Untuk Homebrew di Linux (Linuxbrew): saya tidak rekomendasikan sebagai package manager utama. Tapi kalau ada tool tertentu yang versinya jauh lebih baru di Homebrew dibanding apt, boleh dipasang paralel. Jangan jadikan default.

Manajemen Versi Runtime: Jangan Pernah Install Langsung

Ini kesalahan terbesar yang saya lihat. Orang install Python via apt install python3, Node via apt install nodejs, terus bingung kenapa versinya ketinggalan atau bentrok antar proyek.

Aturannya sederhana: jangan pernah install runtime language secara global via apt untuk development. Pakai version manager.

Python: pyenv

curl https://pyenv.run | bash

Tambahkan ke ~/.bashrc atau ~/.zshrc:

export PYENV_ROOT="$HOME/.pyenv"
[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"

Restart shell, lalu:

pyenv install 3.12.3
pyenv global 3.12.3

Per proyek, buat file .python-version di root repo:

cd /path/to/project
pyenv local 3.10.14

pyenv otomatis switch versi saat kamu masuk direktori itu. Tidak ada lagi drama python3.10 vs python3.12.

Node.js: fnm (bukan nvm)

nvm sudah lama jadi standar, tapi lambat — dia inject dirinya ke setiap shell session dan bikin startup time terminal terasa berat. Saya switch ke fnm (Fast Node Manager) awal 2023 dan tidak pernah balik.

curl -fsSL https://fnm.vercel.app/install | bash

Tambahkan ke shell config:

eval "$(fnm env --use-on-cd)"

Flag --use-on-cd membuat fnm otomatis baca .node-version atau .nvmrc saat masuk direktori. Kompatibel dengan proyek lama yang pakai nvm.

fnm install 20
fnm use 20
fnm default 20

Go, Rust, dan Lainnya

Go: download tarball resmi dari golang.org, ekstrak ke /usr/local/go. Jangan pakai apt — versinya sering jauh ketinggalan.

wget https://go.dev/dl/go1.22.3.linux-amd64.tar.gz
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf go1.22.3.linux-amd64.tar.gz
export PATH=$PATH:/usr/local/go/bin

Rust: pakai rustup, tidak ada alternatif yang masuk akal.

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Shell yang Produktif: Zsh + Konfigurasi Minimal

Bash sudah cukup untuk scripting. Tapi untuk interactive shell sehari-hari, Zsh dengan konfigurasi yang tepat jauh lebih nyaman.

sudo apt install -y zsh
chsh -s $(which zsh)

Saya tidak pakai Oh My Zsh. Terlalu berat, terlalu banyak plugin yang tidak saya butuhkan, dan bikin shell startup lambat. Saya pakai pendekatan minimal:

Zinit sebagai plugin manager:

bash -c "$(curl --fail --show-error --silent --location \
  https://raw.githubusercontent.com/zdharma-continuum/zinit/HEAD/scripts/install.sh)"

Isi ~/.zshrc yang saya pakai (versi ringkas):

# Zinit
source ~/.local/share/zinit/zinit.git/zinit.zsh

# Plugin esensial
zinit light zsh-users/zsh-autosuggestions
zinit light zsh-users/zsh-syntax-highlighting
zinit light ajeetdsouza/zoxide

# History
HISTSIZE=10000
SAVEHIST=10000
setopt HIST_IGNORE_DUPS
setopt SHARE_HISTORY

# Prompt sederhana dengan git info
autoload -Uz vcs_info
precmd() { vcs_info }
zstyle ':vcs_info:git:*' formats ' (%b)'
setopt PROMPT_SUBST
PROMPT='%F{cyan}%~%f%F{yellow}${vcs_info_msg_0_}%f %# '

zoxide adalah pengganti cd yang belajar dari kebiasaan navigasi kamu. Setelah beberapa hari, ketik z proj dan dia langsung lompat ke direktori proyek yang paling sering kamu kunjungi.

tmux: Terminal Multiplexer yang Wajib Ada

Kalau kamu belum pakai tmux, ini yang kamu lewatkan: sesi yang persist meski terminal ditutup, split pane tanpa butuh terminal emulator mewah, dan workflow yang bisa di-reproduce.

Konfigurasi minimal di ~/.tmux.conf:

# Ganti prefix ke Ctrl+a (lebih ergonomis)
unbind C-b
set-option -g prefix C-a
bind-key C-a send-prefix

# Split yang intuitif
bind | split-window -h -c "#{pane_current_path}"
bind - split-window -v -c "#{pane_current_path}"

# Navigasi pane dengan Alt+arrow
bind -n M-Left select-pane -L
bind -n M-Right select-pane -R
bind -n M-Up select-pane -U
bind -n M-Down select-pane -D

# Mouse support
set -g mouse on

# Numbering mulai dari 1
set -g base-index 1

# Status bar bersih
set -g status-style 'bg=#1e1e2e fg=#cdd6f4'

Workflow saya: satu tmux session per proyek, dengan layout standar — pane kiri untuk editor (Neovim), pane kanan atas untuk server dev, pane kanan bawah untuk git dan CLI lainnya.

Dotfile Management: Git + Bare Repository

Ini yang jarang dibahas tapi krusial kalau kamu punya lebih dari satu mesin atau sering reinstall. Simpan semua dotfile di Git.

Metode yang saya pakai: bare repository di ~/.dotfiles.

git init --bare $HOME/.dotfiles
alias dotfiles='/usr/bin/git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME'
dotfiles config --local status.showUntrackedFiles no

Tambahkan alias dotfiles ke shell config kamu. Sekarang kamu bisa:

dotfiles add ~/.zshrc
dotfiles add ~/.tmux.conf
dotfiles commit -m "add zsh and tmux config"
dotfiles remote add origin git@github.com:username/dotfiles.git
dotfiles push

Kalau setup mesin baru:

git clone --bare git@github.com:username/dotfiles.git $HOME/.dotfiles
alias dotfiles='/usr/bin/git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME'
dotfiles checkout

Semua config langsung di tempat yang benar. Tidak perlu symlink, tidak perlu tool tambahan seperti GNU Stow (meski Stow juga bagus kalau kamu mau).

Untuk referensi lebih lanjut soal workflow self-hosted yang produktif, cek artikel saya tentang setup SSH key management untuk multiple server dan Neovim sebagai IDE untuk backend engineer.

Perbandingan Version Manager

Runtime Tool Rekomendasi Alternatif Catatan
Python pyenv conda (kalau data science) Jangan pakai deadsnakes kecuali terpaksa
Node.js fnm volta nvm terlalu lambat
Go tarball resmi goenv apt versinya sering ketinggalan
Rust rustup Tidak ada alternatif yang masuk akal
Ruby rbenv rvm rvm terlalu invasif
Java SDKMAN! jabba SDKMAN juga handle Gradle, Maven

Docker: Pasang dengan Benar, Bukan Convenience Script

Banyak tutorial suruh kamu jalankan curl ... | sh dari Docker. Jangan. Pakai repository resmi:

# Tambah GPG key
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
  sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

# Tambah repository
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
  https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# Tambah user ke group docker (hindari sudo setiap saat)
sudo usermod -aG docker $USER
newgrp docker

Perhatikan: saya install docker-compose-plugin, bukan docker-compose versi lama. Artinya perintahnya docker compose (tanpa tanda hubung), bukan docker-compose. Versi plugin ini jauh lebih cepat dan aktif dikembangkan.

Kesimpulan: Setup Development Environment Linux yang Tahan Lama

Kalau harus diringkas: setup development environment Linux yang baik itu tentang isolasi dan reprodusibilitas. Runtime dikelola per-proyek via version manager, dotfile ada di Git, dan konfigurasi shell dibuat sesederhana mungkin tanpa mengorbankan produktivitas.

Jangan kejar setup yang "keren" — kejar setup yang bisa kamu rebuild dalam 30 menit kalau SSD tiba-tiba mati.

Apa yang harus kamu lakukan besok? Buka terminal, cek apakah Python dan Node kamu dikelola via version manager. Kalau belum, mulai dari sana. Pasang pyenv dan fnm, pindahkan runtime kamu, lalu commit dotfile pertama kamu ke Git. Dua jam kerja hari ini akan hemat puluhan jam debugging di masa depan.