VS Code로 컨테이너 검사하기
2019년 10월 31일 작성자 Bowden Kelly, @bowdenk7
컨테이너화된 애플리케이션을 개발할 때, `docker exec --it {containerID} /bin/sh`를 사용하여 실행 중인 컨테이너에 셸을 연결하여 빌드 및 런타임 문제를 디버깅하는 것이 일반적입니다.

이 기법을 사용하면 명령줄을 통해 컨테이너 환경을 검사할 수 있지만, 문제를 진단하기 위한 풍부한 도구를 제공하지는 않습니다.
이 게시물에서는 Visual Studio Code를 컨테이너에 연결하여 VS Code의 전체 기능을, 디버깅을 포함하여 컨테이너를 검사하고, 문제가 발생한 원인을 파악하고, 해결하는 방법을 살펴보겠습니다.
올해 5월에 출시된 Dev Containers 확장 프로그램은 개인 설정, 테마 및 키 바인딩을 모두 유지하면서 로컬 VS Code를 컨테이너 호스트에 연결할 수 있게 해줍니다.
전제 조건
이 블로그 게시물은 Docker Desktop과 Visual Studio Code가 설치되어 있다고 가정합니다. 또한 Dev Containers 확장 프로그램도 필요합니다. Dev Containers 확장 프로그램을 설치하려면 확장 보기(⇧⌘X (Windows, Linux Ctrl+Shift+X))를 열고 "Dev Containers"를 검색한 다음 **설치**를 선택하고, 필요한 경우 VS Code를 다시 시작합니다.
애플리케이션
가장 먼저 필요한 것은 컨테이너에서 실행할 수 있는 애플리케이션입니다. 이미 가지고 있다면 좋습니다! 이 단계를 건너뛰어도 됩니다. 그렇지 않다면 이 간단한 Node.js Express 애플리케이션을 복제할 수 있습니다.
참고: 로컬에 Node.js를 설치할 필요는 없습니다. 이 애플리케이션은 컨테이너에서 실행됩니다!
git clone https://github.com/microsoft/vscode-express-sample.git
이 애플리케이션은 Node 10 이미지를 기반으로 하는 간단한 Dockerfile과 이미지를 실행하고, 적절한 포트를 노출하며, 로컬 파일 시스템을 매핑하는 데 사용할 `docker-compose.yml` 파일을 가지고 있습니다. 로컬에서 실행할 때와 마찬가지로 앱을 디버깅할 수 있도록 `–inspect` 플래그와 함께 Node를 실행하고 있습니다. 실제 애플리케이션에서는 프로덕션 배포를 위해 별도의 Docker Compose 파일을 사용하는 것이 좋을 것입니다.
참고: Docker Compose 파일이 없어도 됩니다. 단일 Dockerfile로 생성된 컨테이너에 연결할 수도 있습니다.
빌드 및 실행
애플리케이션을 빌드하고 실행하려면 먼저 종속성을 설치한 다음 터미널/명령 프롬프트에서 `docker-compose up`을 실행합니다. 이렇게 하면 Node 기본 이미지를 다운로드하고, 종속성을 복사하고, 컨테이너를 시작합니다.
docker-compose up
모든 것이 제대로 작동했다면 다음과 같은 출력을 볼 수 있습니다.

그리고 https://:3000으로 이동하여 다음을 볼 수 있어야 합니다.

컨테이너에 연결
이제 Dev Containers 확장 프로그램을 사용하여 실행 중인 컨테이너에 연결하고, 환경을 검사하고, 애플리케이션을 디버깅할 수 있습니다.
활동 표시줄에서 원격 탐색기를 선택하여 **기타 컨테이너** 섹션에서 연결할 수 있는 실행 중인 컨테이너 목록을 확인합니다. 방금 시작한 컨테이너, 즉 이름이 'express_server_1'인 컨테이너를 찾은 다음, **컨테이너에 연결** 버튼을 사용하여 연결합니다. 이제 해당 컨테이너는 원격 탐색기의 **연결된 컨테이너** 섹션에 표시되어야 합니다.

