사용자 지정 개발 컨테이너 기능
2022년 9월 15일, Brigit Murtaugh 작성, @BrigitMurtaugh
개발 환경을 설정할 때 "아, 이거 하나만 더 있으면 되는데!"라는 순간을 모두 겪어보셨을 겁니다. 그 "하나"는 프로젝트를 위해 필요한 언어나 도구 세트(혹은 몇 개 더 😊)일 수 있습니다.
개발 컨테이너는 환경 설정을 간소화하는 좋은 방법입니다. 프로젝트에 필요한 도구가 포함된 완전한 코딩 환경을 제공합니다. 이 컨테이너는 이미지, Dockerfile 또는 Docker Compose 파일과 devcontainer.json을 사용하여 구성됩니다. devcontainer.json은 개발에 특화된 콘텐츠와 설정을 컨테이너에 풍부하게 제공하는 데 사용되는 메타데이터 형식입니다.
개발 컨테이너를 생성할 때 "이거 하나만 더 있으면 되는데!"라는 반응을 반복적으로 경험할 수 있습니다. Dockerfile에서 Node.js 이미지를 사용하고 있는데 Git만 추가하면 되는 경우일 수도 있습니다. 아니면 개발 컨테이너 내에서 Docker나 Kubernetes와 같은 더 복잡한 작업을 해야 할 수도 있습니다. 개발 컨테이너는 코드를 액세스하는 모든 사람이 추가한 모든 도구에 대해 동일하고 일관된 환경을 경험할 수 있다는 점에서 훌륭하지만, 이를 추가하는 가장 좋은 방법은 무엇일까요?
도구 이름과 버전만 언급하면 개발 컨테이너에 해당 추가 도구를 쉽게 설치할 수 있는 방법이 있다면 어떨까요? 아니면 도구 사용자 또는 작성자가 다른 사람들이 쉽게 설치할 수 있는 방법을 만들 수 있다면 어떨까요? 수동 스크립트를 공유하면 재사용에 도움이 될 수 있지만, 이를 참조할 때 Go, Rust 또는 C++ 디버깅을 위한 ptrace 지원 활성화, 컨테이너 시작 시 실행될 특정 진입점 추가, 올바른 VS Code 확장 포함 등과 같은 컨테이너 또는 도구 설정을 참조하는 것을 잊어버릴 수 있습니다.
기능
개발 컨테이너 **기능(Features)**이 개발 컨테이너에서 필요한 도구를 원활하게 얻을 수 있도록 도와준다는 소식을 기쁘게 전해드립니다!
기능은 개발 컨테이너에서 새로운 개발 기능을 활성화하도록 설계된 설치 코드, 컨테이너 구성 및/또는 설정 및 확장으로 구성된 자체 포함 단위입니다. 다양한 기본 컨테이너 이미지와 함께 작동하도록 구축될 수 있습니다. **개방형 개발 컨테이너 사양**에 대한 작업의 일환으로, 미리 만들어진 기능을 가져올 수 있는 곳과 자신만의 기능을 작성하고 배포하는 방법에 대한 몇 가지 개선 사항을 적용했습니다.
개발 컨테이너를 지원하는 모든 도구나 서비스(예: VS Code 개발 컨테이너 확장 또는 GitHub Codespaces)에서 새로운 기능과 시작 방법을 살펴보겠습니다!
개발 컨테이너에 기능 추가하기
개발 컨테이너 기능은 설치 단계와 개발 컨테이너 메타데이터를 빠르게 연결하는 방법을 제공합니다. 간단한 참조를 통해 개발 컨테이너에 추가할 수 있습니다.
이러한 기능은 이제 지원되는 모든 컨테이너 레지스트리에서 OCI 아티팩트로 저장될 수 있습니다. 즉, 컨테이너 이미지를 참조하는 것과 동일한 유형의 식별자를 사용하여 참조할 수 있습니다. vscode-dev-containers 리포지토리에 있던 초기 기능 중 일부를 이 새로운 접근 방식을 사용하여 게시하는 새 devcontainers/features 리포지토리로 옮겼습니다.
devcontainers/features 리포지토리의 다양한 기능을 참조하는 것은 devcontainer.json에 features 속성을 추가하는 것만큼 간단합니다. 각 기능에는 기능을 참조하는 방법과 해당 기능에 사용할 수 있는 옵션을 보여주는 README.md 파일이 있습니다.
아래 예시는 go 및 docker-in-docker 기능을 설치하는 방법을 보여줍니다.
"name": "my-project-devcontainer",
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
"features": {
"ghcr.io/devcontainers/features/go:1": {
"version": "1.18"
},
"ghcr.io/devcontainers/features/docker-in-docker:1": {
"version": "latest",
"moby": true
}
}
공식 및 커뮤니티 기여 기능은 사양 사이트에서 탐색할 수도 있습니다. devcontainer.json을 편집하여 모든 기능을 추가할 수 있으며, 공개적으로 게시된 기능은 VS Code 개발 컨테이너 확장과 같이 기존 개발 컨테이너 구성 환경을 통해 추가할 수 있습니다.

