Знакомство и настройка docker

План

1) Введение

2) Что такое docker и для чего он мне нужен

3) Что у меня получилось в результате изучения docker

4) Мои конфигурационные файлы docker и docker-compose

5) Выводы


Введение

Всем привет, меня зовут Александр, я являюсь фронтенд разработчиком более 4-х лет. В этой статье хочу поделится своим опытом знакомства с docker и docker-compose. Перед началом основной части хочу отступить и сделать небольшую предисторию: почему мне понадобилось изучить эту технологию? Также, эта статья не является очередным пособием к обучению docker, а всего лишь показывает, что вы получите в результате обучения данной технологии.


Очень долго избегал ее изучения, потому что не понимал зачем она мне нужна, если в основном работаю с одним стеком, который у меня настроен на моей локальной машине, а настраивал его с нуля очень редко. В те годы, а это было в конце 2019 года, я был еще молод и только заходил в it, многого не понимал. Шли годы, я поменял стек с php на js и переехал с бекенда на юай, но все-равно не видел причины для себя, чтобы изучить докера. Так продолжалось до тех пор, пока я не начал вести блог и несколько проектов на основной работе. На всех трех были разные требования. На работе нужно было две версии ноды, а в домашних проектах помимо нее еще нужно разворачивать базу данных. В этот момент я задумался, что пора изучить docker, лучшего момента уже не придумаешь.


Что такое docker и для чего он мне нужен

Давайте для начала вспомним, что такое докер? Докер — это технология, которая позволяет запускать различные образы и среды разработки в контейнере, при этом сама рабочая среда на физической машине может отсутствовать. Теперь давайте обсудим зачем мне нужна данная технология? Ранее я упоминал косвенные причины зачем мне нужен был docker, теперь давайте погрузимся в них глубже. В своем домашнем проекте я использую nodejs и монго. Постоянно настраивать на домашнем компьютере рабочее пространство уже надоело, да и времени сейчас часто не хватает, просто хочется сесть за машину, запустить пару команд и начать работать - это первая причина. Едем дальше, у меня есть стенд с моим блогом, который вы сейчас читаете в данный момент времени, на нем, также, необходимо развернуть рабочую среду, чтобы этот сайт работал. В начале это тоже делал руками, но теперь могу поставить настройку на докер, чтобы на сайте и домашнем компьютере были аналогичные условия работы сайта, а не приближенные — это вторая причина, по которой мне понадобился докер, но не последняя. На работе участвую в командной разработке и у меня уже не раз возникала ситуация, когда необходимо помочь коллегам бекам установить рабочий юай, чтобы они могли тестировать программу. Также бывают ситуации, когда мне нужен рабочий бек или стенд с ним, а т. к. стендом пользуется много людей параллельно — это часто бывает накладывает определенные ограничения и все должны ждать — неудобно. Вот здесь во всей красе и выходит докер, где можно у каждого локально запустить свой экземпляр рабочей версии бека и далее спокойно работать — эта третья и самая главная причина, по которой я решил изучить docker.


Что у меня получилось в результате изучения docker

Когда я ставил себе конечную цель, которая скажет, что я продвинулся достаточно в изучении докера, то мне на глаза попалась следующее умозаключение: основа контейнера докера — это как можно маленькие контейнеры, как можно меньший образ; он должен работать только с одной программой, для которой он предназначен. Она помогла мне понять, что конечной целью изучения докера должна быть работа трех контейнеров, в которых будут работать отдельно юай, бекенд и база данных, и они смогут между собой общаться.


В результате изучения docker у меня получилось настроить работу в режиме разработки двух моих основных домашних проектов. Они запускаются в одном пространстве, могут общаться друг с другом и параллельно можно вести разработку, чтобы каждый раз не пересобирать контейнеры, то есть у меня получилось достичь поставленной цели. Далее хочу поделится тем, с какими проблемами я столкнулся, когда после теории начал настраивать для себя рабочую инфраструктуру на контейнерах.


Самое главное — это проблема с сетями в docker, то есть у меня не было изначально понимания, как общаются между собой запущенные контейнеры. Оказывается, у docker есть три типа сетей: bridge, host, none. Подробно в это не буду погружаться, нас здесь интересует тип bridge, более подробную информацию можно найти в интернете. В docker можно создать отдельную сеть bridge в рамках которой могут работать все запущенные docker контейнеры. В ее пределах контейнеры могут общаться между собой, а отдельный тип был создан, чтобы запущенные контейнеры изолировать от других, чтобы не было влияния посторонних программ. Когда я вдоволь наигрался и понял как работают сети, то начал тестировать, каким образом можно соединить мои собственные контейнеры.


Подключение контейнера с базой данных на стороне бекенда


