Jalankan Dev Environment Lokal dengan Devcontainer

by Marcus Chen
Jalankan Dev Environment Lokal dengan Devcontainer

Pernah nggak kamu clone repo lama, terus npm install atau pip install gagal karena versi Node atau Python beda? Atau lebih parah: kamu baru beli laptop baru, terus habis setengah hari cuma buat setup ulang semua tools yang kamu butuhkan.

Itu masalah klasik yang bikin frustrasi. Dan solusinya bukan "dokumentasikan semua langkah setup di README" — karena README itu bohong. Selalu ada satu langkah yang ketinggalan.

Solusi yang gue pakai sekarang: Devcontainer. Kamu define environment development kamu dalam satu file JSON, dan VS Code (atau IDE lain yang support) akan spin up container Docker yang isinya persis seperti yang kamu butuhkan. Laptop baru? Clone repo, buka di devcontainer, selesai.

Apa Itu Devcontainer dan Kenapa Bukan Cuma Docker Biasa

Devcontainer bukan sekadar "jalankan app di Docker". Bedanya:

  • Docker Compose biasa: kamu containerize aplikasi kamu buat production.
  • Devcontainer: kamu containerize environment development kamu — termasuk editor extensions, tools CLI, bahkan dotfiles kamu.

Jadi yang jalan di dalam container bukan cuma app-nya, tapi juga VS Code server-nya. Kamu tetap pakai VS Code di laptop, tapi semua eksekusi kode, terminal, dan extension jalan di dalam container.

Ini artinya:

  • Node versi 20 di project A, Node versi 18 di project B — nggak ada konflik.
  • Tim kamu punya environment yang identik. Nggak ada lagi "di laptop gue jalan kok".
  • Mau pindah ke mesin lain? Tinggal clone dan buka.

Struktur File yang Kamu Butuhkan

Minimal kamu butuh dua file di folder .devcontainer/ di root project kamu:

.devcontainer/
  devcontainer.json
  Dockerfile          # opsional, bisa pakai base image langsung

Contoh paling sederhana untuk project Node.js:

// .devcontainer/devcontainer.json
{
  "name": "Node.js Dev",
  "image": "mcr.microsoft.com/devcontainers/node:20",
  "customizations": {
    "vscode": {
      "extensions": [
        "dbaeumer.vscode-eslint",
        "esbenp.prettier-vscode",
        "eamodio.gitlens"
      ],
      "settings": {
        "editor.formatOnSave": true,
        "editor.defaultFormatter": "esbenp.prettier-vscode"
      }
    }
  },
  "forwardPorts": [3000],
  "postCreateCommand": "npm install"
}

Begitu kamu buka folder ini di VS Code dengan extension Dev Containers terinstall, VS Code akan tanya: "Reopen in Container?". Klik iya, tunggu build pertama (biasanya 2–5 menit), dan kamu langsung punya environment yang bersih.

postCreateCommand di atas otomatis jalankan npm install setelah container selesai dibuat. Jadi kamu nggak perlu ingat langkah itu.

Setup Lebih Kompleks: Pakai Dockerfile Sendiri

Kalau base image yang ada nggak cukup — misalnya kamu butuh tools tambahan seperti ffmpeg, database CLI, atau versi Python spesifik — kamu bisa pakai Dockerfile sendiri:

# .devcontainer/Dockerfile
FROM mcr.microsoft.com/devcontainers/python:3.11