개발 컨테이너 CLI, GitHub Action 또는 Azure DevOps 작업을 사용하여 즐겨 사용하는 CI 시스템에서 기능이 포함된 개발 컨테이너를 사용할 수도 있습니다. devcontainers/ci 리포지토리에서 GitHub Action 및 Azure DevOps 작업을 사용할 수 있습니다. 개발 컨테이너 CLI, GitHub Action 또는 Azure DevOps 작업은 시작 시간을 단축하기 위해 기능 콘텐츠가 포함된 이미지를 사전 빌드하는 데에도 사용할 수 있습니다.
공개적으로 사용 가능한 기능을 사용하는 것뿐만 아니라 자신만의 개인 또는 공개 기능을 만들어 공유하고 싶다면 계속 읽어보세요!
작성
자신만의 기능을 만드는 데 도움이 되는 좋은 시작점은 새로운 기능 템플릿 리포지토리입니다. 특정 기능의 콘텐츠에 대한 좋은 템플릿을 포함하는 것 외에도, 템플릿에는 GitHub 컨테이너 레지스트리(GHCR)를 사용하여 가능한 한 빨리 시작할 수 있도록 게시하는 GitHub Actions 워크플로우도 포함되어 있습니다. 게시하는 방법에 대해서는 곧 더 자세히 설명하겠습니다.
기능의 소스 코드는 설치 스크립트(install.sh)와 구성 파일(devcontainer-feature.json)의 두 가지 구성 요소로 이루어집니다.
+-- feature
| +-- devcontainer-feature.json
| +-- install.sh
| +-- (other files)
install.sh: 설치 진입점 스크립트입니다. 개념적으로 이미지의 Dockerfile 레이어로 추가되어 빌드 시간에 실행됩니다. 이 진입점 스크립트는 언어(예: Ruby) 및 도구(GitHub CLI)와 같은 도구를 설치할 수 있습니다.
devcontainer-feature.json: 기능에 대한 메타데이터, 설치 중에 기능의 설치 스크립트로 전달될 수 있는 옵션 집합, 그리고 최종 개발 컨테이너에 병합될 devcontainer.json의 "부분"들을 포함합니다. 예를 들어, 기능 중 하나라도 해당 구성에서 "privileged": true를 지정하면 전체 개발 컨테이너는 --privileged 플래그로 시작됩니다.
기능은 다양한 언어로 작성될 수 있으며, 가장 간단한 것은 쉘 스크립트입니다. 기능이 다른 언어로 작성된 경우, 사용자가 정보에 입각한 선택을 할 수 있도록 메타데이터에 해당 정보가 포함되어야 합니다.
참고: install.sh는 어떤 언어로든 기능을 실행하지만, 개발 컨테이너에 존재하지 않는 인터프리터 언어로 기능을 작성했다면 코드가 실행되지 않습니다. install.sh의 일부로 필요한 언어를 반드시 획득해야 합니다.
공개적으로 릴리스하는 기능은 기능 외에 종속성도 확인하고 설치하도록 해야 합니다.
또한, 공개 기능은 arm64 또는 x86_64 시스템 모두에서 사용될 가능성이 높으므로 가능한 경우 이에 맞춰 조정해야 합니다.
devcontainer-feature.json 속성은 사양에서 검토할 수 있으며, devcontainers/features 리포지토리의 공개 예시도 함께 확인할 수 있습니다.
기능을 만드는 방법을 알아봤는데, 다른 사람에게 배포하는 방법은 무엇일까요?
분포
기능은 tarball로 배포됩니다. tarball에는 devcontainer-feature.json, install.sh 및 해당 디렉터리의 다른 모든 파일을 포함하여 기능 하위 디렉터리의 전체 내용이 포함됩니다.
Open Container Initiative(OCI)는 컨테이너 및 컨테이너 리소스에 대한 산업 표준을 정의합니다. 저희는 기능을 OCI 아티팩트로 취급하고 기능을 배포하기 위해 OCI 레지스트리 개념을 사용합니다.
위에서 언급한 기능 템플릿 리포지토리에는 게시 프로세스를 자동화하는 GitHub Actions 워크플로우가 포함되어 있습니다. 이 워크플로우는 기능을 tarball로 패키지하고 GHCR에 OCI 아티팩트로 에셋을 게시합니다. 템플릿 리포지토리의 release.yaml 워크플로우를 GitHub의 리포지토리 작업 탭 왼쪽에서 선택하여 트리거할 수 있습니다. GitHub Action은 <owner>/<repo> 네임스페이스 아래 GHCR에 해당 기능을 게시합니다. 기능은 devcontainer-feature.json의 버전 속성이 업데이트될 때만 다시 게시됩니다.
참고: GHCR을 사용할 때 한 가지 수동 단계는 OCI 패키지를 "공개"로 표시하는 것입니다. 이 작업은 기능당 한 번만 하면 됩니다. 비공개 기능은 이 단계를 필요로 하지 않으며, 레지스트리 자격 증명으로 Docker CLI에 로그인한 경우 액세스할 수 있습니다.
커뮤니티와 기능 공유하기
기여한 내용이 VS Code 개발 컨테이너 또는 GitHub Codespaces UI에 개발 컨테이너 생성용으로 표시되도록 하려면 다음 단계를 따를 수 있습니다.
- devcontainers.github.io(containers.dev를 지원하는 GitHub 리포지토리)로 이동합니다.
collection-index.yml파일을 수정하기 위해 PR을 엽니다.
병합되면 변경 사항이 containers.dev/collections에 표시됩니다.
기능 설치 순서
내 기능이 다른 기능 후에만 설치되어야 한다면? 기능 작성자는 자신의 기능이 다른 기능보다 먼저 또는 후에 설치되어야 한다고 생각할 수 있습니다. devcontainer-feature.json에서 installsAfter 속성을 사용하여 해당 기능보다 먼저 실행되어야 하는 기능을 나열할 수 있습니다.
최종 사용자는 devcontainer.json의 overrideFeatureInstallOrder 속성을 사용하여 실행 순서를 더욱 제어할 수 있습니다. 이 배열에 있는 모든 기능 ID는 제공된 순서대로 다른 모든 기능보다 먼저 설치됩니다. 예를 들면 다음과 같습니다.
"features": {
"ghcr.io/devcontainers/features/java:1",
"ghcr.io/devcontainers/features/node:1",
},
"overrideFeatureInstallOrder": [
"ghcr.io/devcontainers/features/node"
]
기본적으로 기능은 구현 도구에 의해 최적으로 결정된 순서대로 기본 이미지 위에 설치됩니다.
기능의 devcontainer-feature.json 또는 사용자의 devcontainer.json에 다음 속성 중 하나라도 제공되면, 이러한 속성으로 표시된 순서가 존중됩니다(우선 순위가 낮을수록)..
- 사용자의
devcontainer.json에 있는overrideFeatureInstallOrder속성입니다. 사용자가 기능의 실행 순서를 제어할 수 있도록 합니다. - 기능의
devcontainer-feature.json에 정의된installsAfter속성입니다.
기능 실행 및 설치 순서에 대한 자세한 내용은 사양에서 확인할 수 있습니다.
그 외 새로운 소식은?
새로운 기능 리포지토리와 함께, 최근에는 이전에 vscode-dev-containers 리포지토리에 있던 특정 이미지 세트를 호스팅하는 새 devcontainers/images 리포지토리를 오픈 소스로 공개했습니다.
개발 컨테이너 템플릿(vscode-dev-containers에서 "정의"라고 부르는 것)에 대한 커뮤니티 배포 계획을 개발 중이며, 이는 기능과 유사할 것으로 예상됩니다. 새로운 기능 및 이미지 리포지토리 발표 때와 마찬가지로, vscode-dev-containers 리포지토리에 업데이트를 게시할 것입니다.
더 배우고 싶으시면?
이 게시물은 기능으로 할 수 있는 일의 극히 일부만을 다루고 있으며, 여러분이 직접 사용해보기를 기대합니다!
위 콘텐츠 전체에 링크된 것처럼, 기능에 대해 자세히 알아보고 배포하는 방법을 배울 수 있는 가장 좋은 자료는 개발 컨테이너 사양의 기능 및 기능 배포 페이지입니다.
기능을 사용, 생성 및 게시하면서 피드백을 기다리겠습니다. 여러분에게 기능이 어떻게 작동하는지 기능 및 기능 배포 이슈 제안에서 듣고 싶습니다!
사양 전반에 참여하거나 다른 도구를 연동하여 활용하는 데 관심이 있다면, 개발 컨테이너 사양 및 CLI 리포지토리를 확인하십시오.
즐거운 개발 컨테이너 생성, 즐거운 코딩 되세요!
Brigit Murtaugh, @BrigitMurtaugh