План:
- Введение
- Реализация полного переноса разработки в docker контейнеры и исправление ошибок
- Почему на своем стенде я не буду переводить разворачивание через docker контейнеры
- Вывод
Введение
Всем привет, меня зовут Александр, я являюсь фронтенд разработчиком более 4-х лет. В этой статье я хочу продолжить тему изучения docker и работы с контейнерами. С предыдущих статей «Знакомство и настройка docker» и «Продолжаем изучать docker» прошло уже немало времени и тема для меня оказалось не полностью закрытой. Раскрою свою мысль шире. Когда я написал свою статью «Знакомство и настройка docker» с применением как docker, так и docker compose, то я подумал, что сделал готовый для себя продукт. Как показала практика — я ошибся. Часть проблем, которые обнаружил после первой статьи, я поправил и описал в продолжении - «Продолжаем изучать docker». В ней я взял за основу docker файл и файл docker compose из первоначальной сборки, чтобы перенести и адаптировать их в сборку по созданию html шаблонов. В процессе написания и отладки мною было обнаружены ошибки в исходных файлах. Подробный процесс этого можно почитать в вышеупомянутой статье «Продолжаем изучать docker», здесь я не буду заострять на этом внимание.
Продолжим, когда писал статью «Знакомство и настройка docker», то я тогда сидел на ubuntu, на этой операционной системе сборка работала с вышеупомянутыми ошибками, но тогда я закрыл на это глаза. Сейчас, на момент написания этой статьи я перешел на использование операционной системы fedora. Когда я переезжал, то, к большому сожалению, потерял мой конфигурационный файл docker compose. Для меня это не было большой трагедией, но было не приятно. На тот момент у меня была выложена статья «Знакомство и настройка docker» и в ней было подробно описано содержимое конфигурационного файл docker compose, поэтому оставил этот вопрос на будущее. И вот это будущее наступило. В ближайшем будущем я понимаю, что у меня будет работа с java и php. Настраивать окружающую среду под каждый язык мне совсем не охота, поэтому для себя решил вести локальную разработку полностью в docker. И начал с восстановления моего конфигурационного файла. Сам файл восстановить не было проблемой. Проблемы начались после.
Реализация полного переноса разработки в docker контейнеры и исправление ошибок
После восстановления файла docker compose и исправления ошибок в моих docker файлах для юая и бекенд разработки я начал запускать свои контейнеры через docker compose.
Произошло то, чего я очень сильно боялся, сборка завелась, но не работала корректно. Тогда я начал дебажить docker compose путем запуска контейнеров по очереди. Самым первым у меня должен запускаться контейнер с mongodb. С ним проблем не возникло, доступ к бд из локальной системы был. Как выяснилось в процессе разбора, локальная сеть компьютера не имеет доступа к поднятой сети для docker контейнеров. Объясню на примере.
Логика контейнера для mongodb в файле docker-compose
Здесь нас интересует ip 192.16.1.4. При запуске контейнера поднимается локальная сеть и контейнеру дают вышеуказанный ip. В работе с ним получаем следующее. Если обращаемся к базе данных снаружи, то есть вызов идет с компьютера, то к базе данных можно подключиться по локальной сети. Если пробуем подключится к базе данных через вышеупомянутый ip, то получаем ошибку.
Пример подключения с локального компьютера через программу compass
Как видим на примере выше, с компьютера можно подключится к базе данных локально, а по объявленной сети нет.
Логика контейнера для бекенда в файле docker-compose
После того, как разобрался с запуском и подключением к базе данных mongo, далее следовало разобраться каким образом база данных будет взаимодействовать с бекендом в контейнере. В этом случае я также провел эксперименты и пробовал подключать оба вышеописанных варианта. В ходе проб выяснил, что бекенд не может подключится к базе данных по локальному адресу, но может подключится по выделенному ip 192.16.1.4. Здесь у меня возник вопрос, почему так происходит?
В процессе размышления я пришел к следующему выводу. Бекенд поднимается в отдельном контейнере. Базы данных в нем нет. Если в адресе подключения укажем локальный адрес, то подключение будет выполнено в рамках этого же контейнера. А т. к. базы данных нет, то и не к чему подключаться - будет ошибка подключения. Соответственно, если в адресе подключения укажем ip контейнера с базой данных, то вызов пойдет в этот контейнер и, таким образом, у бекенда получится взаимодействовать с базой данных. При этом сам бекенд доступен по 4000-му порту с локального компьютера.
На этом этапе у меня получилось настроить взаимодействие между базой данных и бекендом. Оставалось еще подключить и настроить юай часть для полной картины.
Логика контейнера для юая в файле docker-compose
Сопоставление урлов на стороне юая
На юае у меня возникла другая проблема: server side rendering. Что я хочу этим сказать. Часть кода запускается на стороне бека, часть на стороне юая в браузере. Я столкнулся со следующей проблемой: код, который запускается на стороне сервера перестал корректно работать. Как выяснилось позже, мне нужно было перед запуском юай приложения сопоставить урлы для обращения на бекенд. Если вызов на бекенд идет на стороне сервера — запрос нужно делать через выделенный ip. Если вызов на бекенд идет на стороне клиента — запрос нужно делать через localhost.
Из вышеописанного я для себя сделал следующие выводы:
- Логика общения между контейнерами происходит по их сети. Сам компьютер доступа к этой сети не имеет. Поэтому при разработке этот нюанс нужно учитывать. У меня такое возникло, когда мне пришлось часть вызовов сделать на стороне клиента, а часть на стороне сервера. При этом еще нужно учитывать, что вызов может произойти, как на стороне клиента, так и на стороне сервера и функционал должен уметь определять, когда какой вызов использовать.
- Ранее я всегда запускал бекенд и фронтенд на одной локальной машине. Соответственно они общались между собой по локальной сети. После того, как я перевел разработку на работу в контейнерах, то выявил для себя, что могут быть ситуации, когда работа на одном домене может пойти в минус. Когда перешел на работу с докером, то для меня это стало открытием.
Почему на своем стенде я не буду переводить разворачивание через docker контейнеры?
На своем стенде я решил остаться на старом формате развертывания по одной причине — docker контейнеры требуют больше ресурсов на их содержание. А т. к. я редко обновляю сайт, то мне не имеет смысла переплачивать за лишние ресурсы.
Вывод
В этой статье я более широко раскрыл тему с чем можно столкнуться при переводе разработки в docker контейнеры. В моем случае это были проблемы с сетью и общение между контейнерами.