Разработка внутри контейнера Docker

Ад зависимостей - это проклятие всех разработчиков программного обеспечения, которые пытаются установить правильный набор инструментов. В этом посте я покажу, как настроить чистую среду с помощью функции удаленного контейнера Visual Studio Code, включая инструменты разработки Python и C ++.

Если вы еще этого не сделали, установите VS Code с официального сайта (я предполагаю, что в этом посте есть некоторые базовые знания). В основном я использую его для разработки на Python - если вы тоже, то рекомендую также взглянуть на учебник по расширению Python. Я также предполагаю, что у вас установлен и работает Docker, поэтому docker ps работает нормально.

Я расскажу, как преобразовал один из своих домашних проектов в контейнер. У меня не так много времени для работы над этим проектом, поэтому я вернулся к нему с новой установкой ОС, и мне нужно было снова запустить сборку. Это расширение Python, написанное на C ++ с использованием отличного фреймворка pybind11 для создания привязки. Это означает, что для этого требуются инструменты для сборки и отладки C ++, а также среда Python. Проект называется entpy on Github, но подробности того, что он делает, не важны для этого поста.

Удаленные контейнеры

Первое, что вам потребуется, это установить расширение удаленных контейнеров в VS Code. Используйте CTRL + SHIFT + P или CMD + SHIFT + P, чтобы вызвать палитру команд, и вставьте:

ext install ms-vscode-remote.remote-containers

Затем создайте файлы, необходимые для начала работы. Remote Containers: Add Development Container Configuration Files... позвонит вам выбор базовых конфигураций Docker для начала. Чтобы запустить проект Python, загрузите параметр Python 3.

Это создает два файла в папке с именем .devcontainer.

  • Dockerfile, определяющий этапы сборки для самого контейнера докеров.
  • devcontainer.json настраивает, как VS Code использует контейнер, как мы увидим.

Сборка докеров

Опять же, используйте палитру команд, чтобы запустить контейнер. Используйте команду Remote Containers: Open Folder in Container... и выберите папку проекта. Если папка уже открыта локально, вы также можете использовать команду Remote-Containers: Reopen in Container.

В первый раз, когда вы это сделаете, это, скорее всего, займет некоторое время. Вот что происходит:

  1. Образ докера построен на основе только что созданного Dockerfile.
  2. VS Code копирует свой собственный код в контейнер в домашний каталог пользователя (в настоящее время /root).
  3. Исходный код монтируется как том Docker внутри контейнера, поэтому он совместно используется контейнером и хостом.
  4. В контейнере запускается сервер для запуска «бизнес-части» VS Code, пользовательский интерфейс на вашем рабочем столе подключается к нему через сетевое соединение.

В частности, этап 1 может занять некоторое время, но в следующий раз он будет кэширован системой сборки Docker. Этап 2 также занимает короткое время, но мы скоро его ускорим.

Когда контейнер будет запущен, вы сможете увидеть его в выводе docker ps из отдельного терминала.

Войдите в контейнер

Найдите минутку, чтобы увидеть, что произошло. После открытия папки в контейнере окно кода возвращается в таком же виде, как и раньше, с исходным кодом слева. Однако вы должны увидеть в левом нижнем углу зеленую рамку с надписью «Dev Container: Python 3» - значит, вы знаете, что контейнер был успешно открыт. Если вы откроете интегрированный терминал, вы увидите, что вы вошли в систему как root в папке /workspaces/entpy.

Мне всегда немного неудобно, когда контейнер открывается с правами root, сначала на случай возможных проблем с безопасностью, но также, когда вы работаете с монтированием томов, это может вызвать головную боль: посмотрите на результат ls -lh на скриншоте выше, все файлы принадлежат пользователю vscode, но я вошел в систему как root. Поскольку я являюсь суперпользователем, поначалу это не кажется большой проблемой, я могу сколько угодно редактировать файлы, принадлежащие другому пользователю. Но если я создам файл в контейнере с touch foo, он также будет принадлежать root в хост-системе. (Это поведение в некоторой степени специфично для Linux и может отличаться в macOS или Windows).

Теперь я не могу редактировать этот новый файл на хосте без использования sudo! К счастью, VS Code имеет механизм, позволяющий справиться с этим практически сразу - в devcontainer.json отредактируйте ключ remoteUser, чтобы указать vscode. После изменения файлов конфигурации контейнера вам необходимо перезагрузить с помощью Remote Containers: Rebuild Container из палитры команд.

Теперь вы должны войти в систему как vscode в Code - и главное, если вы создадите файл из Code, и вы обнаружите, что он принадлежит вашему обычному логину на хосте.

Настройка среды разработки

Теперь важный момент - добавление всех инструментов разработки, необходимых для сборки (и тестирования) вашего кода.

Версия Python

Если вы ориентируетесь на одну версию Python, измените строку FROM в Dockerfile.

FROM python:3.6-buster  # Use the latest Python 3.6.x

Компиляторы и инструменты

По возможности приобретайте компиляторы и инструменты с apt, хотя вам может потребоваться добавить другие загрузки файлов. В примере Dockerfile вызывается apt, поэтому вы можете изменить его по мере необходимости. Если вам нужны инструменты разработчика C ++, как и мне, вам нужно будет установить их здесь.

Вы также можете установить некоторые инструменты из pip - например, предоставленный Dockerfile устанавливает pylint для линтинга (я изменил это на flake8, что предпочитаю). Однако я бы не рекомендовал вам устанавливать зависимости Python для вашего пакета на этом этапе (то есть вашей виртуальной среды requirements.txt / Pipenv / Poetry).

Если вы используете Poetry (как и я), вам необходимо установить его. С помощью сценария get-poetry.py он будет установлен в домашний каталог пользователя, поэтому поместите его в конец Dockerfile, чтобы установить его для пользователя без полномочий root:

Мой код в настоящее время настроен для Poetry 0.12.17 - последний выпуск (Poetry 1.0.0 на момент написания) несовместим, поэтому я закрепил его переключателем --version.

Расширения VS Code

При использовании функций удаленного контейнера VS Code устанавливается как служба внутри вашего контейнера, а расширения (не связанные с пользовательским интерфейсом) запускаются внутри контейнера с ним. Это означает, что нужные вам расширения (например, инструменты Python) необходимо переустановить в контейнерах. Вы можете указать их в devcontainer.json файле под extensions.

Заключительные рекомендации

Расширение Remote Containers, похоже, быстро развивается - когда я впервые начал писать этот пост, было много дополнительных деталей, чтобы обойти причуды, которые, похоже, уже были исправлены в расширении, которое отлично. Имея это в виду, следите за обновлениями расширений, я ожидаю, что этот пост может быстро устареть!

Последний вопрос: проверять конфигурацию контейнера разработчика в git или нет. Я бы посоветовал вам сделать это, но только проверьте конфигурацию, которую вы хотите передать команде разработчиков. Например, хотя вы можете указать расширения VS Code в файле devcontainer.json, придерживайтесь расширений, которые действительно необходимы для разработки, таких как расширение Python, а не ваше личное предпочтительное расширение истории git и т. Д. Вы всегда можете установить их после сборки контейнера. Перестройка контейнера требует времени, и вы не хотите делать частые обновления и заставлять всю свою команду делать это.

Мою полную конфигурацию можно найти на гитхабе.

Обязательно ознакомьтесь с официальной документацией по удаленным контейнерам.