Docker Compose 사용
Docker Compose는 함께 작동하는 여러 컨테이너를 오케스트레이션하는 방법을 제공합니다. 예로는 요청을 처리하는 서비스와 프런트엔드 웹 사이트, 또는 Redis 캐시와 같은 지원 기능을 사용하는 서비스가 있습니다. 앱 개발에 마이크로서비스 모델을 사용하는 경우, Docker Compose를 사용하여 앱 코드를 웹 요청을 통해 통신하는 여러 독립 실행형 서비스로 분할할 수 있습니다. 이 문서는 Node.js, Python 또는 .NET 앱에 Docker Compose를 사용하도록 설정하고 이러한 시나리오에 대한 Visual Studio Code에서 디버깅을 구성하는 데 도움이 됩니다.
또한, 단일 컨테이너 시나리오의 경우 Docker Compose를 사용하면 단일 Dockerfile이 제공하지 않는 방식으로 도구 독립적인 구성을 제공합니다. 컨테이너에 대한 볼륨 마운트, 포트 매핑, 환경 변수와 같은 구성 설정은 docker-compose YML 파일에 선언할 수 있습니다.
Container Tools 확장을 사용하여 VS Code에서 Docker Compose를 사용하려면 Docker Compose의 기본 사항을 이미 알고 있어야 합니다.
프로젝트에 Docker Compose 지원 추가
하나 이상의 Dockerfile이 이미 있는 경우, 명령 팔레트( ⇧⌘P (Windows, Linux Ctrl+Shift+P))를 열고 Containers: Add Docker Compose Files to Workspace 명령을 사용하여 프로젝트에 Docker Compose 파일을 추가할 수 있습니다. 프롬프트를 따르세요.
Dockerfile을 추가할 때 동시에 프로젝트에 Docker Compose 파일을 추가할 수 있습니다. 명령 팔레트( ⇧⌘P (Windows, Linux Ctrl+Shift+P))를 열고 Containers: Add Docker Files to Workspace 명령을 사용하십시오. Docker Compose 파일을 추가할지 묻는 메시지가 표시됩니다. 기존 Dockerfile을 유지하려면 Dockerfile 덮어쓰기 프롬프트에서 No를 선택하십시오.
Container Tools 확장은 docker-compose.yml 파일을 프로젝트에 추가합니다. 이 파일에는 프로덕션 환경에서 예상대로 컨테이너를 시작하는 구성이 포함되어 있습니다. 경우에 따라 docker-compose.debug.yml 파일도 생성됩니다. 이 파일은 디버거를 시작하는 간소화된 모드를 제공합니다.

