VS Code에서 Dev 컨테이너 마스터하기

Dev Containers를 사용하여 일관되며 이식 가능하고 재현 가능한 개발 환경을 생성하세요.

Page content

개발자들은 종종 의존성 불일치, 도구 버전, 또는 OS 차이로 인해 “works on my machine” 딜레마에 직면합니다. VS Code의 Dev Containers는 이 문제를 우아하게 해결합니다 — 프로젝트에 맞게 구성된 컨테이너화된 환경에서 개발할 수 있도록 해줍니다.

현대 소프트웨어 개발은 기계와 운영 체제에 걸쳐 일관되고 재현 가능한 환경을 요구합니다. Python 데이터 과학 프로젝트, Node.js 웹 애플리케이션, 또는 Go 마이크로서비스를 작업하든, 모든 팀원이 동일한 개발 설정을 갖는 것이 어려울 수 있습니다.

vs code dev containers

이 포괄적인 가이드는 Dev Containers가 무엇인지, 왜 유용한지, 그리고 VS Code에서 Dev Containers를 설정하여 부드럽고 이동 가능한 개발 워크플로우를 어떻게 구성하는지 설명합니다. 기본 설정부터 Docker Compose와 팀 협업을 위한 최선의 실천 방법까지 모든 것을 배우게 됩니다.


🧩 Dev Containers란 무엇인가요?

Dev ContainersVS Code Remote - Containers 확장 프로그램(현재 VS Code Remote Development에 포함됨)에서 제공하는 기능입니다.
이 기능은 Docker 컨테이너에 모든 의존성, 언어, 도구가 사전 구성된 상태로 프로젝트를 열 수 있도록 해줍니다.

이것은 다음과 같다고 생각해보세요:

“코드로 정의된 완전히 구성된 개발 환경.”

로컬 머신에 직접 Python, Node.js, 데이터베이스, 다양한 도구를 설치하는 대신, 구성 파일에 정의합니다. VS Code에서 프로젝트를 열면 지정된 대로 모든 것이 사전 설치되고 구성된 컨테이너가 자동으로 생성됩니다.

Dev Container 설정은 일반적으로 다음과 같은 항목을 포함합니다:

  • Dockerfile 또는 기반 이미지에 대한 참조(컨테이너 OS, 언어, 도구를 정의)
  • devcontainer.json 파일(워크스페이스 설정, VS Code 확장 프로그램, 포트 전달, 환경 변수, 시작 명령을 구성)
  • 프로젝트가 여러 서비스(데이터베이스, Redis, 메시지 큐 등)에 의존하는 경우 docker-compose.yml (선택 사항)

⚙️ Dev Containers를 사용하는 이유

이들이 강력한 이유는 다음과 같습니다:

  • 재현 가능성: 모든 개발자와 CI 시스템이 동일한 환경을 사용합니다. “내 머신에서는 작동하지만, 너의 머신에서는 작동하지 않는다"는 문제가 없습니다. 내 노트북에서 작동하는 것이 동료의 Windows, Mac, 또는 Linux 워크스테이션에서도 동일하게 작동합니다.

  • 분리: 로컬 머신에 충돌하는 의존성을 설치할 필요가 없습니다. Python, Node.js 또는 다른 도구의 다른 버전을 요구하는 여러 프로젝트를 작업할 때 버전 충돌이나 가상 환경 조작 없이 작업할 수 있습니다.

  • 이동성: Docker를 지원하는 모든 OS에서 작동합니다. 개발 환경은 코드와 함께 이동합니다. 저장소를 클론하고 VS Code에서 열면 운영 체제에 관계없이 몇 분 안에 코딩을 시작할 수 있습니다.

  • 팀 일관성: 팀 전체에 걸쳐 공유되는 하나의 구성. 새로운 팀원은 몇 시간(또는 며칠)을 소요해 개발 환경을 구성하는 대신 몇 분 안에 시작할 수 있습니다.

  • 자동화: 프로젝트를 열 때 자동으로 VS Code 확장 프로그램, 언어 의존성, 도구를 설치합니다. 생성 후 명령은 데이터베이스 마이그레이션, 데이터 시드, 또는 기타 설정 작업을 수동 개입 없이 수행할 수 있습니다.

  • 보안: 컨테이너에 잠재적으로 위험한 의존성을 분리합니다. 오래되고 취약한 라이브러리 버전을 테스트해야 할 경우, 컨테이너 내부에 제한되어 있고 호스트 시스템에 영향을 주지 않습니다.

