Transcription
За 10 минут я расскажу и на конкретных примерах покажу, для чего нужен докер и как с ним работать. Не терплю гайды, где люди разливают воду. Хотите полноценно начать работать с докером? Потратьте на это видео всего лишь 600 секунд.
Итак, в обучающих видео все нам начинают рассказывать, что такое контейнеризация, виртуализация и так далее. Когда я был начинающим программистом, для меня слышать все эти слова было жутко. Я просто не понимал, о чём идёт речь и зачем нужен этот докер. Эти сложные термины пугали и просто не давали пройти мне этот барьер понимание, а как без понимания, зачем оно надо, можно что-то изучать.
Поэтому я и решил сделать такое видео. Я при вас разверну приложение и базу данных и свяжу их между собой. Специально допущу множество ошибок и исправлю их. Я надеюсь, что моё видео станет той стартовой точкой, которая позволит тебе в дальнейшем уже углубиться в докеer.
Вот пример. Представь, что ты бэкндер и у тебя есть друг фронтенer, и вы вместе работаете над одним сайтом, и у вас нет общего сервера. У тебя, как у бэкндера, это не вызовет совершенно никаких проблем. Ведь все свои поинты ты можешь вызвать постманом. Но у твоего друга фронтендера реально будет проблема, ведь ему необходимо куда-то отправлять запросы и откуда-то получать ответ, а какого-то сервера в наличии нет. И что делать? Ты можешь попросить своего друга фронтендера установить весь бэкэнд у себя, но для этого ему необходимо будет развернуть базу данных, скачать язык программирования и так далее. Это очень неудобно. Вот было бы здорово, если бы была возможность передать твоему другу всё приложение как есть, и он бы одной кнопкой всё запустил, и у него бы всё работало точно так же, как и у тебя.
С этой задачею может успешно справиться Докер. Ты можешь запаковать всё своё приложение в Docker образ и передать его своему другу. Docker образ - это некий шаблон приложения. Вот что необходимо, чтобы запустить твоё приложение, например, на Java. Для его запуска необходима операционная система, где будет работать твоё приложение плюс сама Java. То есть Docker образ - это некий шаблон, в котором заранее будет установлена операционная система, предустановленные библиотеки плюс язык программирования, само приложение и так далее. В качестве операционной системы обычно выступает Linux.
Давай сразу же разберём пример практического использования готового docker образа. Я подготовил вот такую команду. Docker run. В ней означает, что мы хотим создать от нашего docker образа контейнер. Контейнер - это экземпляр нашего шаблона. По аналогии с ая языками образ - это класс, а контейнер - это объект. Вот это указывает на то, какой образ мы используем. У нас это образ базы данных Поз. И через двоеточие указана версия образа. У нас это последняя. Это проброс портов. Внутри Линукса поднимается база данных порту 5432. Это нам известно заранее в описании образа. Так сделали его создатели. А первый порт - это наш порт. Порт на хостмашине, на той машине, где мы и запускаем doкеerконтейнер. То есть мы как бы связываем наш порт 5432 с портом 5432 внутри контейнера. И все обращения на наш порт будут переадресовываться туда. Мы можем указать и другой порт, например, 5434. Это не имеет значения. Главное, чтобы порт был свободен. Вот это переменные окружение, которые мы задаём при создании. Их названия нам известны заранее. Создателя образа их описали. Я здесь задаю для базы данных имя пользователя, пароль и название самой базы данных. Можно их тут не писать, тогда будут использоваться дефолтные значения. Это название контейнера, который мы создадим от образа. Используется просто для нас, для удобства. Как вы, когда создаёте объект от класса, придумываете ему название. Вот тут то же самое. -D - это флаг, который запускает команду на выполнение в фоновом режиме. То есть, если бы этого флага не было, то мы бы видели логи запущенного постгреса в консоли и наша консоль была бы заблокирована. Мы бы не смогли писать команды.
Дальше запустим команду, попробуем подключиться к нашей базе данных. И вот мы это сделали. Теперь, выполнив такую команду, мы увидим список наших образов. У меня их много разных, но нас интересует наш, вот этот. Его видно в списке. Также это видно в Docker десктоп приложении, которое идёт вместе с Докером. Вот такой командой мы можем вывести список наших запущенных контейнеров. И вот тут вот видно наш экземпляр. Аналогично видно и не в консоли. Мы можем создать ещё один экземпляр. Поменяем только порт и название. И вот теперь у нас их два. Мы можем удалить наш контейнер вот такой командой, но если он запущен, то предварительно его надо остановить. Останавливаю. Вот тут видно, что теперь не горит зелёным. Удаляю. Вот всё, контейнер пропал. Аналогично можно сделать и отсюда, нажав на Delete.
Как вы понимаете, Docker - это отличный инструмент, как для разработки, так и для деплоя вашего приложения. Но для того, чтобы продуктивно им пользоваться, необходимо уметь разрабатывать такие приложения, писать чистый код, такой код, за который не будет стыдно, чтобы потом не трястись на испытательном сроке или легко проходить собеседование. Самый простой и быстрый способ это сделать - это найти себе ментор. Я являюсь основателем учебной компании Col и ментором уже более 2 лет. В нашей практике было множество кейсов. Кто-то учился с нуля, кто-то закончил курсы и не смог трудоустроиться. Всем мы помогали, доучивали, трудоустраивали и тебе готовы помочь. Ускорь свой процесс обучения с нами, с менторами команды.
Теперь я запущу своё приложение, которое приконнектится к базе данных. Там уже указаны верные коннекты. Моё приложение автоматически создало таблицу Posts. Как видно, в ней пока нет записей. Я создал метод, который создаёт эти записи. Выполним его. И вот запись создалась.
Давайте теперь создадим свой кастомный образ, но только для нашего приложения. Но перед этим разберёмся, что нам необходимо сделать, чтобы через консоль запустить приложение. Для Java для начала необходимо выполнить сборку проекта через MVN Clean Install. После чего у нас создалась папка Target, в котором лежит наш джарник. Теперь через команду Java jar мы можем запустить наш джарник. Ну и всё, приложение запустилось. Через Ctrl C я его остановлю.
Разобравшись с тем, как необходимо запускать наше приложение через консоль, мы можем начать описывать наш Docker файл. Первым делом необходимо его создать в корне проекта. В начале команды Chrome. М я указываю, что я буду использовать в качестве базового образа. Ведь нам необходима какая-то стартовая точка, какой-то Linux, где мы будем всё описывать. Вот я выбрал такой. В нём сразу же стоит Linux, Mavon и Java. Но где я его нашёл? Для этих целей есть сайт DockerHub. Это как GitHub для хранения кода, только для образов. Из него мы наш базовый образ и скачаем. Аналогично было и с постгресом ранее, но либо ты можешь просто спросить у чат GPT. Я как-то про него не сказал и в комментариях меня засрали. Вот теперь говорю. Следующая команда задаёт рабочую директорию внутри нашего Линукса. То есть мы создаём папку app и переходим в неё. Аналог такого действия на Виндоусе. Вот. Теперь мы копируем наш повник и папку SRC из нашей хостмашины, с нашего ПК в Docker образ, в Linux, в папку App. Теперь у нас есть всё необходимое, чтобы запустить сборку проекта через MAV. Команда Run в Docker файле позволяет нам запускать команды внутри базового образа. После этого мы указываем порт, на который сможем в дальнейшем сделать проброс портов, как делали с примером Постгреса. Ну и теперь мы можем запустить наш джарник. Здесь мы уже используем не команду Run, как с Мавином, а команду ЦМД. Разница в том, что RAN запускается при сборке образа, а ЦМД при старте контейнера. То есть мы заранее подготовили всё, что можно для старта, для того чтобы контейнер потом максимально быстро запустился и выполнил лишь одну команду.
Теперь, чтобы собрать образ, надо выполнить команду Docker Build, где флагом Т указывается название образа, и точкой обозначаем контекстом текущую директорию, откуда мы выполняем команду. Контекст означает то, что Docker файл будет находиться в текущей директории и различные команды типа копи будут работать относительно этой директории. Выполнив эту команду, мы видим, что теперь у нас локально есть наш образ. Мы можем создать от него контейнер знакомый нам командой. Ранее в Expos мы указывали порт 8080. Вот тут я его прокидываю и сопоставляю со своим портом на хостмашине 8085. Запустим команду. И что мы видим? Ошибка. Мы не смогли подключиться к базе данных по адресу local host 5432. Но почему? Ведь у нас есть запущенная база данных, и я к ней подключён. Дело в том, что Local host 5432 - это хост внутри контейнера, внутри Линукса, а не хост машины ПК, откуда запускались контейнеры. То есть у нас просто нет связи между двумя контейнерами, и мы не можем приконнектиться к базе данных. А в качестве учебного задания попробуй улучшить свой образ, оформить всё в несколько стейджей, сделать мультистйдж сборку. Это сделает твой образ меньше по объёму и твой контейнер будет запускаться быстрее. Текущий проект и все команды я выложил в своём Telegram-канале. ты можешь склонировать проект к себе и поиграться с докером. Также туда я залью и решение этой задачи, где подробно всё объясню.
Чтобы создать эту связь, нам необходимо создать network. Команда выглядит следующим образом. Создаём. После создания нам необходимо пересоздать контейнер с базой данных, но теперь ещё и указать наш созданный нетворк. Предыдущий контейнер я заранее удалил. Аналогично поступим и с нашим образом, только укажем ещё и переменную окружения Postgress Host, которую я заранее определил в проекте. Вот она. В качестве значения в нём указываем название контейнера с нашей базой данных. В итоге получится, что мы обращаемся не к local host 5432, а к Docker Up Postgress 1 5432. И так как у нас есть общий нетворк, Docker легко найдёт этот контейнер и пойдёт в него. Выполняем команду. Давайте посмотрим логин. Видно, что всё поднялось и нет ошибок. Надо проверять работоспособность постманом. Но вот не задача. Выдаёт ошибку. Посмотрев логи внимательно, мы можем заметить, что наш сервис запустился на порту 8085 внутри контейнера, а мы сделали проброс порта на порт 8080. При этом в Expass указали порт 8080, поэтому наш запрос просто не доходит до нашего сервиса. Давайте поменяем порт на 8085. Удалим наш запущенный контейнер с приложением. Запустим сборку образа по новой и запустим контейнер от нашего образа. Только укажем порт 8085. Пробуем постманом. Теперь у нас всё успешно отработало.
Вернёмся к нашему примеру фронтдера и бэкэндера. Но как передать это всё таким образом фронтдеру, чтобы он запустил одной командой? Не хочется, чтобы он заморачивался с неетворком и пробросами портов. Для этих целей подойдёт Docker compos. Он предназначен для запуска нескольких контейнеров из различных образов. Для начала создадим файл docker compost yamel в корне проекта. Далее создадим сервис Погрос. Это просто название в рамках файла. Укажем название контейнера, переменное окружение и проброс портов. Всё как и в нашей прошлой команде. В сервисе приложения у нас нет образа. Образ создаётся из Docker файла, поэтому укажем, откуда нам необходимо собирать этот Docker файл. То есть укажем контекст, укажем название контейнера, пробросим порты, установим переменные окружения и добавим блок depends on. Этот блок говорит нам о том, что этот контейнер зависим от контейнера с погросом, значит, его надо запустить только после запуска контейнера с базой данных. Здесь мы не указываем network. Нетворк создаётся автоматически, поэтому мы можем сразу в переменное окружение в приложении указать название контейнера с постгресом. Чтобы всё запустилось, необходимо выполнить следующую команду. Флаг -D говорит о том, что команда должна быть выполнена в фоновом режиме. Как вы видите, у нас создался контейнер с постгресом, контейнер с нашим приложением и network. В Docker Desktop это всё выглядит следующим образом. Проверим работу постманом. Всё работает. Теперь получается, для того, чтобы нашему фронтендеру выполнить всё одной командой, ему необходимо написать в проекте Rish Docker Compos up, и у него всё заработает.
Docker - это отличный инструмент для программиста любого уровня, но только лишь с ним вы никогда не найдёте работу. Необходимы знания множества технологий. Для этих целей многие решают воспользоваться услугами ментора. Но сейчас под видом ментора есть множество инфациган, и я сделал обзор на них в своём видео. Посмотри обязательно, чтобы потом не потерять своё время и деньги.