그러면 다음과 같은 알림이 오른쪽 하단에 표시되는 새 VS Code 창(인스턴스)이 열립니다.

이 시간 동안 VS Code는 앱이 실행 중인 컨테이너 내에 VS Code **서버** 인스턴스를 설치하고 있습니다. 이 설치 단계의 자세한 내용과 진행 상황을 보려면 알림에 표시된 **자세히 보기** 링크를 선택할 수 있습니다. VS Code 서버가 설치되면 로컬 VS Code 클라이언트가 원격 VS Code 서버에 연결됩니다. 결과적으로 모든 설정, 테마 및 키 바인딩을 갖춘 로컬 VS Code 인스턴스가 애플리케이션과 함께 컨테이너 내부에서 실행되는 "백엔드"에 연결됩니다.

연결이 완료되면 화면 왼쪽 하단에 녹색 표시등이 있는 새 VS Code 창이 표시됩니다. 이 표시등은 이 VS Code 인스턴스가 원격 컨텍스트에서 실행되고 있음을 나타냅니다. 표시등을 클릭하면 현재 원격 컨텍스트와 관련된 명령 목록이 있는 드롭다운 메뉴가 표시됩니다.

**폴더 열기** 버튼을 선택하고 `/usr/src/app`으로 이동하여 앱을 열겠습니다. **폴더 열기** 대화 상자가 로컬 파일 시스템이 아닌 실행 중인 컨테이너의 파일 시스템을 표시한다는 점에 유의하십시오.

소스 폴더를 연 후, 편집기에 `express-server.json`이라는 파일 이름으로 열린 것을 발견하게 됩니다. 이 이름은 연결한 컨테이너 이미지 이름에서 파생됩니다. 예시에서 docker-compose는 `docker-compose.yml` 파일에 정의된 폴더 이름 `express`와 서비스 이름 `server`에서 파생된 'express_server'라는 이미지 이름을 생성합니다. 이 파일은 이미지와 관련된 구성 파일이며, 이 이미지를 기반으로 하는 컨테이너에 연결할 때 구성 설정을 기억합니다. 자동 저장 기능이 켜져 있지 않다면 이 파일을 저장해야 합니다. 이제 향후 세션에서는 이 이미지에 연결할 때 VS Code가 이 소스 폴더를 다시 열 것입니다.
참고: 명령 팔레트(⇧⌘P (Windows, Linux Ctrl+Shift+P))에서 **컨테이너 구성 파일 열기** 명령을 실행하여 현재 개발 컨테이너의 이 파일을 볼 수 있습니다.

이 시점에서 VS Code는 일반 로컬 VS Code 창과 동일하게 보입니다.

일반 로컬 VS Code 컨텍스트에서 할 수 있는 모든 작업을 수행할 수 있습니다.
예를 들어 `app.js`를 엽니다. 8행을 마우스 오른쪽 버튼으로 클릭하고 **모든 참조 찾기**를 실행하여 `usersRouter`의 모든 사용량을 찾습니다. docker-compose 파일을 사용하여 로컬 파일 시스템을 컨테이너에 마운트했기 때문에 모든 편집 내용은 로컬 디스크에 유지됩니다.
컨테이너 내부에서 디버그
개발 컨테이너가 로컬 환경과 얼마나 유사한지 더 보여주기 위해 디버거를 연결해 보겠습니다. `docker-compose.yaml`에서 `--inspect` 매개변수를 사용하여 Node 앱을 시작했으므로, 해당 프로세스에 디버거를 연결하기만 하면 됩니다.
명령 팔레트(⇧⌘P (Windows, Linux Ctrl+Shift+P))에서 "Node 프로세스에 연결"을 검색하고 선택합니다. 컨테이너 내에서 여러 Node 프로세스가 실행 중일 수 있습니다. 우리의 애플리케이션을 실행하는 프로세스를 선택해야 하므로, `bin/www`를 표시하는 것을 선택합니다.

