CosmosDB 및 개발자와 협력하는 로컬 개발자

내가 컨설턴트였을 때 프로젝트에서 실현하고자 했던 열반은 원본 코드 관리에서 복제할 수 있고, 설치할 도구를 추적할 수 있는 wiki 페이지가 없고, 유지보수되지 않은 설치 스크립트가 없고, 복제 + 설치 의존항만 준비되어 있었다.이것이 바로 내가 좋아하는 이유VS Code Remote Containers, 일명 devcontainers라고도 부른다.
내가 전에 말했지, 그들은 아주 좋은 팀이야, 아마도 이곳에서 과격할 거야..


앨런 바벨
스라스

저는 devcontainers의 슈퍼팬입니다. 하지만 제가 너무 했나 봐요...🤣
2021년 5월 10일 오전 05:03
네, 제 기계에는 23명의 개발자가 있습니다.요 며칠 나는 나의 기계에서 어떤 개발도 하지 않았고, 모든 개발은 한 용기에서 진행되었다.
이것은 개발자에게 매우 좋습니다. 저는 웹 서버/API/등을 실행할 수 있습니다. 좋습니다. 하지만 조금 더 어려운 것은... 저장입니다.저는 보통 코스모스DB를 백엔드로 사용하기 때문에 최종적으로 코스모스DB의 실례를 배치하여 작업을 진행했습니다.비록 이것은 나에게 매우 좋지만, 만약 내가 다른 사람이 사용할 수 있는 환매 협의나 따라가는 세미나를 만들려고 한다면,CosmosDB 서비스를 배치하는 데 매우 어려운 요구가 있기 때문에, 이것은 입문 비용을 증가시킬 것이다.
한동안 CosmosDB emulator 이 있었지만, 이것은 윈도 모방기였다. 이것은 Git repo에 설치할 수 있는 물건을 제외하고는 일련의 절차가 필요하다는 것을 의미한다. 나는 devcontainer에서 그것을 연결하지 못했다.
이번 주 마이크로소프트 빌드preview of a Linux emulator was released가 모든 것을 바꿨다.자연스러워서 나는 어쩔 수 없이 그것을 좀 돌렸다.

에뮬레이터 설정


emulator는 Docker 이미지로 제공되므로 이미지를 끌어오기만 하면 쉽게 설정할 수 있습니다.
$> docker pull mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator
그런 다음 컨테이너를 시작합니다.
$> docker run -p 8081:8081 -p 10251:10251 -p 10252:10252 -p 10253:10253 -p 10254:10254 --name=cosmos -it mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator
이것은 로컬에서 실행됩니다. 이것은 매우 좋지만, 나는 VS 코드와 devcontainers에서 그것을 사용하고 싶습니다.

우주 개발자


