Как использовать отладчик VSCode с несколькими сервисами Docker

В моей компании (https://indy.fr) мы используем Docker и Docker Compose для локального запуска наших сервисов Node.js. Недавно мне понадобилось настроить и запустить отладчик VSCode на некоторых из этих сервисов для отладки одной функции. Для этого необходимо знать несколько вещей, которыми я поделюсь в этой статье на нескольких базовых примерах.

Прежде чем мы начнем, вот пункты, которые будут служить ориентиром в этом руководстве:

  • Мы хотим продолжать использовать Docker и Docker compose для запуска наших сервисов, поэтому у нас есть соответствующее окружение для каждого из этих сервисов (переменные окружения и т.д.).
  • Мы не хотим трогать текущий docker-compose.yml, который потенциально может быть использован в будущем для развертывания наших сервисов в production.

Образец приложения

Давайте начнем с создания первого сервиса. Это простой веб-сервер, который объединяет две строки, имя и фамилию, и возвращает результат. Этот сервис будет находиться в каталоге webapp/ в корне проекта.

Код Node.JS

webapp/package.json

{
    "name": "webapp",
    "scripts": {
        "start": "node src/server.js"
    },
    "dependencies": {
        "express": "^4.16.1"
    }
}
Вход в полноэкранный режим Выйти из полноэкранного режима

webapp/src/server.js

const express = require('express');
const app = express();

app.get('/fullname', (req, res) => {
    const firstName = req.query.firstNme;
    const lastName = req.query.lastName;
    res.send(`${firstName} ${lastName}`);
});

app.listen(8080, () => console.log('Listening on port 8080...'));
Войти в полноэкранный режим Выйти из полноэкранного режима

webapp/Dockerfile

FROM node:16

WORKDIR /usr/src/app

COPY package*.json ./

RUN npm install
COPY . .

EXPOSE 8080
CMD [ "node", "src/server.js" ]
Войти в полноэкранный режим Выйти из полноэкранного режима

webapp/.dockerignore

node_modules
npm-debug.log
Войти в полноэкранный режим Выйти из полноэкранного режима

Конфигурация Docker

Теперь, когда код приложения написан и Dockerfile создан, мы можем добавить файл docker-compose.yml в корень проекта.

docker-compose.yml

services:
    webapp:
        build: ./webapp
        ports:
            - "127.0.0.1:8080:8080"
Вход в полноэкранный режим Выйти из полноэкранного режима

Давайте запустим службу.

docker-compose build
docker-compose up -d
Войти в полноэкранный режим Выход из полноэкранного режима

Если вы перейдете по адресу http://localhost:8080/fullname?firstName=Foo&lastName=Bar, вы увидите строку undefined Bar, которая и является неожиданным поведением, которое мы будем отлаживать.

Отладка приложения в Docker с помощью VSCode

Команда отладчика

Чтобы позволить будущему отладчику VSCode присоединиться к службе Node, нам нужно указать его при запуске процесса, добавив флаг --inpect.

Простого использования --inspect или --inspect=127.0.0.1:9229 здесь недостаточно, поскольку нам нужно, чтобы порт 9229 был доступен извне службы, что разрешено адресом 0.0.0.0. Поэтому эту команду следует использовать только в том случае, если вы запускаете отладчик в службе Docker. В противном случае вы откроете порт и отладчик для любого пользователя в Интернете.

webapp/package.json

{
    "name": "webapp",
    "scripts": {
        "start": "node src/server.js",
        "start:docker:debug": "node --inspect=0.0.0.0:9229 src/server.js"
    },
    "dependencies": {
        "express": "^4.16.1"
    }
}
Вход в полноэкранный режим Выход из полноэкранного режима

Конфигурация Docker

Следуя нашим рекомендациям, мы не изменяем исходный docker-compose.yml, а создаем второй, расширяющий первый. Мы будем использовать флаг -f в docker-compose CLI, чтобы использовать их оба.

docker-compose.debug.yml

services:
    webapp:
        command: [ 'npm', 'run', 'start:docker:debug' ]
        ports:
            - "127.0.0.1:8080:8080"
            - "127.0.0.1:9229:9229"
Войти в полноэкранный режим Выйти из полноэкранного режима

Затем, чтобы перезапустить службу с включенным режимом отладки, вы можете использовать эту команду:

docker-compose build
docker-compose -f docker-compose.yml -f docker-compose.debug.yml up -d
Войти в полноэкранный режим Выйти из полноэкранного режима

Теперь служба готова к подключению к отладчику VSCode.

Запуск отладчика с помощью VSCode

В корне вашего проекта создайте новый каталог .vscode и добавьте в него следующий конфигурационный файл.

.vscode/launch.json

{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "node",
            "request": "attach",
            "name": "Debug webapp",
            "remoteRoot": "/app/src",
            "localRoot": "${workspaceFolder}/webapp/src"
        }
    ]
}
Вход в полноэкранный режим Выйти из полноэкранного режима