실제 사례: Python 3.11, PostgreSQL 15, Redis, Elasticsearch를 사용하는 마이크로서비스 프로젝트에 참여한다고 상상해보세요. Dev Containers가 없으면 각 구성 요소를 설치하고 구성하는 데 몇 시간이 걸릴 수 있습니다. Dev Containers가 있으면 VS Code에서 프로젝트를 열고 컨테이너를 생성하면 5~10분 안에 코딩을 시작할 수 있습니다.


🧱 VS Code에서 Dev Container 설정하기

단계별로 진행해보겠습니다.

1. 필요한 도구 설치

시작하기 전에 다음을 설치해두세요:

  • Docker Desktop (또는 Podman과 같은 다른 컨테이너 런타임)

    • Windows/Mac: Docker Desktop을 다운로드하고 설치
    • Linux: Docker Engine을 설치하고 사용자가 docker 그룹에 속하도록 설정
  • VS Code (최신 버전 권장)

  • Dev Containers 확장 프로그램 (Microsoft에서 제공)

    • VS Code 열기
    • 확장 프로그램(Ctrl+Shift+X 또는 Cmd+Shift+X macOS)
    • “Dev Containers” 검색
    • ID: ms-vscode-remote.remote-containers로 확장 프로그램 설치

설치 확인:

# Docker 실행 확인
docker --version
docker ps

# Docker 버전 및 실행 중인 컨테이너(있는 경우) 출력

2. Dev Container 초기화

VS Code에서 프로젝트 폴더를 열고 명령 팔레트(Ctrl+Shift+P 또는 Cmd+Shift+P macOS)를 열고 다음을 입력 및 선택합니다:

Dev Containers: Add Dev Container Configuration Files...

VS Code는 사전 정의된 환경 템플릿 목록을 제공합니다. 프로젝트에 맞는 것을 선택하세요:

  • Node.js — JavaScript/TypeScript 프로젝트
  • Python — 데이터 과학, 웹 앱, 스크립트
  • Go — Go 애플리케이션 및 서비스
  • .NET — C#/F# 애플리케이션
  • Java — Spring Boot, Maven, Gradle 프로젝트
  • Docker-in-Docker — 컨테이너 내부에서 Docker가 필요한 경우
  • 그 외에도 많은 것들이 있습니다…

추가 기능도 선택할 수 있습니다:

  • 일반 유틸리티 (git, curl, wget)
  • 데이터베이스 클라이언트
  • 클라우드 CLI 도구 (AWS, Azure, GCP)

이 마법사가 생성하는 .devcontainer 폴더에는 다음과 같은 항목이 포함됩니다:

  • devcontainer.json — 주요 구성 파일
  • Dockerfile — 커스텀 이미지 정의 (또는 사전 구성된 기반 이미지 참조)

3. devcontainer.json 커스터마이징

devcontainer.json 파일은 마법이 일어나는 곳입니다. Node.js 프로젝트를 위한 잘 문서화된 예시는 다음과 같습니다:

{
  // VS Code에서 컨테이너의 표시 이름
  "name": "Node.js Development Container",
  
  // 빌드 구성 - Dockerfile 또는 사전 구성된 이미지 사용
  "build": {
    "dockerfile": "Dockerfile",
    "context": ".."
  },
  
  // 대안: Dockerfile 대신 사전 구성된 이미지 사용
  // "image": "mcr.microsoft.com/devcontainers/javascript-node:18",
  
  // 워크스페이스 구성
  "customizations": {
    "vscode": {
      // 컨테이너 내부에서 적용되는 VS Code 설정
      "settings": {
        "terminal.integrated.defaultProfile.linux": "bash",
        "editor.formatOnSave": true,
        "editor.defaultFormatter": "esbenp.prettier-vscode"
      },
      
      // 자동 설치할 VS Code 확장 프로그램
      "extensions": [
        "dbaeumer.vscode-eslint",
        "esbenp.prettier-vscode",
        "eamodio.gitlens",
        "ms-azuretools.vscode-docker"
      ]
    }
  },
  
  // 포트 전달 - 컨테이너의 포트를 호스트에 노출
  "forwardPorts": [3000, 5432],
  "portsAttributes": {
    "3000": {
      "label": "Application",
      "onAutoForward": "notify"
    }
  },
  
  // 다양한 단계에서 실행할 명령
  "postCreateCommand": "npm install",     // 컨테이너가 처음 생성될 때 실행
  "postStartCommand": "npm run dev",      // 컨테이너가 시작될 때 실행
  
  // 환경 변수
  "containerEnv": {
    "NODE_ENV": "development",
    "PORT": "3000"
  },
  
  // 컨테이너 내부에서 사용할 사용자 계정 (보안을 위해 권장)
  "remoteUser": "node",
  
  // 추가 볼륨 마운트
  "mounts": [
    "source=${localEnv:HOME}/.ssh,target=/home/node/.ssh,readonly,type=bind"
  ]
}

주요 구성 옵션 설명:

  • name — VS Code 상태 표시줄에 표시되는 이름
  • build / image — Dockerfile 또는 사전 구성된 이미지 사용
  • customizations.vscode.extensions — 자동 설치할 VS Code 확장 프로그램
  • forwardPorts — 컨테이너에서 호스트로 노출할 포트
  • postCreateCommand — 컨테이너가 처음 생성될 때 실행 (예: 의존성 설치)
  • postStartCommand — 컨테이너가 시작될 때마다 실행
  • containerEnv — 컨테이너 내부에서 사용 가능한 환경 변수
  • remoteUser — 컨테이너 내부에서 사용할 사용자 계정
  • mounts — 추가 파일/폴더 마운트 (예: SSH 키)

💡 전문가 팁:

  • postCreateCommand에 느린 작업 (npm install, pip install) 사용
  • postStartCommand에 빠른 시작 작업 (데이터베이스 마이그레이션) 사용
  • 항상 프로젝트에 필요한 확장 프로그램을 명시 — 이는 일관된 도구 사용을 보장
  • 환경 변수를 사용하여 개발자 간에 다른 설정을 관리

4. 빌드 및 컨테이너에서 열기

구성 파일이 준비되면 개발 환경을 시작할 시간입니다:

명령 팔레트(Ctrl+Shift+P / Cmd+Shift+P)를 열고 실행합니다:

Dev Containers: Reopen in Container

다음이 일어납니다:

  1. 이미지 빌드 — VS Code는 Dockerfile을 기반으로 이미지를 빌드하거나 사전 구성된 이미지를 가져옵니다. 처음에는 몇 분이 걸릴 수 있습니다.

  2. 컨테이너 생성 — Docker는 빌드된 이미지에서 새로운 컨테이너를 생성합니다.

  3. 볼륨 마운트 — 프로젝트 폴더가 컨테이너에 마운트되어 코드가 내부에서 접근 가능해집니다.

  4. 확장 프로그램 설치 — 지정된 모든 VS Code 확장 프로그램이 자동으로 컨테이너에 설치됩니다.

  5. 생성 후 명령 실행postCreateCommand가 실행됩니다 (예: npm install, pip install -r requirements.txt).

  6. 준비 완료! — VS Code는 컨테이너에 다시 연결되고, 이제 그 안에서 개발을 시작할 수 있습니다.

컨테이너 내부인지 확인:

터미널을 열고 다음을 실행하여 확인할 수 있습니다:

# 운영 체제 확인
uname -a
# 출력: Linux ... (컨테이너의 커널)