VS Code Container Tools 확장은 즉시 사용할 수 있는 파일을 생성하지만, 시나리오에 최적화하도록 사용자 지정할 수도 있습니다. 그런 다음 Containers: Compose Up 명령(docker-compose.yml 파일을 마우스 오른쪽 버튼으로 클릭하거나 명령 팔레트에서 명령을 찾기)을 사용하여 모든 것을 한 번에 시작할 수 있습니다. VS Code의 명령 프롬프트 또는 터미널 창에서 docker-compose up 명령을 사용하여 컨테이너를 시작할 수도 있습니다. Docker Compose 동작을 구성하는 방법과 사용 가능한 명령줄 옵션에 대해서는 Docker Compose 설명서를 참조하십시오.
docker-compose 파일을 사용하면 .json 구성 파일이 아닌 docker-compose 파일에 포트 매핑을 지정할 수 있습니다. 예시는 Docker Compose 설명서를 참조하십시오.
팁: Docker Compose를 사용할 때 호스트 포트를 지정하지 마십시오. 대신 Docker가 자동으로 사용 가능한 포트를 선택하도록 하여 포트 충돌 문제를 피하십시오.
프로젝트에 새 컨테이너 추가
다른 앱이나 서비스를 추가하려면 Containers: Add Docker Compose Files to Workspace 명령을 다시 실행하고 기존 docker-compose 파일을 덮어쓰도록 선택할 수 있지만, 해당 파일의 사용자 지정 내용은 손실됩니다. Compose 파일의 변경 사항을 보존하려면 docker-compose.yml 파일을 수동으로 수정하여 새 서비스를 추가해야 합니다. 일반적으로 기존 서비스 섹션을 복사하여 새 항목으로 붙여넣고 새 서비스에 적합한 이름을 변경하면 됩니다.
Containers: Add Docker Files to Workspace 명령을 다시 실행하여 새 앱에 대한 Dockerfile을 생성할 수 있습니다. 각 앱 또는 서비스에는 자체 Dockerfile이 있지만, 일반적으로 워크스페이스당 하나의 docker-compose.yml 파일과 하나의 docker-compose.debug.yml 파일이 있습니다.
Python 프로젝트에서는 Dockerfile, .dockerignore, docker-compose*.yml 파일이 모두 워크스페이스의 루트 폴더에 있습니다. 다른 앱이나 서비스를 추가할 때 Dockerfile을 해당 앱의 폴더로 이동하십시오.
Node.js 프로젝트에서는 Dockerfile 및 .dockerignore 파일이 해당 서비스의 package.json 옆에 있습니다.
.NET의 경우, 폴더 구조는 Docker Compose 파일을 만들 때 여러 프로젝트를 처리하도록 이미 설정되어 있습니다. .dockerignore 및 docker-compose*.yml 파일은 워크스페이스 루트에 배치됩니다(예: 프로젝트가 src/project1에 있는 경우 파일은 src에 있음). 따라서 다른 서비스를 추가할 때 project2와 같은 폴더에 다른 프로젝트를 만들고 이전에 설명한 대로 compose 파일을 다시 만들거나 수정합니다.
디버그
먼저, 대상 플랫폼의 디버깅 설명서를 참조하여 VS Code에서 컨테이너 내 디버깅의 기본 사항을 이해하십시오.
Docker Compose에서 디버깅하려면 이전 섹션에서 설명한 두 가지 Docker Compose 파일 중 하나를 사용하여 Containers: Compose Up 명령을 실행한 다음, 해당 Attach 실행 구성을 사용하여 연결하십시오. 일반 실행 구성을 사용하여 직접 시작하는 것은 Docker Compose를 사용하지 않습니다.
Attach 실행 구성을 만듭니다. 이는 launch.json의 한 섹션입니다. 이 프로세스는 대부분 수동이지만, 경우에 따라 Container Tools 확장이 템플릿으로 사용하고 사용자 지정할 수 있는 미리 구성된 실행 구성을 추가하여 도움이 될 수 있습니다. 각 플랫폼(Node.js, Python, .NET)에 대한 프로세스는 다음 섹션에 설명되어 있습니다.
Node.js
-
Debug 탭에서 Configuration 드롭다운을 선택하고, New Configuration을 선택한 다음,
Containers: Attach구성 템플릿인 Containers: Attach to Node를 선택합니다. -
docker-compose.debug.yml에서 디버깅 포트를 구성합니다. 이 파일은 파일을 만들 때 설정되므로 변경할 필요가 없을 수 있습니다. 아래 예에서는 호스트와 컨테이너 모두에서 디버깅을 위해 포트 9229가 사용됩니다.version: '3.4' services: node-hello: image: node-hello build: . environment: NODE_ENV: development ports: - 3000 - 9229:9229 command: node --inspect=0.0.0.0:9229 ./bin/www -
여러 앱이 있는 경우 일부 앱의 포트를 변경해야 각 앱에 고유한 포트가 있도록 합니다.
launch.json에서 올바른 디버깅 포트를 가리키고 파일을 저장할 수 있습니다. 이를 생략하면 포트가 자동으로 선택됩니다.다음은 Node.js 실행 구성 - Attach를 보여주는 예입니다.
"configurations": [ { "type": "node", "request": "attach", "name": "Containers: Attach to Node", "remoteRoot": "/usr/src/app", "port": 9229 // Optional; otherwise inferred from the docker-compose.debug.yml. }, // ... ] -
Attach 구성 편집이 완료되면
launch.json을 저장하고 새 실행 구성을 활성 구성으로 선택합니다. Debug 탭에서 Configuration 드롭다운에서 새 구성을 찾습니다.
-
docker-compose.debug.yml파일을 마우스 오른쪽 버튼으로 클릭하고 Compose Up을 선택합니다. -
HTML을 반환하는 HTTP 엔드포인트를 노출하는 서비스에 연결하면 웹 브라우저가 자동으로 열리지 않습니다. 브라우저에서 앱을 열려면 사이드바에서 컨테이너를 선택하고 마우스 오른쪽 버튼을 클릭한 다음 Open in Browser를 선택합니다. 여러 포트가 구성된 경우 어떤 포트를 사용할지 묻는 메시지가 표시됩니다.
-
일반적인 방식으로 디버거를 시작합니다. Debug 탭에서 녹색 화살표(Start 버튼)를 선택하거나 F5를 사용합니다.
Python
Docker Compose로 Python을 디버깅하려면 다음 단계를 따르십시오.
-
Debug 탭에서 Configuration 드롭다운을 선택하고, New Configuration을 선택한 다음, Python Debugger를 선택하고,
Remote Attach구성 템플릿을 선택합니다.
-
디버깅에 사용할 호스트 머신(예: localhost)과 포트를 선택하라는 메시지가 표시됩니다. Python의 기본 디버깅 포트는 5678입니다. 여러 앱이 있는 경우 각 앱에 고유한 포트가 있도록 앱 중 하나의 포트를 변경해야 합니다.
launch.json에서 올바른 디버깅 포트를 가리키고 파일을 저장할 수 있습니다. 이를 생략하면 포트가 자동으로 선택됩니다."configurations": [ { "name": "Python Debugger: Remote Attach", "type": "debugpy", "request": "attach", "port": 5678, "host": "localhost", "pathMappings": [ { "localRoot": "${workspaceFolder}", "remoteRoot": "/app" } ] } -
Attach 구성 편집이 완료되면
launch.json을 저장합니다. Debug 탭으로 이동하여 활성 구성으로 Python Debugger: Remote Attach를 선택합니다. -
유효한 Dockerfile이 이미 있는 경우, Containers: Add Docker Compose Files to Workspace 명령을 실행하는 것이 좋습니다. 이렇게 하면
docker-compose.yml파일과 Python 디버거를 컨테이너에서 볼륨 마운트하고 시작하는docker-compose.debug.yml파일이 생성됩니다. 아직 Dockerfile이 없는 경우, Containers: Add Docker Files to Workspace 명령을 실행하고 Docker Compose 파일을 포함할지 묻는 메시지에서 Yes를 선택하는 것이 좋습니다.참고: 기본적으로 Containers: Add Docker Files to Workspace를 사용할 때 Django 및 Flask 옵션을 선택하면 Gunicorn에 구성된 Dockerfile이 스캐폴드됩니다. 계속 진행하기 전에 Python 컨테이너 빠른 시작 설명서의 지침을 따라 올바르게 구성되었는지 확인하십시오.
-
docker-compose.debug.yml파일을 마우스 오른쪽 버튼으로 클릭하고(아래 예시 참조) Compose Up을 선택합니다.version: '3.4' services: pythonsamplevscodedjangotutorial: image: pythonsamplevscodedjangotutorial build: context: . dockerfile: ./Dockerfile command: ["sh", "-c", "pip install debugpy -t /tmp && python /tmp/debugpy --wait-for-client --listen 0.0.0.0:5678 manage.py runserver 0.0.0.0:8000 --nothreading --noreload"] ports: - 8000:8000 - 5678:5678 -
컨테이너가 빌드되고 실행되면, Python Debugger: Remote Attach 실행 구성이 선택된 상태에서 F5를 눌러 디버거를 연결하십시오.

참고: Python 디버거를 특정 파일로 가져오려면 debugpy README에서 자세한 정보를 찾을 수 있습니다.
-
HTML을 반환하는 HTTP 엔드포인트를 노출하는 서비스에 연결하면 웹 브라우저가 자동으로 열리지 않을 수 있습니다. 브라우저에서 앱을 열려면 Container Explorer에서 컨테이너를 마우스 오른쪽 버튼으로 클릭하고 Open in Browser를 선택합니다. 여러 포트가 구성된 경우 어떤 포트를 사용할지 묻는 메시지가 표시됩니다.

이제 컨테이너에서 실행 중인 앱을 디버깅하고 있습니다.
.NET
-
Debug 탭에서 Configuration 드롭다운을 선택하고, New Configuration을 선택한 다음,
Container Attach구성 템플릿인 Containers: .NET Attach (Preview)를 선택합니다. -
VS Code는 호스트 머신에서 대상 컨테이너로
vsdbg를 기본 경로를 사용하여 복사하려고 합니다. Attach 구성에서vsdbg의 기존 인스턴스에 대한 경로를 제공할 수도 있습니다."netCore": { "debuggerPath": "/remote_debugger/vsdbg" } -
Attach 구성 편집이 완료되면
launch.json을 저장하고 새 실행 구성을 활성 구성으로 선택합니다. Debug 탭에서 Configuration 드롭다운에서 새 구성을 찾습니다. -
docker-compose.debug.yml파일을 마우스 오른쪽 버튼으로 클릭하고 Compose Up을 선택합니다. -
HTML을 반환하는 HTTP 엔드포인트를 노출하는 서비스에 연결하면 웹 브라우저가 자동으로 열리지 않습니다. 브라우저에서 앱을 열려면 사이드바에서 컨테이너를 선택하고 마우스 오른쪽 버튼을 클릭한 다음 Open in Browser를 선택합니다. 여러 포트가 구성된 경우 어떤 포트를 사용할지 묻는 메시지가 표시됩니다.
-
일반적인 방식으로 디버거를 시작합니다. Debug 탭에서 녹색 화살표(Start 버튼)를 선택하거나 F5를 사용합니다.

-
컨테이너에서 실행 중인 .NET 앱에 연결하려고 하면 앱의 컨테이너를 선택하라는 프롬프트가 표시됩니다.

이 단계를 건너뛰려면 launch.json의 Attach 구성에서 컨테이너 이름을 지정하십시오.
"containerName": "Your ContainerName"다음으로, 디버거(
vsdbg)를 컨테이너로 복사할지 묻는 메시지가 표시됩니다. Yes를 선택합니다.
모든 것이 올바르게 구성되었다면 디버거가 .NET 앱에 연결되어야 합니다.

볼륨 마운트
기본적으로 Container Tools 확장은 디버깅 구성 요소에 대한 볼륨 마운트를 수행하지 않습니다. .NET 또는 Node.js에서는 필요한 구성 요소가 런타임에 내장되어 있으므로 필요하지 않습니다. 앱에 볼륨 마운트가 필요한 경우 docker-compose*.yml 파일의 volumes 태그를 사용하여 지정하십시오.
volumes:
- /host-folder-path:/container-folder-path
여러 Compose 파일로 Docker Compose 사용
워크스페이스는 개발, 테스트, 프로덕션과 같은 다양한 환경을 처리하기 위해 여러 docker-compose 파일을 가질 수 있습니다. 구성의 내용은 여러 파일로 분할될 수 있습니다. 예를 들어, 모든 환경에 대한 일반 정보를 정의하는 기본 Compose 파일과 환경별 정보를 정의하는 별도의 오버라이드 파일입니다. 이 파일들을 docker-compose 명령에 입력으로 전달하면, 이 파일들이 단일 구성으로 결합됩니다. 기본적으로 Containers: Compose Up 명령은 단일 파일을 Compose 명령에 입력으로 전달하지만, 명령 사용자 지정을 사용하여 여러 파일을 전달하도록 compose up 명령을 사용자 지정할 수 있습니다. 또는 사용자 지정 작업을 사용하여 원하는 매개변수로 docker-compose 명령을 호출할 수 있습니다.
참고: 워크스페이스에
docker-compose.yml및docker-compose.override.yml만 있고 다른 Compose 파일이 없는 경우,docker-compose명령은 입력 파일 없이 호출되며 암시적으로 이 파일들을 사용합니다. 이 경우 사용자 지정이 필요하지 않습니다.
명령어 사용자 지정
명령 사용자 지정은 요구 사항에 따라 compose up 명령을 사용자 지정하는 다양한 방법을 제공합니다. 다음은 compose up 명령에 대한 몇 가지 샘플 명령 사용자 지정입니다.
기본 파일 및 오버라이드 파일
워크스페이스에 기본 Compose 파일(docker-compose.yml)과 각 환경에 대한 오버라이드 파일(docker-compose.dev.yml, docker-compose.test.yml 및 docker-compose.prod.yml)이 있고 항상 기본 파일과 오버라이드 파일을 사용하여 docker compose up을 실행한다고 가정해 보겠습니다. 이 경우 compose up 명령은 다음 예와 같이 사용자 지정할 수 있습니다. compose up 명령이 호출되면 ${configurationFile}은 선택한 파일로 대체됩니다.
"docker.commands.composeUp": [
{
"label": "override",
"template": "docker-compose -f docker-compose.yml ${configurationFile} up -d --build",
}
]
템플릿 일치
각 환경에 대해 다른 입력 파일 세트가 있다고 가정해 보겠습니다. 정규식 일치와 함께 여러 템플릿을 정의할 수 있으며, 선택한 파일 이름은 이 match 속성과 일치하고 해당 템플릿이 사용됩니다.
"containers.commands.composeUp": [
{
"label": "dev-match",
"template": "docker-compose -f docker-compose.yml -f docker-compose.debug.yml -f docker-compose.dev.yml up -d --build",
"match": "dev"
},
{
"label": "test-match",
"template": "docker-compose -f docker-compose.yml -f docker-compose.debug.yml -f docker-compose.test.yml up -d --build",
"match": "test"
},
{
"label": "prod-match",
"template": "docker-compose -f docker-compose.yml -f docker-compose.release.yml -f docker-compose.prod.yml up -d --build",
"match": "prod"
}
]
명령 호출 시 템플릿 선택
명령 템플릿에서 match 속성을 생략하면 compose up 명령이 호출될 때마다 사용할 템플릿을 묻는 메시지가 표시됩니다. 예:
"containers.commands.composeUp": [
{
"label": "dev",
"template": "docker-compose -f docker-compose.yml -f docker-compose.common.dev.yml ${configurationFile} up -d --build"
},
{
"label": "test",
"template": "docker-compose -f docker-compose.yml -f docker-compose.common.test.yml ${configurationFile} up -d --build"
},
{
"label": "prod",
"template": "docker-compose -f docker-compose.yml -f docker-compose.common.prod.yml ${configurationFile} up -d --build"
},
],
사용자 지정 작업
명령 사용자 지정 대신 다음을 사용하여 docker-compose 명령을 호출하는 작업을 정의할 수도 있습니다. 이 옵션에 대한 자세한 내용은 사용자 지정 작업을 참조하십시오.
{
"type": "shell",
"label": "compose-up-dev",
"command": "docker-compose -f docker-compose.yml -f docker-compose.Common.yml -f docker-compose.dev.yml up -d --build",
"presentation": {
"reveal": "always",
"panel": "new"
}
}