При добавлении точки останова свойства remoteRoot и localRoot будут соответствовать положению файла в среде VSCode и его расположению в файловой системе сервиса Docker.

Теперь вы можете запустить отладчик на службе webapp. Откройте панель отладки и выберите опцию Debug webapp. Затем нажмите на кнопку воспроизведения.

Отладчик будет запущен.

Добавьте точку останова на строке 6, а затем перейдите по адресу http://localhost:8080/fullname?firstName=Foo&lastName=Bar.

Отладчик останавливается на строке 6, и мы видим, что переменная firstName является undefined. Проблема исходит из строки 5, где это опечатка в имени параметра firstName.

Чтобы закрыть отладчик, нажмите на кнопку с красным квадратом.

Отладка нескольких сервисов Docker

Микросервис Node.JS

Чтобы сделать еще один шаг вперед, мы добавим еще один сервис, названный micro-service, который будет вызываться webapp.

Сначала скопируйте и вставьте содержимое каталога webapp в другой каталог с именем micro-service.

Затем в директории webapp установите axios и обновите код следующим образом.

npm install axios
Вход в полноэкранный режим Выход из полноэкранного режима

webapp/src/server.js

const express = require('express');
const axios = require('axios');

const app = express();

app.get('/fullname', async (req, res, next) => {
    try {
        const { data: fullName } = await axios.get('http://micro-service:8080/fullname', {
            params: req.query
        });
        res.send(fullName);
    } catch (err) {
        next(err);
    }
});

app.listen(8080, () => console.log('Listening on port 8080...'));
Войти в полноэкранный режим Выйти из полноэкранного режима

URL, используемый в строке 8, основан на имени службы Docker, определенной в следующем разделе.

Конфигурация Docker

Добавьте новый сервис в ваш docker-compose.yml. Обратите внимание, что он использует другой порт, чтобы не конфликтовать с сервисом webapp.

docker-compose.yml

services:
    webapp:
        build: ./webapp
        ports:
            - "127.0.0.1:8080:8080"
    micro-service:
        build: ./micro-service
        ports:
            - "127.0.0.1:3001:8080"
Вход в полноэкранный режим Выйти из полноэкранного режима

Затем, в вашем docker-compose.debug.yml, также добавьте новый сервис. Обратите внимание, что порт отладчика также отличается от первого.

docker-compose.debug.yml

services:
    webapp:
        command: [ 'npm', 'run', 'start:docker:debug' ]
        ports:
            - "127.0.0.1:8080:8080"
            - "127.0.0.1:9229:9229"
    micro-service:
        command: [ 'npm', 'run', 'start:docker:debug' ]
        ports:
            - "127.0.0.1:3001:8080"
            - "127.0.0.1:9230:9229"
Вход в полноэкранный режим Выйти из полноэкранного режима

Теперь создайте и запустите две службы.

docker-compose build
docker-compose -f docker-compose.yml -f docker-compose.debug.yml up -d
Войти в полноэкранный режим Выход из полноэкранного режима

Запуск нескольких отладчиков с помощью VSCode

Последнее, что нужно сделать, это добавить конфигурацию второго отладчика в launch.json.

.vscode/launch.json

{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "node",
            "request": "attach",
            "name": "Debug webapp",
            "remoteRoot": "/app/src",
            "localRoot": "${workspaceFolder}/webapp/src"
        },
        {
            "type": "node",
            "request": "attach",
            "name": "Debug micro-service",
            "port": 9230,
            "remoteRoot": "/app/src",
            "localRoot": "${workspaceFolder}/micro-service/src"
        }
    ]
}
Войти в полноэкранный режим Выйти из полноэкранного режима

После добавления конфигурации вы можете запустить два отладчика для каждой службы.

После запуска обоих отладчиков добавьте точку останова в каждой службе и перейдите по адресу http://localhost:8080/fullname?firstName=Foo&lastName=Bar. Приложение будет останавливаться последовательно на каждой точке останова.

Теперь ваш отладчик VSCode полностью настроен для работы с сервисами Docker. Поздравляем!

Статья первоначально была опубликована здесь: https://tech.indy.fr/2022/06/10/how-to-use-vscode-debugger-with-multiple-docker-services/

Оцените статью
devanswers.ru
Добавить комментарий