# 호스트 이름 확인 (일반적으로 컨테이너 ID)
hostname
# 출력: abc123def456

# 실행 중인 프로세스 확인
ps aux
# 컨테이너의 프로세스를 볼 수 있고, 호스트 시스템의 프로세스는 보이지 않습니다.

VS Code 상태 표시줄(왼쪽 하단)이 이제 다음과 같이 표시됩니다: Dev Container: [컨테이너 이름]

컨테이너 생명주기 명령:

  • 컨테이너 재빌드Dev Containers: Rebuild Container (Dockerfile 변경 시)
  • 캐시 없이 재빌드Dev Containers: Rebuild Container Without Cache (신선한 빌드)
  • 로컬에서 다시 열기Dev Containers: Reopen Folder Locally (컨테이너를 나가고 호스트에서 작업)

5. 추가 서비스 추가 (선택 사항)

실제 애플리케이션은 종종 데이터베이스, 캐싱 레이어, 메시지 큐 또는 기타 서비스에 의존합니다. **Docker Compose**를 사용하여 여러 컨테이너를 오케스트레이션할 수 있습니다.

예시: Node.js, PostgreSQL, Redis를 사용한 전체 스택 애플리케이션

.devcontainer 폴더에 docker-compose.yml을 생성합니다:

version: "3.8"

services:
  # 주 개발 컨테이너
  app:
    build: 
      context: ..
      dockerfile: .devcontainer/Dockerfile
    
    volumes:
      # 프로젝트 폴더 마운트
      - ..:/workspace:cached
      # node_modules을 위한 이름 지정된 볼륨 (더 나은 성능)
      - node_modules:/workspace/node_modules
    
    # 컨테이너가 실행되도록 유지
    command: sleep infinity
    
    # 다른 서비스에 대한 네트워크 접근
    depends_on:
      - db
      - redis
    
    environment:
      DATABASE_URL: postgresql://dev:secret@db:5432/appdb
      REDIS_URL: redis://redis:6379

  # PostgreSQL 데이터베이스
  db:
    image: postgres:15-alpine
    restart: unless-stopped
    volumes:
      - postgres-data:/var/lib/postgresql/data
    environment:
      POSTGRES_USER: dev
      POSTGRES_PASSWORD: secret
      POSTGRES_DB: appdb
    ports:
      - "5432:5432"

  # Redis 캐시
  redis:
    image: redis:7-alpine
    restart: unless-stopped
    volumes:
      - redis-data:/data
    ports:
      - "6379:6379"

volumes:
  postgres-data:
  redis-data:
  node_modules:

그런 다음 devcontainer.json을 Docker Compose를 사용하도록 업데이트합니다:

{
  "name": "Full-stack Dev Environment",
  
  // Docker Compose 대신 단일 컨테이너 사용
  "dockerComposeFile": "docker-compose.yml",
  
  // 사용할 개발 컨테이너 서비스
  "service": "app",
  
  // 컨테이너 내부의 워크스페이스 폴더 경로
  "workspaceFolder": "/workspace",
  
  "customizations": {
    "vscode": {
      "extensions": [
        "dbaeumer.vscode-eslint",
        "esbenp.prettier-vscode",
        "ms-azuretools.vscode-docker",
        "ckolkman.vscode-postgres"  // PostgreSQL 클라이언트
      ]
    }
  },
  
  "forwardPorts": [3000, 5432, 6379],
  
  "postCreateCommand": "npm install && npm run db:migrate",
  
  "remoteUser": "node"
}

이 설정이 제공하는 내용:

  • app — Node.js를 사용하는 개발 컨테이너
  • db — PostgreSQL 데이터베이스, db:5432에서 애플리케이션에 접근 가능
  • redis — Redis 캐시, redis:6379에서 접근 가능
  • 이름 지정된 볼륨 — 컨테이너 재시작 간 데이터베이스 데이터 유지
  • 포트 전달 — 호스트 머신에서 모든 서비스에 접근 가능

코드에서 서비스에 연결:

// Node.js 애플리케이션에서
const { Pool } = require('pg');
const redis = require('redis');