# Install system dependencies
RUN apt-get update && apt-get install -y \
    ffmpeg \
    postgresql-client \
    redis-tools \
    && rm -rf /var/lib/apt/lists/*

# Install global Python tools
RUN pip install --no-cache-dir \
    black \
    ruff \
    httpie

Lalu di devcontainer.json, ganti image dengan build:

{
  "name": "Python + Tools",
  "build": {
    "dockerfile": "Dockerfile"
  },
  "customizations": {
    "vscode": {
      "extensions": [
        "ms-python.python",
        "ms-python.black-formatter",
        "charliermarsh.ruff"
      ]
    }
  },
  "forwardPorts": [8000],
  "postCreateCommand": "pip install -r requirements.txt"
}

Tambah Database dengan Docker Compose

Kalau project kamu butuh PostgreSQL atau Redis, jangan install di dalam devcontainer utama. Pisahkan pakai docker-compose.yml:

# .devcontainer/docker-compose.yml
version: '3.8'

services:
  app:
    build:
      context: ..
      dockerfile: .devcontainer/Dockerfile
    volumes:
      - ..:/workspace:cached
    command: sleep infinity
    environment:
      - DATABASE_URL=postgresql://postgres:postgres@db:5432/devdb
      - REDIS_URL=redis://cache:6379

  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: devdb
    volumes:
      - postgres-data:/var/lib/postgresql/data

  cache:
    image: redis:7-alpine

volumes:
  postgres-data:

Lalu update devcontainer.json untuk pakai compose:

{
  "name": "Full Stack Dev",
  "dockerComposeFile": "docker-compose.yml",
  "service": "app",
  "workspaceFolder": "/workspace",
  "customizations": {
    "vscode": {
      "extensions": [
        "ms-python.python",
        "mtxr.sqltools",
        "mtxr.sqltools-driver-pg"
      ]
    }
  },
  "forwardPorts": [8000, 5432, 6379],
  "postCreateCommand": "pip install -r requirements.txt && python manage.py migrate"
}

Sekarang tiap kamu buka project ini, PostgreSQL dan Redis otomatis nyala. Database kamu persist di Docker volume, jadi data nggak hilang tiap kali container restart.

Gotcha yang Gue Temuin (Biar Kamu Skip)

1. Permission masalah di Linux

Kalau kamu pakai Linux (bukan Mac atau Windows), file yang dibuat di dalam container kadang punya owner root, bukan user kamu. Ini bikin kamu nggak bisa edit file itu dari luar container.

Fix-nya: tambahkan ini di devcontainer.json:

{
  "remoteUser": "vscode"
}

Base image Microsoft (mcr.microsoft.com/devcontainers/*) sudah include user vscode dengan UID yang di-map ke user host kamu.

2. Git credentials nggak kebawa

Secara default, Git config dan SSH keys kamu nggak otomatis tersedia di dalam container. Untuk SSH keys, VS Code Dev Containers bisa forward SSH agent dari host — tapi kamu perlu pastikan ssh-agent jalan di host dan key sudah di-add:

# Di host kamu (bukan di dalam container)
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519

Untuk Git config (nama, email), VS Code otomatis copy dari host kalau kamu pakai image Microsoft. Kalau pakai image custom, tambahkan manual di postCreateCommand:

"postCreateCommand": "git config --global user.email 'kamu@email.com' && git config --global user.name 'Nama Kamu'"

3. Build pertama lama, tapi build berikutnya cepat

Build pertama bisa 5–10 menit tergantung Dockerfile kamu. Ini normal karena Docker pull base image dan install semua dependencies. Build berikutnya jauh lebih cepat karena layer caching. Jangan panik dan jangan cancel.

4. Volume mount di Windows lambat

Kalau kamu pakai Windows dengan WSL2, pastikan project kamu ada di filesystem WSL2 (/home/username/projects/), bukan di /mnt/c/. Mount dari Windows filesystem ke container itu lambat banget — bisa 10x lebih lambat untuk operasi file-heavy seperti npm install.

Tambahkan devcontainer ke GitHub Codespaces

Bonus: kalau kamu push .devcontainer/ ke repo GitHub kamu, siapa pun (termasuk kamu sendiri dari browser) bisa buka project itu di GitHub Codespaces dengan environment yang sama persis. Tinggal klik tombol "Code" → "Codespaces" → "Create codespace".

Ini berguna banget kalau kamu lagi di mesin orang lain dan butuh akses ke project kamu dengan cepat tanpa install apa pun.

Yang Gue Lakuin Sekarang

Semua project aktif gue sekarang punya .devcontainer/. Setup awalnya mungkin 30–45 menit, tapi itu investasi yang balik modal cepat.

Workflow gue sekarang:

  1. Clone repo.
  2. VS Code otomatis detect .devcontainer/ dan tanya mau reopen di container.
  3. Klik "Reopen in Container".
  4. Tunggu build (kalau pertama kali), atau langsung jalan kalau image sudah di-cache.
  5. Langsung coding. Semua tools, extensions, dan services sudah siap.

Kalau kamu mau mulai, install dulu extension Dev Containers di VS Code (ID: ms-vscode-remote.remote-containers), pastikan Docker Desktop (atau Docker Engine di Linux) jalan, lalu coba buat .devcontainer/devcontainer.json paling sederhana dulu — pakai image langsung, tanpa Dockerfile custom.

Setelah itu baru eksplor fitur lanjutan: Dockerfile custom, Docker Compose, features (cara mudah tambah tools seperti git, gh, kubectl tanpa tulis Dockerfile), dan postStartCommand vs postCreateCommand.

Documentation resminya ada di containers.dev — lengkap dan up-to-date. Reference untuk semua property devcontainer.json ada di sana, dan kamu bisa juga melihat this guide on OpenTelemetry Collector Configuration Tutorial untuk contoh konfigurasi yang lebih kompleks jika project kamu membutuhkan observability setup.