Во второй части мы рассмотрели практические примеры упаковки приложений. В этой заключительной части мы рассмотрим способы использования Docker в процессе самой разработки.
Навигация Скопировать ссылку
- Код внутри контейнера
- Тестирование приложений в GUI
- Безопасность Docker
- Заключение
- Материалы по теме
Код внутри контейнера Скопировать ссылку
До сих пор, мы не говорили о написании кода внутри контейнера. Вы можете использовать классическую связку vim с плагинами + tmux. Вы можете подключится к контейнеру по SSH почти из любой популярной среды разработки. Но не использовать или хотя бы не попробовать использовать возможности Visual Studio Code (VS Code) будет преступлением.
Для того, чтобы работать с кодом красиво, можно и даже нужно использовать Visual Studio Code Remote, что позволяет подключиться к созданному контейнеру и работать с ним в терминальном режиме.
Это делается довольно просто. Достаточно установить расширение Remote Development и создать файл .devcontainer.json
в папке из которой собирается ваш контейнер. Часто эта папка является папкой проекта. Можно собрать контейнер и на ходу с помощью мастера, но это трудно воспроизвести впоследствии. Например, содержимое .devcontainer.json
может быть таким:
{
"name": "server",
"dockerComposeFile": ["../docker-compose.yaml"],
"service": "test",
"workspaceFolder": "/app"
}
Это заставит VS Code собрать все контейнеры, указанные в файле для Docker Compose и открыть папку /app, которая находится внутри контейнера server.
В VS Code можно попытаться открыть папку проекта, и среда сама предложит открыть снова ее, но уже внутри контейнера. А можно сделать это вручную, нажав клавишу F1 или сочетание клавиш Ctrl + P (Cmd + P для macOS) и выбрав команду:
> Remote-Containers: Open Workspace in Container.
Вы также можете указать те расширения, которые нужно поставить для данной рабочей сессии VS Code. После работы все эти расширения удаляться из редактора. Это очень удобно. Мне это позволяет держать в VS Code всего десять (!) расширений, которые будут востребованы в любом проекте, и никаких расширений для конкретного языка или фреймворка. Чистота и порядок!
В списке литературы вы сможете познакомится с репозиторием конфигурационных файлов для разных языков и фреймворков, на которых я в основном и работаю. Этот репозиторий обновляется по мере необходимости.
Тестирование приложений в GUI Скопировать ссылку
В Docker можно запускать не только консольные приложения, но и приложения с графическим интерфейсом (GUI). Единственное ограничение — они будут работать на сервере системы X Windows для рендеринга графических приложений и взаимодействия с ними. Воспользоваться можно интересным свойством приложений с графическим интерфейсом Linux. Приложения запускаются как клиенты, которые обращаются к серверу X Windows. При этом не важно, где этот сервер расположен. Он вполне может быть на удаленном хосте. А нам это и надо!
Если вы работаете на любом дистрибутиве ОС Linux, такой сервер у вас уже запущен. Чтобы поставить его на macOS, можете воспользоваться XQuartz. На ОС Windows можно попробовать использовать VcXsrv. В первую очередь вы должны разрешить удаленное подключение к X Windows серверу и добавить переменные среды для контейнера. Универсального решения для всех ОС не существует, но я приведу флаги для команды docker run
, учитывая ОС:
-e DISPLAY=docker.for.mac.host.internal:0 # macOS
-e DISPLAY=host.docker.internal:0 # Windows
--net=host -e DISPLAY=:0 # Linux
Цифра в конце строки обозначает номер монитора, на который будет выведен графический интерфейс приложения (0 используется для обозначения главного монитора). Для macOS и Windows вы можете воспользоваться графическим интерфейсом вашего сервера. Удаленное подключение для LInux можно разрешить с помощью команды:
xhosts +
Например, вы так можете запустить Gimp одной командой:
- macOS:
docker run --rm -ti -e DISPLAY=docker.for.mac.host.internal:0 jamesnetherton/gimp
- Windows:
docker run --rm -ti -e DISPLAY=host.docker.internal:0 jamesnetherton/gimp
- Linux:
docker run --rm -ti --net=host -e DISPLAY=:0 jamesnetherton/gimp
Для запуска Eclipse нужно в конце дописать psharkey/eclipse
вместо jamesnetherton/gimp
, а чтобы запустить Firefox — jess/firefox
. В конце строки вы указываете имя нужного образа, который будет скачан с Docker Hub? Посмотрите, как был собран один из них, и вы будете точно знать, как запустить необходимое вам приложение с графическим интерфейсом.
Безопасность Docker Скопировать ссылку
Предлагаю обсудить еще одну важную тему — безопасность. Рассмотрим четыре аспекта:
- Безопасность вашей ОС во время разработки;
- Управление доступом на этапе запуска приложения в контейнере;
- Безопасные образы;
- Хранение секретной информации.
Безопасность вашей ОС Скопировать ссылку
Что мешает ОС быть в безопасности? Конечно то, что вы вынуждены устанавливать кучу разнообразного софта, в том числе и экспериментального. Это могут быть приложения с графическим интерфейсом или сугубо консольные приложения. Часто вам нужно устанавливать JVM или что-то подобное. Каждая новая программа несет в себе дырки, через которые можно что-нибудь, да сделать. Docker позволяет практически избавить вас от необходимости установки этого груза. Да и работать с коллегами будет намного проще.
Доступ при запуске приложения Скопировать ссылку
Запуск контейнера происходит в отельном окружении, изолированном от ОС и других контейнеров. Но есть определенные трюки, которые позволят обеспечить вам еще большую изоляцию. В документации к Docker есть замечательное руководство, которое точно стоит почитать. Перечислю самые важные советы, с моей точки зрения.
Во-первых, необходимо запуск приложений внутри контейнера осуществлять от имени какого-то пользователя. По умолчанию, приложение запускается от имени root. Осуществить это довольно просто, достаточно добавить параметр -u:
docker run -u user image
Вы также можете добавить эту настройку в Dockerfile:
FROM alpine:latest
RUN apk update && apk add --no-cache git
USER 1000
Во-вторых, необходимо поддерживать только те возможности, которые вам нужны. Полный функционал для вашего приложения внутри контейнера зачастую совершенно не обязателен. Управление возможностями осуществляется через командную строку с помощью параметров --cap-drop
и --cap-add
. Лучшей практикой будет запуск контейнера с одним параметром --cap-drop all
и разрешающими флагами для необходимых возможностей, обеспечивающих работу вашего приложения. Вы можете ознакомиться подробнее со всеми поддерживаемыми флагами в документации. С помощью Docker Compose вы также можете управлять поддержкой той или иной возможности контейнера с помощью параметров cap_drop
и cap_add
. В документации к Linux есть исчерпывающий список.
В-третьих, необходимо управлять ресурсами вашей ОС, которые будут доступны для запуска контейнеров. Если вы не будете ограничивать эти ресурсы, Docker просто забьет всю оперативную память, что очень смахивает на DDOS атаку прямо у вас на компьютере. Необходимо также ограничивать и использование процессора. В Windows и macOS вы можете посмотреть потребление ресурсов системы с помощью Docker Desktop. Это можно сделать и через консоль командой, доступной уже на всех ОС:
docker stats
Об оптимальных настройках вы можете подробнее почитать в официальной документации.
Безопасные образы Скопировать ссылку
Во время работы вы часто будете использовать образы из разных реестров. Будьте бдительны! Использовать образы необходимо с большим количеством скачиваний, высоким рейтингом при большом количестве отзывов, рекомендованные компанией (официальные образы) или группой, которой вы доверяете. Загружая неизвестный образ, вы получаете кота в мешке. В любом случае внимательно смотрите на конфигурационные файлы и базовые образы. Желательно также использовать подписанные образы. Для того чтобы уберечь себя от загрузки «неправильных» образов, необходимо выполнить команду в терминале:
export DOCKER_CONTENT_TRUST=1
Прочитать подробнее про эту систему можно в документации.
Хранение секретной информации Скопировать ссылку
Чтобы учетные данные аккаунтов, сертификаты, секретные ключи доступа, имена ресурсов и любая другая конфиденциальная информация оставались в тайне от других, необходимо следовать двум правилам:
- Не помещайте секреты внутрь образа;
- Не используйте для секретов переменные среды.
В документации Docker есть специальный раздел, посвящённый сохранности подобной чувствительной информации. Там предлагаются различные варианты. Но Джеф Хэйл (Jeff Hale) советует хранить секретные данные в томах (Docker volumes), создание и использование которых были описаны выше.
Заключение Скопировать ссылку
Нам приходится устанавливать на свою любимую технику всякую дребедень, экспериментировать с новыми технологиями, прикручивать на этапе внедрения продукта то, что не должно быть в нем. Фраза «у меня все работает» по понятным причинам совершенно не устраивает заказчика. Эти неприятные моменты приводят к прокрастинации или даже эмоциональному выгоранию разработчика, который часто работает больше положенных восьми часов в день. Ночные посиделки на кануне сдачи этапа проекта скорее обыденность, чем исключение.
Все вышесказанное является не чем иным, как попыткой помочь узнать основы без чтения документации. Как и всегда, попытка сделать что-либо подобное обречена на провал. Однако надеюсь, что время, проведенное за чтением, не будет бесполезным. Для меня процесс разработки совершенно точно разделился на «До» и «После». Надеюсь, опыт и умозаключения, изложенные выше, вам пригодятся, позволят попробовать различные технологии самостоятельно, поэкспериментировать, и, может быть, обеспечат преимущества при устройстве на следующую работу!
Если вы поработаете с Docker, вас, скорее всего, от него уже не спасти. Есть надежда, что вы будете писать уже следующее приложение внутри контейнера. В заключение, вот вам ещё несколько ссылок:
- Команды Docker
- Справочник по командам
- Мой репозиторий наборов конфигурационных файлов для работы в VS Code
- Docker для начинающего разработчика
Материалы по теме Скопировать ссылку
- Современные операционные системы
- Anatomy of Docker
- LXC vs Docker: Why Docker is Better
- A Beginner-Friendly Introduction to Containers, VMs and Docker
- Изучаем Docker, часть 1: основы
- Изучаем Docker, часть 2: термины и концепции
- Википедия: Стандартные потоки
- Википедия: TTY-абстракция
- Manage data in Docker
- Изучаем Docker, часть 6: работа с данными
- Dockerfile reference
- Изучаем Docker, часть 3: файлы Dockerfile
- Postgres: Dockerfile
- Linux downloads (Red Hat family)
- Docker run reference
- Top 14 Best PHP CMS In Market For Developers in 2020
- Install Docker Compose
- Compose file version 3 reference
- Интегрируем Docker в приложение Vue.js
- Официальный репозиторий Node.js от команды Docker
- Изучаем Docker, часть 4: уменьшение размеров образов и ускорение их сборки
- Use multi-stage builds
- Utilizing the power of Docker while building MERN Apps using mern-docker
- How To Set Up Flask with MongoDB and Docker
- Изучаем Docker, часть 5: команды
- Docker Commands — The Ultimate Cheat Sheet
- Docker Seeds
- Docker для начинающего разработчика