Dev Container로 개발 환경 한 번에 세팅하기
새 프로젝트에 합류했는데 개발 환경 설정에만 하루 이상 걸린 적 있으신가요? Node.js 버전이 안 맞고, Python 패키지가 충돌하고, 데이터베이스 설치가 안 되고… 😅 이런 문제는 개발자라면 누구나 한 번쯤 겪어봤을 텐데요.
Dev Container는 이런 골치 아픈 개발 환경 설정을 컨테이너 안에 통째로 담아서 해결합니다. 설정 파일 하나만 프로젝트에 넣어두면 팀원 누구나 동일한 환경에서 바로 작업을 시작할 수 있죠. 이번 글에서는 Dev Container가 뭔지, 어떻게 쓰는지 처음부터 차근차근 알아보겠습니다.
Dev Container란?
Dev Container(Development Container)는 Docker 컨테이너를 개발 환경으로 활용하는 방식입니다. 프로젝트에 필요한 런타임, 도구, 라이브러리, 에디터 설정까지 전부 컨테이너 이미지로 묶어서 관리하는 건데요.
핵심 아이디어는 간단합니다. “내 컴퓨터에서는 되는데?”라는 말이 나올 수 없도록, 모든 사람이 똑같은 환경에서 작업하는 겁니다.
Dev Container의 동작 방식을 간단히 정리하면 이렇습니다.
우선 프로젝트 루트에 .devcontainer/devcontainer.json 파일을 만들어서 개발 환경을 정의합니다.
그러면 VS Code 같은 에디터가 이 설정 파일을 읽어서 Docker 컨테이너를 자동으로 빌드하고 실행합니다.
개발자는 마치 로컬에서 작업하듯이 에디터를 사용하지만, 실제 코드 실행은 컨테이너 안에서 일어나는 거죠.
왜 Dev Container를 쓸까?
개발 환경을 컨테이너로 관리하면 어떤 점이 좋을까요?
가장 큰 장점은 환경 설정이 코드로 관리된다는 겁니다.
devcontainer.json 파일이 Git에 함께 버전 관리되니까, 변경 이력도 추적할 수 있고 코드 리뷰도 가능하죠.
“위키에 적힌 대로 했는데 안 돼요”라는 상황이 사라집니다.
온보딩도 훨씬 빨라집니다. 신규 팀원이 합류하면 저장소를 클론하고 Dev Container를 여는 것만으로 개발을 시작할 수 있거든요. Node.js 설치하고, Python 가상 환경 만들고, 데이터베이스 설정하는 과정이 전부 자동이니까 따로 신경 쓸 게 없습니다.
로컬 환경을 깔끔하게 유지할 수 있다는 것도 빼놓을 수 없는데요. 프로젝트마다 필요한 도구가 다른데, 그걸 다 내 맥북에 직접 설치하면 금방 지저분해지잖아요. Dev Container를 쓰면 프로젝트별로 격리된 환경이니까 서로 충돌할 일이 없습니다.
사전 준비
Dev Container를 사용하려면 두 가지가 필요합니다.
먼저 Docker가 설치되어 있어야 합니다. macOS라면 Docker Desktop이나 Colima를, Windows라면 Docker Desktop을, Linux라면 Docker Engine을 설치하면 됩니다. Docker가 처음이라면 Docker 시작하기 글을 먼저 읽어보시는 걸 추천드립니다.
그리고 VS Code와 Dev Containers 확장 프로그램이 필요합니다.
code --install-extension ms-vscode-remote.remote-containers
VS Code의 확장 프로그램 마켓플레이스에서 “Dev Containers”를 검색해서 설치해도 됩니다. 설치하고 나면 VS Code 왼쪽 아래에 파란색 원격 연결 아이콘이 생기는데요, 이 아이콘을 통해 Dev Container를 열고 관리할 수 있습니다.
devcontainer.json 작성하기
Dev Container의 핵심은 .devcontainer/devcontainer.json 설정 파일입니다.
가장 기본적인 형태부터 살펴볼게요.
{
"name": "Node.js Dev",
"image": "mcr.microsoft.com/devcontainers/javascript-node:22"
}
이게 가장 간단한 Dev Container 설정입니다. Microsoft에서 제공하는 Node.js 22 이미지를 그대로 사용하겠다는 뜻인데요. 이것만으로도 Node.js 22가 설치된 리눅스 컨테이너에서 개발할 수 있습니다.
실제 프로젝트에서는 좀 더 상세한 설정이 필요할 텐데요, 주요 속성을 하나씩 살펴보겠습니다.
{
"name": "My Project",
"image": "mcr.microsoft.com/devcontainers/typescript-node:22",
"features": {
"ghcr.io/devcontainers/features/git:1": {},
"ghcr.io/devcontainers/features/github-cli:1": {}
},
"customizations": {
"vscode": {
"extensions": ["dbaeumer.vscode-eslint", "esbenp.prettier-vscode"],
"settings": {
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
}
},
"forwardPorts": [3000],
"postCreateCommand": "npm install",
"remoteUser": "node"
}
features는 기본 이미지에 추가 도구를 얹을 때 쓰는데요.
위 예시에서는 Git과 GitHub CLI를 추가했습니다.
별도의 Dockerfile 없이도 원하는 도구를 쉽게 설치할 수 있어서 꽤 편리하죠.
사용할 수 있는 Feature 목록은 Dev Container Features에서 확인할 수 있습니다.
customizations.vscode에서는 VS Code 확장 프로그램과 설정을 지정합니다.
여기에 적어둔 확장 프로그램은 컨테이너가 만들어질 때 자동으로 설치되니까, 팀원 모두 같은 린터와 포매터를 쓸 수 있게 되죠.
forwardPorts는 컨테이너 안에서 실행되는 서버 포트를 로컬로 포워딩해 줍니다.
3000번 포트를 포워딩해 두면 브라우저에서 localhost:3000으로 개발 서버에 바로 접속할 수 있고요.
postCreateCommand는 컨테이너가 처음 만들어진 직후에 실행할 명령어입니다.
의존성 설치나 데이터베이스 마이그레이션 같은 초기 설정 작업을 넣어두면 편리합니다.
Dockerfile과 함께 사용하기
기본 이미지만으로 부족하다면 직접 Dockerfile을 작성할 수도 있습니다.
FROM mcr.microsoft.com/devcontainers/python:3.12
RUN apt-get update && apt-get install -y \
postgresql-client \
&& rm -rf /var/lib/apt/lists/*
RUN pip install poetry
{
"name": "Python + PostgreSQL",
"build": {
"dockerfile": "Dockerfile"
},
"features": {
"ghcr.io/devcontainers/features/node:1": {}
},
"postCreateCommand": "poetry install",
"forwardPorts": [8000]
}
image 대신 build.dockerfile을 지정하면 해당 Dockerfile을 기반으로 컨테이너를 빌드합니다.
위 예시에서는 Python 3.12 이미지에 PostgreSQL 클라이언트와 Poetry를 추가로 설치하고, Feature로 Node.js까지 넣었습니다.
이렇게 하면 프론트엔드와 백엔드를 한 컨테이너에서 개발할 수 있습니다.
Docker Compose와 함께 사용하기
데이터베이스나 캐시 서버 같은 외부 서비스가 필요한 프로젝트라면 Docker Compose를 활용할 수 있습니다.
services:
app:
build:
context: ..
dockerfile: .devcontainer/Dockerfile
volumes:
- ..:/workspace:cached
command: sleep infinity
ports:
- "3000:3000"
db:
image: postgres:16
environment:
POSTGRES_USER: dev
POSTGRES_PASSWORD: dev
POSTGRES_DB: myapp
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:
{
"name": "Full Stack",
"dockerComposeFile": "docker-compose.yml",
"service": "app",
"workspaceFolder": "/workspace",
"postCreateCommand": "npm install",
"forwardPorts": [3000, 5432]
}
dockerComposeFile을 지정하면 Dev Container가 Docker Compose를 사용해서 여러 서비스를 한꺼번에 띄웁니다.
service는 실제로 개발 작업을 할 컨테이너를 가리키고요.
이렇게 하면 애플리케이션 코드는 app 컨테이너에서 작성하면서, db 컨테이너의 PostgreSQL에도 바로 접근할 수 있습니다.
app 서비스의 command: sleep infinity가 좀 특이하게 보일 수 있는데요.
Dev Container가 컨테이너의 생명주기를 관리하기 때문에, 컨테이너가 종료되지 않도록 이렇게 설정하는 게 일반적인 패턴입니다.
VS Code에서 Dev Container 열기
설정 파일을 작성했으면 실제로 Dev Container를 열어볼 차례입니다.
VS Code에서 프로젝트 폴더를 열고 Ctrl+Shift+P (macOS에서는 Cmd+Shift+P)를 눌러 커맨드 팔레트를 엽니다.
거기서 “Dev Containers: Reopen in Container”를 선택하면 됩니다.
처음 열 때는 Docker 이미지를 빌드하는 과정이 있어서 시간이 좀 걸립니다. 빌드가 끝나면 VS Code가 컨테이너에 연결되고, 터미널도 컨테이너 안쪽의 셸을 사용하게 됩니다. VS Code 왼쪽 아래 표시가 “Dev Container: [이름]“으로 바뀌면 정상적으로 연결된 겁니다.
자주 쓰는 커맨드 팔레트 명령어를 정리하면 이렇습니다.
- Dev Containers: Reopen in Container — 현재 폴더를 Dev Container로 열기
- Dev Containers: Rebuild Container — 설정 변경 후 컨테이너 다시 빌드
- Dev Containers: Rebuild Without Cache and Reopen in Container — 캐시 없이 처음부터 빌드
- Dev Containers: Reopen Folder Locally — Dev Container에서 빠져나와 로컬로 돌아가기
설정 파일을 수정했는데 반영이 안 되면 “Rebuild Container”를 실행하면 됩니다.
단, devcontainer.json에서 VS Code 설정이나 확장 프로그램만 바꾼 거라면 리빌드 없이도 적용될 수 있습니다.
GitHub Codespaces에서 사용하기
Dev Container의 진가가 드러나는 순간은 GitHub Codespaces와 결합할 때입니다.
Codespaces는 GitHub에서 제공하는 클라우드 개발 환경인데요, 프로젝트의 devcontainer.json 설정을 그대로 사용합니다.
GitHub 저장소 페이지에서 초록색 “Code” 버튼을 누르고 “Codespaces” 탭에서 “Create codespace on main”을 클릭하면 됩니다. 브라우저에서 VS Code가 열리면서 프로젝트의 Dev Container 설정에 맞는 환경이 자동으로 구성됩니다.
로컬에 Docker를 설치할 필요도 없고, 노트북 성능이 낮아도 클라우드 서버에서 코드가 돌아가니까 쾌적하게 작업할 수 있습니다.
오픈 소스 프로젝트에 기여하고 싶을 때도 저장소에 devcontainer.json이 있으면 Codespaces로 바로 개발 환경을 열어서 시작할 수 있어서 정말 편리합니다.
무료 계정에서도 월 120시간의 코어 시간을 제공하니까, 개인 프로젝트나 학습 용도로는 충분합니다.
실전 팁
Dev Container를 실무에서 사용하다 보면 알게 되는 유용한 팁들이 있습니다.
Git 자격 증명은 자동으로 공유됩니다.
VS Code의 Dev Containers 확장이 로컬의 Git 설정과 SSH 키, 자격 증명을 컨테이너 안으로 자동 전달해 줍니다.
별도로 컨테이너 안에서 git config를 다시 할 필요가 없죠.
dotfiles 저장소를 연결하면 개인 설정도 자동으로 적용됩니다.
VS Code 설정에서 dotfiles.repository에 본인의 dotfiles 저장소 주소를 넣어두면, Dev Container가 열릴 때 셸 설정이나 에일리어스가 자동으로 적용됩니다.
{
"dotfiles.repository": "https://github.com/your-username/dotfiles",
"dotfiles.installCommand": "install.sh"
}
컨테이너 빌드가 느리다면 cacheFrom 옵션을 활용해 보세요.
빌드된 이미지를 레지스트리에 푸시해두고, 다음 빌드 때 캐시로 재사용할 수 있습니다.
{
"build": {
"dockerfile": "Dockerfile",
"cacheFrom": "ghcr.io/your-org/your-repo-devcontainer:latest"
}
}
자주 만나는 문제와 해결법
Dev Container를 처음 사용하면 몇 가지 문제를 마주칠 수 있는데요, 대부분 간단히 해결됩니다.
컨테이너 빌드가 실패한다면 Docker가 제대로 돌아가고 있는지부터 확인해 보세요.
docker info
이 명령어가 에러 없이 실행되면 Docker 쪽은 문제가 없는 겁니다. 그래도 빌드가 안 된다면 “Rebuild Without Cache”를 시도해 보세요.
파일을 수정했는데 컨테이너에 반영이 안 되는 경우도 있는데요, 이럴 때는 볼륨 마운트 설정을 확인해야 합니다.
Docker Compose를 사용하고 있다면 volumes에 프로젝트 디렉토리가 제대로 매핑되어 있는지 살펴보세요.
컨테이너 안에서 localhost로 다른 서비스에 접속이 안 되는 것도 흔한 실수인데요.
Docker Compose 환경에서는 서비스 이름을 호스트명으로 써야 합니다.
PostgreSQL 컨테이너의 서비스 이름이 db라면, 접속 주소는 localhost가 아니라 db인 거죠.
마치며
Dev Container를 사용하면 “내 컴퓨터에서는 되는데?”라는 말에서 해방될 수 있습니다. 설정 파일 하나로 개발 환경을 코드처럼 관리하고, 팀원 누구나 동일한 환경에서 작업을 시작할 수 있으니까요.
Docker가 처음이라면 Docker 시작하기부터, 여러 서비스를 함께 띄우고 싶다면 Docker Compose 커맨드 사용법을 참고하시면 좋겠습니다. macOS에서 Docker Desktop 대신 가벼운 대안을 찾고 있다면 Colima도 살펴보세요.
Dev Container에 대해 더 깊이 알고 싶다면 공식 스펙 문서를 확인해 보세요.
This work is licensed under
CC BY 4.0