На изображении «Подключение контейнера с базой данных на стороне бекенда» в примере видно, что вместо localhost после обратного слеша используется имя контейнера, в данном примере — это mongodb, то есть здесь получилось обратится к контейнеру через dns. А вот с подключением бекенда к юаю так не получилось сделать, когда прописал название контейнера, в котором работал бекенд — у меня вызов на сторону бекенда не приходил. В итоге пришлось прописать ip контейнера с беком, чтобы подружить юай и бекенд.


Подключение контейнера с бекендом на стороне юая


На изображении «Подключение контейнера с бекендом на стороне юая» в примере показано, что вместо localhost, как было ранее, прописан ip адрес контейнера с бекендом. Вот таким неоднозначным образом у меня получилось связать три контейнера между собой.


Также необходимо упомянуть еще одного героя, который позволяет автоматизировать управление вышеупомянутыми тремя контейнерами, - docker-compose. Благодаря ему можно двумя командами up и build запустить контейнеры и одной командой stop остановить это все и почистить остатки мусора, который оставляет за собой обычный docker.


В сухом остатке имеем, что для настройки разработки бека с юаем необходимо сделать следующее:


  • создать локальную сеть, в рамках которой контейнеры смогут общаться между собой;
  • прописать правильные доменные имена/ip адреса, чтобы контейнеры могли общаться между собой;
  • запустить все три контейнера в рамках одной локальной сети вручную или через docker-compose.


Также вы меня можете спросить, как узнать ip адрес контейнера, чтобы к нему подключится и проверить есть ли связь между контейнерами? Давайте начнем с первого, ip адрес можно узнать из настроек сети docker, более подробную работу с ними можно найти в интернете. А вот проверить связь между контейнерами — это хороший вопрос. Я его решил следующим алгоритмом действий:


  • зайти в bash консоль контейнера, это можно сделать следующей командой: docker exec -it b5d116ad83cc bash, где b5d116ad83cc — это id или имя контейнера;
  • проверить наличие программы для прослушивания контейнера по ip или имени контейнера, который нужен для работы. Например, есть два контейнера с бекендом и базой данных для него и контейнер с бекенодом от него зависит. В этом случае контейнер с бекендом должен смочь прослушивать контейнер с базой данных;
  • если программы по прослушиванию ip нет, то ее можно установить через apt-get менеджер и повторить вышеописанный пункт;


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


Но это не все проблемы, которые у меня возникли, вторая из них, но не менее важная — это как сохранить данные в контейнере с базой данных, делать дамп и вносить данные в базу данных? Здесь у меня нашелся ответ через нативную команду docker — exec. Выполнив эту команду можно сделать дамп или восстановить базу данных.


Команды для выполнения дампа или восстановления базы данных в докере


На изображении «Команды для выполнения дампа или восстановления базы данных в докере» приводится пример выполнения работы с контейнером, в котором крутится база данных, в данном примере используется база данных mongo, на других базах данных должен применяться тот же принцип, что и для нее. Первая команда выполняет создание дампа, вторая — применения дампа в базу данных. Из нюансов работы, я бы отметил, что необходимо использовать целостный файл для работы. Дело в том, что mongo может создать отдельный дамп из коллекции базы данных и поместить его в отдельный файл. Так работать не получится, необходимо применять целостный файл, который содержит в себе всю базу данных. Не знаю на сколько это актуально для баз данных mysql и т. п., но упомянуть этот нюанс посчитал нужным.


Мои конфигурационные файлы docker и docker-compose


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


Файл докер на стороне юая


Файл докер на стороне бекенда


На изображениях «Файл докер на стороне юая» и «Файл докер на стороне бекенда» приведены примеры конфигурационных файлов, которые используются для создания образов юай и бекенд частей моего интернет приложения. Давайте разберем общие команды:


  • from — указывает образ, на базе которого будет собран текущий образ;
  • workdir — указывается рабочая папка, так до конца и не понял зачем ее указывать, если и без нее все работает, но на всякий случай оставил, чтобы в дальнейшем не было проблем;
  • copy — копирует файлы с физической машины в образ, первым аргуметом принимает путь откуда нужно копировать, вторым — куда в контейнере вставить;
  • run — запускает комманду, которая будет запускаться, когда создается контейнер от образа;
  • cmd — команда, которая запускается при каждом старте контейнера.


Версия и настройка сети в docker-compose


Настройка сервиса для frontend приложения


Настройка сервиса для backend приложения


Настройка сервиса для базы данных mongo приложения


Выводы

В этой статье я поделился своими мыслями почему ранее мне, как специалисту, не нужно было использование docker и почему он мне понадобился в данный момент времени; с какими трудностями столкнулся и как их решил, что было сделано для этого, какие алгоритмы использовал; привел пример конфигурационных файлов, которые используются в моих проектах. Надеюсь, что мой пример и пояснения помогли вам понять в освоении и понимании зачем нужен docker.

© Все права защищены 2024