다음으로, `index.js`를 열고 여백을 클릭하거나 F9을 눌러 6행에 중단점을 설정합니다.
res.render('index', { title: 'Express' });
이제 브라우저에서 https://:3000으로 이동하여 중단점이 예상대로 트리거되는 것을 확인하세요!
확장 프로그램 설치
일반 VS Code 인스턴스와 마찬가지로 개발 컨테이너에 연결된 동안 확장 프로그램을 설치하고 사용할 수 있습니다.
확장 프로그램 유형에 따라 클라이언트 측에서 실행되거나 원격 VS Code 서버의 컨테이너에서 실행될 수 있습니다. 테마 및 스니펫과 같은 주로 UI 기반 확장 프로그램은 클라이언트 측에 유지되는 반면, 다른 모든 확장 프로그램은 컨테이너에 설치됩니다. 이를 통해 각 환경에서 작업할 때 필요한 확장 프로그램만 가지고 있으면서 모든 환경에서 일관된 UI를 유지할 수 있습니다.
확장 보기(⇧⌘X (Windows, Linux Ctrl+Shift+X))를 열면 로컬에 설치된 확장 프로그램 목록과 현재 컨테이너 인스턴스에 설치된 확장 프로그램 목록이 표시됩니다. 컨테이너에 설치해야 하는 로컬 설치 확장 프로그램(아래의 Azure 계정 확장 프로그램과 같은)은 회색으로 표시됩니다.

확장 보기에서 'gitlens'를 입력하고 **연결된 컨테이너에 설치**를 선택하여 GitLens 확장 프로그램을 설치해 보겠습니다.

이렇게 하면 VS Code를 다시 시작하라는 메시지가 표시되고, 다시 시작하면 새로 설치된 확장 프로그램과 함께 컨테이너 및 VS Code 서버가 다시 시작될 때 **개발 컨테이너 설치 중**이라는 알림이 잠시 표시됩니다.
또한 이전에 보았던 컨테이너 구성 파일이 다시 열리고, 이 이미지에 연결할 때마다 설치되기를 원하는 확장 프로그램을 나열하는 새 속성으로 업데이트되었음을 알 수 있습니다.
{
"workspace": "/usr/src/app",
"extensions": ["eamodio.gitlens"]
}
이제 파일을 열고 코드 줄을 선택하면 GitLens에서 제공하는 인라인 Git 정보가 표시됩니다!

정리
완료되면 명령 팔레트에서 **원격 연결 닫기** 명령을 실행하거나 VS Code 창을 닫아 원격 연결을 종료할 수 있습니다.
이제 터미널/명령 프롬프트에서 `docker-compose down`을 실행하여 실행 중인 컨테이너를 중지합니다. 이렇게 하면 메모리가 해제되고 사용된 포트가 릴리스됩니다.
docker-compose down
이제 다른 컨테이너를 시작하고 다른 프로젝트를 작업할 준비가 되었습니다!
다음 단계
이 블로그 게시물에서는 Dev Containers 확장 프로그램을 사용하여 기존 컨테이너화된 애플리케이션에 연결하는 방법을 다루었습니다.
개발하려는 개발 환경을 설명하는 `devcontainer.json` 파일을 만들 수도 있습니다. 이 파일은 프로젝트와 함께 저장되어 팀원들과 공유할 수 있습니다.
다른 유용한 자료로는 전체 컨테이너 내 개발 문서, 고급 컨테이너 구성, 그리고 Dev Containers 확장 프로그램을 사용하여 격리된 개발 환경을 구축하는 입문 튜토리얼이 있습니다.
행복한 원격 코딩,
Bowden Kelly, VS Code 프로그램 관리자 @bowdenk7