// PostgreSQL 연결
const pool = new Pool({
  connectionString: process.env.DATABASE_URL
  // 해석: postgresql://dev:secret@db:5432/appdb
});

// Redis 연결
const redisClient = redis.createClient({
  url: process.env.REDIS_URL
  // 해석: redis://redis:6379
});

호스트에서 서비스에 접근:

  • : http://localhost:3000
  • PostgreSQL: localhost:5432 (어떤 PostgreSQL 클라이언트를 사용해도 됨)
  • Redis: localhost:6379 (redis-cli 또는 GUI 도구 사용)

이제 VS Code에서 프로젝트를 열면 모든 서비스가 자동으로 시작됩니다!


🧠 고급 팁 및 최선의 실천 방법

사전 구성된 이미지 사용

Microsoft의 공식 devcontainer 이미지에서 시작하여 빌드 시간을 절약하세요:

{
  "image": "mcr.microsoft.com/devcontainers/python:3.11",
  "features": {
    "ghcr.io/devcontainers/features/git:1": {},
    "ghcr.io/devcontainers/features/github-cli:1": {}
  }
}

기능은 일반 도구(Git, GitHub CLI, Node, AWS CLI 등)를 위한 재사용 가능한 설치 스크립트입니다.

버전 관리 최선의 실천 방법

항상 .devcontainer 폴더를 커밋하세요:

git add .devcontainer/
git commit -m "Add Dev Container configuration"
git push

이렇게 하면:

  • ✅ 새로운 팀원이 자동으로 환경을 얻을 수 있음
  • ✅ 환경 변경이 추적되고 검토 가능
  • ✅ 모두가 동일한 설정에서 개발

전문가 팁: README 섹션에 dev container 설정을 설명하세요:

## 개발 설정

이 프로젝트는 VS Code Dev Containers를 사용합니다. 시작하려면:

1. Docker Desktop과 VS Code 설치
2. "Dev Containers" 확장 프로그램 설치
3. 이 저장소 클론
4. VS Code에서 열기
5. 프롬프트가 나타날 때 "Reopen in Container" 클릭

컨테이너에서 디버깅

디버깅은 원활하게 작동합니다. launch.json을 일반적으로 구성하세요:

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Launch Node.js",
      "type": "node",
      "request": "launch",
      "program": "${workspaceFolder}/index.js",
      "skipFiles": ["<node_internals>/**"]
    }
  ]
}

브레이크포인트를 설정하고 일반적으로 디버깅하세요 — VS Code는 컨테이너 연결을 자동으로 처리합니다.

CI/CD와의 일관성

CI/CD 파이프라인에서 동일한 컨테이너 이미지를 사용하세요:

# GitHub Actions 예시
name: CI
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    container:
      image: mcr.microsoft.com/devcontainers/javascript-node:18
    steps:
      - uses: actions/checkout@v3
      - run: npm install
      - run: npm test

이렇게 하면 개발/생산 일관성이 보장됩니다 — 로컬에서 테스트가 통과하면 CI에서도 통과합니다.

성능 최적화

macOS/Windows 사용자에게node_modules, venv 등에 대해 이름 지정된 볼륨을 사용하세요:

{
  "mounts": [
    "source=myproject-node_modules,target=${containerWorkspaceFolder}/node_modules,type=volume"
  ]
}

이렇게 하면 node_modules, venv 등에 대한 파일 I/O 성능이 크게 향상됩니다.

다단계 개발

다른 팀 역할에 대한 다양한 구성 생성:

.devcontainer/
├── devcontainer.json          # 기본 (풀스택)
├── frontend/
│   └── devcontainer.json      # 프론트엔드만 (가볍게)
└── backend/
    └── devcontainer.json      # 백엔드만 (데이터베이스 포함)

팀원은 프로젝트를 열 때 환경을 선택할 수 있습니다.

SSH 키와 Git 사용

Git 작업을 위해 SSH 키를 마운트하세요:

{
  "mounts": [
    "source=${localEnv:HOME}${localEnv:USERPROFILE}/.ssh,target=/home/node/.ssh,readonly,type=bind"
  ],
  "postCreateCommand": "ssh-add ~/.ssh/id_ed25519 || true"
}

커스텀 환경 파일

환경에 따라 구성 파일을 로드하세요:

{
  "runArgs": ["--env-file", ".devcontainer/.env"]
}

.devcontainer/.env:

API_KEY=dev_key_here
DEBUG=true
LOG_LEVEL=debug

🔧 일반적인 문제 해결

컨테이너가 시작되지 않음

에러: Docker 데몬에 연결할 수 없음

해결 방법:

  • Docker Desktop이 실행 중인지 확인
  • Linux에서: sudo systemctl status docker
  • Docker가 PATH에 있는지 확인: docker --version

macOS/Windows에서 느린 성능

문제: 파일 작업이 느림

해결 방법:

  1. node_modules, venv 등에 이름 지정된 볼륨 사용

  2. Docker Desktop 설정에서 파일 공유 활성화

  3. cached 또는 delegated 마운트 옵션 사용:

    "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind,consistency=cached"
    

확장 프로그램이 설치되지 않음

문제: devcontainer.json에 지정된 확장 프로그램이 설치되지 않음

해결 방법:

  1. 컨테이너 재빌드: Dev Containers: Rebuild Container
  2. 확장 프로그램 ID가 올바른지 확인
  3. 확장 프로그램이 원격 컨테이너를 지원하는지 확인 (대부분 지원)

포트가 이미 사용 중

에러: 포트 3000이 이미 할당됨

해결 방법:

  1. 충돌하는 컨테이너 중지: docker psdocker stop <컨테이너>
  2. forwardPorts에서 포트 매핑 변경
  3. 동적 포트 사용: VS Code가 사용 가능한 포트를 자동으로 할당

Dockerfile 변경이 적용되지 않음

문제: Dockerfile을 수정했지만 변경사항이 적용되지 않음

해결 방법: 캐시 없이 재빌드:

Dev Containers: Rebuild Container Without Cache

컨테이너가 즉시 종료됨

문제: 컨테이너가 시작되고 바로 종료됨

해결 방법: docker-compose.yml에 다음을 추가하여 실행을 유지:

command: sleep infinity

또는 devcontainer.json에 다음을 추가:

{
  "overrideCommand": true
}

✅ 결론

VS Code의 Dev Containers는 개발 워크플로우에 일관성, 간단함, 자동화를 가져옵니다. 복잡하고 취약한 설정을 코드로 정의된 환경으로 전환하여, 사용하는 머신이나 운영 체제에 관계없이 작동하도록 합니다.

핵심 요약:

  • 🎯 “works on my machine” 문제 제거 — 모든 사람이 동일한 환경 사용
  • 🚀 빠른 온보딩 — 새로운 팀원이 몇 시간이 아닌 몇 분 안에 생산성 시작
  • 🔒 더 나은 보안 — 의존성을 호스트 시스템에서 분리
  • 📦 이동성 — 환경이 코드와 함께 이동
  • 🤝 팀 일관성 — 의존성 버전 충돌 없음
  • 🔄 CI/CD 일관성 — 개발과 CI에서 동일한 이미지 사용

단순한 Python 스크립트든 복잡한 마이크로서비스 아키텍처든, Dev Containers는 현대 개발에 대한 견고한 기반을 제공합니다.

다중 언어 프로젝트에 협업하거나, 오픈소스 저장소에 기여하거나, 자주 새로운 개발자를 온보딩하거나, 또는 깨끗하고 재현 가능한 개발 환경을 원한다면 — Dev Containers는 당신의 스택에 필수적인 도구입니다.

작은 것부터 시작하세요: 다음 프로젝트에서 Dev Containers를 시도해보세요. 이 혜택을 경험한 후에는 그 전에 어떻게 개발했는지 놀라게 될 것입니다.


📚 유용한 자료 및 관련 기사

공식 문서:

이 사이트의 관련 기사: