BUZZVIL BLOG

[Tech Blog] VS Code로 컨테이너 안에서 개발하기

컨테이너 환경은 날이 갈 수록 더 많은 사람에게 사랑 받고 있죠. 처음부터 Docker, Kubernetes 등을 활용해 컨테이너 기반의 배포를 사용하기 시작한 사람들은 capistrano나 fabric 같은 도구를 사용한 배포 환경에서 나타날 수 있는 정말 다양하고 예상하기 힘든 문제들이 어떤 지옥인지 상상하기 어려울 것입니다.

컨테이너는 배포 환경과 개발 환경을 최대한 맞춰주는 역할도 수행할 수 있습니다. docker-compose를 잘 활용하면 큰 무리 없이 실제 배포 환경과 거의 비슷한 환경을 구성할 수 있죠. 로컬 환경에서 실행 된다면 배포 시점에도 실행될 것이라는 자신감을 얻을 수 있습니다. 다들 불안해 하면서 개발하고 더 불안해 하면서 배포하기는 정말 싫잖아요?

하지만 사람의 욕심은 끝이 없죠. 다들 메모장으로 개발하지 않는 이상 특정 IDE를 활용하고 있을 텐데요, IDE에서도 컨테이너 환경 안에서 개발할 수 있다면 얼마나 좋을까요? 이 글에서는 컨테이너 안에서 개발할 수 있는 환경이 필요한 이유VS Code를 사용해서 컨테이너 내부 개발 환경을 구성하는 방법을 정리해 보겠습니다.

컨테이너 환경에서 동작하는 IDE가 왜 필요할까?

개발자 사이 개발 환경 통일

보통 Repository를 clone하고 맨 처음 하는 일은 README.md를 정독하는 일입니다. 어떻게 개발 및 테스트를 진행하는지 알아야 하니까요. 다행이 대부분의 언어들이 package manager를 가지고 있죠. gem, npm, pip, mod 등을 활용해서 라이브러리를 가지고 옵니다. pip install -r requirements.txt 하면 짜잔, 완료일까요? 에고 Python 버전이 다르네요. Python 3.8.0을 설치해야겠어요. 설치하려고 보니 다른 프로젝트에서는 여전히 python 2를 사용 중입니다. 프로젝트 왔다 갔다 할 때마다 python을 설정해 줄 수 없으니 virtualenv를 사용해야 겠군요. rvm, nvm, … 뭐 이리 해야 될 것들이 많은지.

애써 Docker를 사용해서 컨테이너화 시켰지만 아직 많은 경우 이와 같은 행동을 반복합니다. 컨테이너 안에 개발 및 디버깅에 필요한 도구들이 들어있지 않거든요. IDE에서 지원하는 intellisense 기능을 사용하려면 필요하기도 하구요. 컨테이너는 만들었지만 로컬 환경에서 개발할 때는 정작 쓰지를 못하는군요.

테스트 환경 구성

docker-compose up으로 프로그램 실행은 시켜도 테스트는 여전히 로컬 테스트 환경을 사용하기도 합니다. 개발 환경과 배포 환경 사이의 의존성 차이 때문에 컨테이너 내부에서 테스트 환경이 구성되어 있지 않을 수도 있고, 디버거를 붙여서 디버깅 하기 어렵기도 합니다. Remote debugger를 지원하는 언어들도 있지만 테스트를 실행하고 나서 디버거를 연결해야 한다거나, IDE에서 테스트 버튼 하나 눌러서 디버깅을 하기 어려운 등의 난관이 있습니다.

반면 로컬 테스트 환경을 사용할 경우 integration test, acceptance test 진행 시 외부 디펜던시 연결이 상당히 귀찮은 문제가 발생합니다. docker-compose를 잘 구성해두면 커맨드 하나로 test db들을 다 띄워서 손쉽게 연결할 수 있는 반면, 로컬 환경을 사용하면 mysql 띄우고, redis 띄우고, es 띄워서 해당 host들 환경 변수로 다 따로 설정해줘야 하죠. 그거 귀찮다고 unit test만 구성할 수는 없잖아요?

구성 방법

자세한 내용은 https://code.visualstudio.com/docs/remote/containers 문서에서 확인할 수 있습니다. 이 글에서는 기본적인 설정 방법만 간단하게 적어보겠습니다.

VS Code의 Remote Container extension을 사용하면 컨테이너 내부에 개발 환경을 설정할 수 있습니다. docker-compose와 비슷한 방식으로 Dockerfile을 활용해서 개발 환경을 설정하는 방식이죠. 프로젝트 루트에 .devcontainer 폴더를 만들고 devcontainer.json 파일을 추가해서 개발 환경을 설정합니다.

{
    "name": "Python 3",
    "dockerComposeFile": [
        "../docker-compose.yml",
        "docker-compose.yml"
    ],
    "service": "test",
    "workspaceFolder": "/app",
    "settings": {
        "python.pythonPath":
        "/usr/local/bin/python",
        "python.linting.flake8Enabled": true,
        "python.testing.pytestEnabled": true
    },
    "postCreateCommand": "apt-get update && apt-get install -y git && pip3 install flake8",
    "extensions": [
        "ms-python.python",
        "littlefoxteam.vscode-python-test-adapter"
    ]
}

위 파일은 python 프로젝트를 위한 devcontainer.json 파일 예시입니다. 프로젝트 실행을 위한 docker-compose.yml 를 추가하고, 개발 시 특정 값을 덮어쓰기 위해 .devcontainer/docker-compose.yml 도 함께 설정합니다.

settings 필드에는 공통적으로 사용할 vs code 설정 값을 추가합니다. 개발자마다 다르게 설정할 수 있는 값은 각자 로컬 설정 파일에 추가하면 됩니다.

postCreateCommand 를 사용해서 개발에 필요한 디펜던시들을 추가합니다. 이 부분은 당연히 배포를 위한 Docker 이미지에는 포함되지 않습니다.

extensions 에는 VS Code에서 사용할 extension을 추가합니다. 컨테이너 내부에서 실행되는 환경이기 때문에 vs code 실행 후 설치한 extension 들은 해당 이미지를 다시 빌드시 다 사라집니다. 이 곳에 추가해두면 이미지를 빌드할 때마다 해당 extension 들을 설치한 상태로 vs code가 실행되게 됩니다.

실행 방법

extension이 잘 설치되어 있고 .devcontainer 폴더가 잘 구성했다면 Remote-Container: Reopen in Container 커맨드를 실행합니다.


짜잔, 컨테이너 환경에서 VS Code가 실행되었습니다!

Conclusion

해당 기능은 2019년 5월에 처음 나온 따끈따끈한 기능입니다. 그만큼 아직 불안정한 부분도 있습니다. 하지만 테스트 결과 충분히 시도할 만한 가치가 있습니다. 프로젝트에 신규 개발자가 들어올 때마다 일일이 가서 세팅해주는 일은 이제 슬슬 필요 없을 때가 된 듯 합니다.

컨테이너 기반 IDE 설정의 장점

  • rvm, virtualenv 등 프로젝트별 개발 환경 설정이 따로 필요하지 않다.
  • DB 등 외부 서비스 의존성이 있는 테스트 진행이 매우 수월하다.
  • 개발자 사이 개발 환경을 손쉽게 맞출 수 있다.

컨테이너 기반 IDE 설정의 단점

  • 자원을 많이 사용한다.
  • 따라서 배터리 소모가 크다.
  • Intellisense 등의 기능이 약간 느릴 수 있다.

Author: Whale Lee / Chief Architect

  • #VS Code
  • #Docker
  • #Container
  • #Engineering