말 그대로 devcontainer는 개발을 진행하는 곳이다. 우리는CosmosDB를 대상으로 개발해야 하기 때문에 emulator 이미지를 기초 이미지로 하고 우리가 필요로 하는 모든 다른 내용을 추가할 수 있다. 예를 들어 노드,dotnet 등이다.
비록 이것은 실행 가능한 선택이지만, 나는 이것이 가장 간단한 방법이 아닐 수도 있다고 생각한다.우선, 실행할 거대한 용기가 있습니다. 개발 환경과 관련된 모든 내용을 변경하려면, 사용자가 가지고 있는 모든 데이터를 포함하여 모든 내용을 파괴할 것입니다.이 밖에 emulator 이미지는 노드나dotnet 같은 실행을 설치하지 않았을 때 매우 간단합니다. 따라서 적절한 apt 원본을 추가하고, 설치할 때, 실행할 때 등을 추가해야 합니다. 매우 가능하지만, 이것은 문제를 해결하는 최선의 방법이 아니라고 생각합니다.
Docker Compose로 이동합니다.
나는 최근에야 이 점을 알게 되었다. devcontainers support Docker Compose 이것은 당신이 더욱 복잡한 환경 창고를 만들고 VS 코드로 이 모든 것을 시작할 수 있다는 것을 의미한다.
Node.js quickstart (full docs here 를 사용하고devcontainer에서 그것을 실행합시다.

devcontainer Dockerfile


CosmosDB 시뮬레이터를 잠시 멈추고 이 코드 라이브러리에 필요한 Dockerfile을 볼 것입니다.
VS Code docs에 따라devcontainer 정의를 구축하여 해커 공격을 시작합니다.
주의: Docker Compose 옵션에 들어가려면 '모든 정의 보이기' 를 선택해야 할 수도 있습니다. 이 옵션은 .devcontainer 폴더를 추가한 것을 발견하고 용기에서 열 수 있도록 알려 줍니다. 그러나 모든 내용을 설정할 때까지 잠시 미루겠습니다.
응용 프로그램은 노드입니다.그래서 우리는 그것을 우리의 기초 그림으로 삼고 싶을지도 모른다.먼저 기본 이미지를 노드로 변경합니다.js 그림:
ARG VARIANT="16-buster"
FROM mcr.microsoft.com/vscode/devcontainers/javascript-node:0-${VARIANT}
올바른 버전의 Node가 설치되어 있는지 확인하기 위해 컨테이너 매개 변수로 유연하게 전달할 수 있지만 기본값은 16입니다.js 버전.

Docker Compose 설정


Docker 파일은 devcontainer를 위한 준비가 되어 있습니다. 잘 실행할 수 있지만, 조합 환경의 일부가 되기를 바랍니다. 그래서 Docker 조합 파일을 완성할 때가 되었습니다.
우리를 위해 구축된 그 프로그램은 우리가 필요로 하는 응용 프로그램을 갖추고 있으며, 우리가 해야 할 일은CosmosDB emulator를 서비스로 추가하는 것이다.
version: "3"

services:
    cosmos:
        image: mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator:latest
        mem_limit: 3g
        cpu_count: 2
        environment:
            AZURE_COSMOS_EMULATOR_PARTITION_COUNT: 10
            AZURE_COSMOS_EMULATOR_ENABLE_DATA_PERSISTENCE: "true"
        volumes:
            # Forwards the local Docker socket to the container.
            - /var/run/docker.sock:/var/run/docker-host.sock
    app:
        # snip
우리는 cosmos라는 새로운 서비스를 추가했다(분명히 그렇지!)이것은 시뮬레이터에 이미지를 사용하고 환경 변수를 보내서 시작을 제어합니다.우리는 또한 나중에 필요로 할 때 Docker socket를 설치할 것이다.
컨테이너를 열기 전에 마지막으로 설정해야 할 일은 devcontainer 포트를 통해 CosmosDB emulator를 공개하는 것입니다.현재 Docker Compose 파일을 사용하여 포트 매핑을 할 수 있습니다. VS 코드를 통해 이 환경을 실행하면 포트 매핑을 납치합니다. 따라서 devcontainer.json 파일에 포트를 공개하는 것이 아니라 docker-compose.yml 파일에 포트를 공개하는 것입니다. (코드 공간에 사용할 경우 Docker 호스트에 접근할 수 없기 때문입니다.)그러나 만약 우리가 devcontainer.json에 포트 전송을 추가한다면, 이것은 VS 코드의 주요 용기가 아니기 때문에 cosmos 서비스에서 포트를 공개하려고 하는 것을 알 수 없을 것이다.대신 Dellapp의 네트워크에 서비스를 매핑해야 합니다network_mode: service:cosmos.
services:
    cosmos:
    # snip
    app:
        build:
        context: .
        dockerfile: Dockerfile.compose
        args:
            USER_UID: 1000
            USER_GID: 1000
            VARIANT: 16

        init: true
        volumes:
            - /var/run/docker.sock:/var/run/docker-host.sock
            - ..:/workspace:cached

        entrypoint: /usr/local/share/docker-init.sh
        command: sleep infinity

        network_mode: service:cosmos

devcontainer를 조정합니다.json


우리의 환경은 이미 준비가 되었지만, 그것을 시작하려면 devcontainer를 시작할 수 없습니다. 다음 오류가 발생했기 때문입니다.
[2209 ms] Start: Run in container: uname -m
[2309 ms] Start: Run in container: cat /etc/passwd
[2309 ms] Stdin closed!
[2312 ms] Shell server terminated (code: 126, signal: null)
unable to find user vscode: no matching entries in passwd file

문제는 기본 Docker 이미지를 사용하여 모든 컨텐트를 실행하는 사용자node를 만들었지만 devcontainer.json 파일은 remoteUservscode로 지정했습니다.
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
// https://github.com/microsoft/vscode-dev-containers/tree/v0.179.0/containers/docker-from-docker-compose
{
    "name": "Docker from Docker Compose",
    "dockerComposeFile": "docker-compose.yml",
    "service": "app",
    "workspaceFolder": "/workspace",

    // Use this environment variable if you need to bind mount your local source code into a new container.
    "remoteEnv": {
        "LOCAL_WORKSPACE_FOLDER": "${localWorkspaceFolder}"
    },

    // Set *default* container specific settings.json values on container create.
    "settings": {
        "terminal.integrated.shell.linux": "/bin/bash"
    },

    // Add the IDs of extensions you want installed when the container is created.
    "extensions": ["ms-azuretools.vscode-docker"],

    // Use 'forwardPorts' to make a list of ports inside the container available locally.
    // "forwardPorts": [],

    // Use 'postCreateCommand' to run commands after the container is created.
    // "postCreateCommand": "docker --version",

    // Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
    "remoteUser": "vscode"
}
우리는 remoteUsernode로 바꿀 수 있다. 모든 것이 준비되었다.그러나 devcontainer.json 파일에 있을 때 확장자를 추가합니다.
    "extensions": [
        "ms-azuretools.vscode-docker",
        "dbaeumer.vscode-eslint",
        "esbenp.prettier-vscode",
        "ms-azuretools.vscode-cosmosdb"
    ],
이것은 eslint + prettier (내가 선택한 linter와 포맷 프로그램), 그리고 VS 코드에 사용되는CosmosDB 도구를 제공합니다.용기를 사용하기 전에 모든 npm 패키지를 설치하기 위해서 npm installpostCreateCommand로 추가하는 것도 좋아합니다.

CosmosDB 에뮬레이터에 연결


emulator는 호스트에서 볼 수 있는 작업공간의 개별 컨테이너에서 실행됩니다docker ps.
➜ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a883d9a21499 azure-cosmos-db-sql-api-nodejs-getting-started_devcontainer_app "/usr/local/share/do…" 4 minutes ago Up 4 minutes azure-cosmos-db-sql-api-nodejs-getting-started_devcontainer_app_1
c03a7a625470 mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator:latest "/usr/local/bin/cosm…" 20 minutes ago Up 4 minutes azure-cosmos-db-sql-api-nodejs-getting-started_devcontainer_cosmos_1

그렇다면, 우리는 어떻게 응용 프로그램에서 그것을 해결합니까?호스트 이름이나 IP 주소를 사용합니다.나는 호스트 이름을 사용하는 것을 더 좋아한다. 이것은 우리 docker-compose.yml 파일의 서비스 이름이기 때문에 cosmos 포트8081에서 실행된다.계정 키에 대해 표준 키that you’ll find in the docs를 받았습니다.config.js를 열고 세부 정보를 입력합니다.
// @ts-check

const config = {
    endpoint: "https://cosmos:8081/",
    key:
        "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==",
    databaseId: "Tasks",
    containerId: "Items",
    partitionKey: { kind: "Hash", paths: ["/category"] }
};

module.exports = config;
현재 터미널을 열고 node app.js 아날로그에서 프로그램을 실행합니다.
node ➜ /workspace (main ✗) $ node app.js

/workspace/node_modules/node-fetch/lib/index.js:1455
                        reject(new FetchError(`request to ${request.url} failed, reason: ${err.message}`, 'system', err));
                               ^
FetchError: request to https://cosmos:8081/ failed, reason: self signed certificate
    at ClientRequest.<anonymous> (/workspace/node_modules/node-fetch/lib/index.js:1455:11)
    at ClientRequest.emit (node:events:365:28)
    at TLSSocket.socketErrorListener (node:_http_client:447:9)
    at TLSSocket.emit (node:events:365:28)
    at emitErrorNT (node:internal/streams/destroy:193:8)
    at emitErrorCloseNT (node:internal/streams/destroy:158:3)
    at processTicksAndRejections (node:internal/process/task_queues:83:21) {
  type: 'system',
  errno: 'DEPTH_ZERO_SELF_SIGNED_CERT',
  code: 'DEPTH_ZERO_SELF_SIGNED_CERT',
  headers: {
    'x-ms-throttle-retry-count': 0,
    'x-ms-throttle-retry-wait-time-ms': 0
  }
}
읊다, 읊조리다💥. 저희가 원하는 게 아니라...
결국 우리가 뭘 놓쳤는지노드js는 정의된 TLS 인증서 목록을 사용합니다. 자가 서명 인증서는 지원되지 않습니다.Cosmos DB SDK handles this for localhost 는 아날로그의 디자인 사용 방식입니다. 그러나 localhost 에서 문의할 수 없습니다. (compose 파일에서 서비스를 지정하지 않으면 나쁜 생각일 수도 있습니다.) 따라서 TLS를 사용하지 않는 것으로 이 문제를 해결해야 합니다.
참고: TLS를 비활성화하는 것은 결코 좋은 생각은 아니지만 이것이 우리의 유일한 해결 방법입니다.단지 어떤 생산 배치에서도 그것을 금지하지 마라.
컨테이너를 시작할 때devcontainer.json 섹션에서 환경 변수를 컨테이너에 주입할 수 있으므로 remoteEnv 파일을 엽니다.
  "remoteEnv": {
    "LOCAL_WORKSPACE_FOLDER": "${localWorkspaceFolder}",
    "NODE_TLS_REJECT_UNAUTHORIZED": "0"
  },
NODE_TLS_REJECT_UNAUTHORIZED0로 설정하면 Node에 표시됩니다.js에서 TLS 오류를 무시합니다.이것은 응용 프로그램이 실행될 때 터미널에서 경고를 보낼 것입니다. 단지 생산 과정에서 이렇게 해서는 안 된다는 것을 알릴 뿐입니다.
이제 환경을 다시 만들고 VS 코드를 다시 불러와야 합니다. devcontainer.json 파일의 변경 사항을 감지하고 환경을 재구성할지 여부를 묻습니다."재구성"을 누르면 몇 분 후에 환경이 생성됩니다. (그림이 이미 존재하기 때문에 이번에는 훨씬 빠릅니다.)터미널을 열고 응용 프로그램을 다시 실행할 수 있습니다.
node ➜ /workspace (main ✗) $ node app.js
(node:816) Warning: Setting the NODE_TLS_REJECT_UNAUTHORIZED environment variable to '0' makes TLS connections and HTTPS requests insecure by disabling certificate verification.
(Use `node --trace-warnings ...` to show where the warning was created)
Created database:
Tasks

Created container:
Items

Querying container: Items

Created new item: 3 - Complete Cosmos DB Node.js Quickstart ⚡

Updated item: 3 - Complete Cosmos DB Node.js Quickstart ⚡
Updated isComplete to true

Deleted item with id: 3
🎉 타다!이 예는 Docker 컨테이너에서 CosmosDB emulator를 실행하고 다른 Docker 컨테이너에서 호출합니다.

결론


본고에서 우리는 VS 코드 원격 용기 (일명 devcontainers) 를 사용하여 복잡한 환경을 만드는 방법을 보았다. 이 용기는CosmosDB emulator를 사용하여 노드의 로컬 개발을 진행한다.js 응용 프로그램이 코스모스DB에 대항합니다.
만약 네가 그것을 돌리고 싶다면, 너는 나의 견본품을 찾을 것이다. on GitHub

알 룬 바벨 / azure cosmos db sqlapi 노드 사용 시작


이 예는 이 노드를 어떻게 사용하는지 보여 준다.js SDK는 Microsoft Azure Cosmos DB와 상호 작용합니다.


대체 솔루션


이 글을 발표한 후, 나는 트위터 토론에 들어갔는데, 그 중 TLS를 사용하지 않아도 되는 또 다른 해결 방안이 있는 것 같다.an example repo가 있고 NODE_EXTRA_CA_CERTS 환경 변수를 사용하여 cert that comes with the emulator를 노드에 추가합니다.TLS를 사용하지 않는 것이 아니라 js입니다.devcontainer가 시작되면 몇 단계를 더 실행해야 하기 때문에, 옵션으로 보십시오.

좋은 웹페이지 즐겨찾기