Настраиваем devcontainer, который будет работать локально, в EC2 и Codespaces

Схема работы 
Схема работы 

Для тех, кто не в курсе, devcontainer - это спецификация от майкрософт, с помощью которой можно универсально описывать параметры окружения для разработки и поднимать все в один клик на любом устройстве, включая клауды.

Этот подход похож на стандартный запуск окружения с помощью docker compose, но намного удобнее за счет стандартизации. 

Пока что в полной мере спека поддерживается только в VS Code. Jetbrains обещают добавить поддержку уже скоро. Так же можно использовать CLI для запуска и управления контейнером.

В этой статье мы настроим Node.js + PostgreSQL + PGAdmin4 стэк для разработки.

Папка .devcontainer

Для начала нужно создать папку .devcontainer. В ней будет находиться docker-compose.yml, различные Dockerfile и devcontainer.json.

Docker контейнеры

Основным контейнером будет тот, внутри которого мы хотим находиться во время разработки. В нашем случае это будет контейнер с Node.js приложением. Cоздадим файл .devcontainer/app/Dockerfile со следующим содержимым:

Помимо образа ноды, мы дополнительно устанавливаем socat и sudo. Чуть позже станет понятнее зачем это надо.

Так же создадим .devcontainer/docker-compose.yml,

Если вы работаете на Windows или MacOS, обязательно нужно сделать отдельный volume для папки node_modules (строка #7) – это поможет ускорить работу вашего приложения внутри контейнера. 

Cтроки #21, #33 и куча переменных окружения заставят pgadmin4 не требовать ввода логина и пароля при входе и непосредственно при подключении к бд. Так же надо создать .devcontainer/pgadmin4/servers.json:

devcontainer.json

Теперь самое сладенькое. Нужно создать .devcontainer/devcontainer.json:

В service указываем, который из контейнеров считать основным. Внутри основного контейнера будет вестись вся разработка. В нашем случаем это app, куда установлена нода.

В postCreateCommand меняем владельца node_modules на node, так как эта папка у нас отдельный volume, устанавливаем зависимости и настраиваем переменные окружения. Эти команды буду выполняться после создания контейнера.

В postStartCommand с помощью socat и nohup пробрасываем порт pgadmin4, в основной контейнер, а из основного контейнера, с помощью "forwardPorts": [8080], форвардим этот порт вовне. На самом деле это можно сделать попроще через forwardPorts, указав ["pgadmin4:8080"], но этот способ не будет работать в Codespaces (почему-то они это пока не поддерживают).

Ну и в postAttachCommand прописываем код, чтобы git не ругался на разных владельцев.

Итого у нас получился devcontainer, который можно запускать из VS Code, Codespaces, с помощью CLI, или даже в EC2 при помощи Remote – SSH расширения для VS Code.