Инструкция как запустить проект в докере.
Устанавливаем docker и docker-compose
Версии:
- docker 19.0+
- docker-compose 1.25+
Только прежде чем приступить к установке: так как у тебя диск жесткий разбит и постоянные траблы с местом на диске, сначала на большом диске (который не основной, а под всякие данные) создай папку docker и залинкуй ее на основной диск
sudo ln -s {путь к созданной папке} /var/lib/docker
Чтобы докер все образы и т.п. там хранил. А то каждый день чиститься будешь :)
Процесс установки описан здесь. Только не все ставь, а только указанное ПО. И там написано как пользователя добавить в группу docker, чтобы можно было контейнерами управлять без вызова sudo.
Запуск докер-проекта
Прежде всего, если ты с гитом все еще не работаешь через ssh, то ключ себе сделай. Вот тут описана процедура: https://docs.github.com/en/github/authenticating-to-github/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent
Плюс использования ключа в том, что тебе не придется каждый раз вводить логин/пароль там, где потребуется авторизация.
Этот же ключ можно будет использовать для доступа к серверам на digitalocaen ;-)
- Скачиваем проект
git clone --recurse-submodules https://github.com/Pivkarta/docker docker-pivkarta (или если ssh настроил, то git clone --recurse-submodules git@github.com:Pivkarta/docker.git docker-pivkarta )
cd docker-pivkarta
- Читаем readme.md, там прописаны актуальные первичные шаги. Сейчас прописано следующее:
На локальной машине можно .env и не редактировать (оставить пароли по умолчанию), но на проде конечно же надо отредактировать.
Запускаем контейнеры
Я специально в композ-файле не прописываю зависимости контейнеров, чтобы можно было на одном сервере сразу несколько проектов запускать, так что придется запускать контейнеры с явным указанием оных. Да и лучше их все прописать, чтобы было понятно что для чего.
Быстрый старт (только фронт)
Для того, чтобы быстро получить результат и в меньшие дебри лезть, запустим пока только фронт.
API_ENDPOINT=https://pivkarta.ru/api/ docker-compose -f docker-compose.yml -f docker-compose.dev.yml up --build pivkarta.ru-2
Будет довольно долго выполняться (особенно в первый раз, потому что еще надо будет ему скачать нужные докер-образы). Должно быть типа такого:
Когда контейнер будет запущен, можно зайти на адрес http://localhost:3100. Должен открыться сайт. В дев-конфиге прописана линковка на исходники в локальной файловой системе, так что можно редактировать файлы в своей IDE как есть, изменения будут учитываться и в контейнере.
Если все ОК, то жмем CTRL+C, чтобы завершить выполнение программы. В этот момент у нас и контейнер остановится, потому что он работал в режиме программы. Чтобы этого не происходило, и он продолжал работать дальше, выполняем то же самое, только с флагом -d
API_ENDPOINT=https://pivkarta.ru/api/ docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d --build pivkarta.ru-2
Теперь, когда контейнер пересоберется (а сейчас он очень быстро это сделает, потому что никаких изменений в нем не было), команда успешно завершится и все. При этом контейнер продолжет работать. Чтобы его остановить, надо будет выполнить
docker-compose stop pivkarta.ru-2
Если надо будет удалить потом, то docker-compose rm pivkarta.ru-2
Выполнение команд внутри контейнера.
Иногда надо выполнить какую-нибудь команду в самом контейнере, например yarn generate:types.
Для этого нам надо зайти в нужный нам контейнер. Откроем еще один терминал и выполним в директории проекта docker-compose ps. Найдем в списке наш контейнер и его имя (скорее всего будет docker-pivkarta_pivkarta.ru-2_1).
Выполняем docker exec -it docker-pivkarta_pivkarta.ru-2_1 bash
Если ОК, то мы оказываемся внутри контейнера, то есть как бы в другом компьютере. Только следует учитывать, что конкретно этот образ не на базе ubuntu создан, а alpine-linux. Некоторые командыы могут отличаться (например, не apt install, а apk add). И вот, когда мы внутри, выполняем yarn generate:types.
Полный запуск (с базой данных и прочим)
MySQL
docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d mysql
Расшифрую:
1. docker-compose - команда
2. -f docker-compose.yml -f docker-compose.dev.yml - указал для конфигурационных файла.
На проде надо будет -f docker-compose.yml -f docker-compose.prod.yml
3. up -d - субкоманда запуск с флагом -d - запуск в режиме демона. То есть запущенный контейнер будет крутиться как служба, то есть терминал сразу освобождается и его можно будет даже закрыть.
Проверим работу контейнера.
docker-compose ps
Должно быть типа такого:
$ docker-compose ps
Name Command State Ports
-------------------------------------------------------------------------------------------------
docker-pivkarta_mysql_1 docker-entrypoint.sh mysqld Up 0.0.0.0:3306->3306/tcp, 33060/tcp
Здесь видно, что контейнер с персональным именем docker-pivkarta_mysql_1 работает (State Up) и открыт внешний порт 3306 указывающий на внутренний 3306 (0.0.0.0:3306->3306/tcp), а так же работает внутренний 33060.
То есть все как и ожидалось.
4. имя службы (service).
Все службы и их конфигурации прописаны в docker-compose.yml. Дополнительные файлы типа docker-compose.dev.yml содеражат переопределяющие конфиги для этих служб (не обязательно для всех).
PhpMyAdmin
docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d pma
Закрепим материал и еще раз выполним docker-compose ps
Видим:
$ docker-compose ps
Name Command State Ports
----------------------------------------------------------------------------------------------------
docker-pivkarta_mysql_1 docker-entrypoint.sh mysqld Up 0.0.0.0:3306->3306/tcp, 33060/tcp
docker-pivkarta_pma_1 /docker-entrypoint.sh apac ... Up 0.0.0.0:8090->80/tcp
У нас уже два работающих контейнера. Обрати внимание, что у pma внешний и внутренний порты отличаются. Это не страшно. Это как раз фишка докера - можно запустить несколько сервисов, каждый из которых используют один и тот же порт, но указать им разные, чтобы они не конфликтовали. То есть хотя PhpMyAdmin в контейнере и крутится на порту 80, для доступа к нему мы используем адрес http://localhost:8090
Откроем этот адрес в браузере и увидим привычный PhpMyAdmin. Если пароль в .env не менял, то используем указанные по умолчанию логин/пароль: root/prisma
Инспектирование контейнеров
Вот здесь важно сразу понять что за что отвечает.
docker-compose - это всего лишь утилита оркестрации докер-контейнеров. При чем ее даже не рекомендуют использовать в продакшене, типа есть более правильные инструменты (но я их пока не освоил). Само же ядро этой системы - сам docker. То есть все команды так или иначе выполняются через docker. Просто в докере одна команда - один контейнер (ну, кроме типа docker ps, который выводит список контейнеров). А docker-compose создан, чтобы управлять проектами. При этом проекты могут содержать и по одному контейнеру, не обязательно несколько. Суть просто в том, что создается папка с файлом docker-compose.yml, в котором прописано все необходимое для запуска, и когда мы запускаем из этой папки через docker-compose, последний берет на себя работу по неймингу конечных контейнеров (как у нас получился docker-pivkarta_mysql_1, а не просто mysql), быстрому доступу к контейнерам именно этого проекта и т.п. Без этого, запустив через сам docker из разных проектов кучу контейнеров, нам сложно будет ориентироваться какой контейнер к чему относится. То есть если мы выполним docker ps, то мы увидим все запущенные на этом сервере контейнеры. А выполнив docker-compose ps в папке проекта, мы увидим только те контейнеры, которые относятся конкретно к этому проекту. К примеру, если мы захотим остановить все контейнеры текущего проекта, мы выполним docker-compose stop. А с чистым докером нам пришлось бы явно перечислять контейнеры (или использовать хитрости с фильтрацией, тегами).
Но docker-compose не все команды поддерживает. К примеру нельзя выполнить docker-compose inspect pma. А нам нужна именно эта команда. Поэтому мы обратимся к докеру напрямую docker inspect docker-pivkarta_pma_1
Здесь следует отметить, что в docker-compose мы оперируем именами сервисов, а в docker именами контейнеров, поэтому используем docker-pivkarta_pma_1, а не pma.
Команда inspect покажет нам много полезной информации, в том числе из какого образа контейнер собран, с какими параметрами, какие виртуальные диски подключены и т.п. Нам же сейчас надо просто посмотреть какой ip задан этому контейнеру. Вот эта информация (может конечно же отличаться на вашей машине):
И здесь самая главная для нас информация - "IPAddress": "172.16.6.2", а так же Ports, где видно, что 80-му порту соответствует 8090
То есть контейнеру задан ip 172.16.6.2. А значит мы можем к его внутренним адресам обращаться напрямую по этому адресу. Откроем в браузере http://172.16.6.2 (то есть именно с 80 портом, а не внешним 8090) и увидим, что нам так же откроется PhpMyAdmin. Сейчас смысл всего этого наверняка покажется неочевидным, но просто помни, что здесь эта инфа есть, и она наверняка еще пригодится.
Prisma-сервер
docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d --build prisma
В дев-режиме будет крутиться на порту 4466
API-сервер
docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d --build api
После успеешного запуска (который включает в себя в том числе и деплой схемы в призма-сервер), можно увидеть призма-АПИ, который админский и который не должен быть виден напрямую на прод-сервере. С этим призма-АПИ и работает фронтовый АПИ-сервер. Смотри эндпоинты в .env файле. У тебя их там два (обнови репу докера, я там фикс вылил, и у себя .env поправь):
dev_endpoint=http://prisma:4466/pivkarta/dev
prod_endpoint=http://prisma:4466/pivkarta/prod
Соответственно, если ты АПИ-сервер запускаешь в дев-режиме (или в данном случае правильней сказать не в прод-режиме, потому что только в docker-compose.prod.yml прописано endpoint=${prod_endpoint}), то у тебя призма-АПИ и открывается по адресу http://prisma:4466/pivkarta/dev. Если ты изменишь переменные и пересоберешь АПИ-сервер, то и призма-АПИ заработают на новом адресе (но старые просто так никуда не удалятся).
В базе данных имена баз данных будут со знаками @ вместо /, то есть pivkarta@dev и pivkarta@prod. После первого деплоя надо сделать следующее:
1. Снять актуальный дамп с боевого сайта.
2. В целевой базе призмы удалить вообще все таблицы.
3. Залить дамп базы.
Все, это надо сделать разово. Просто у твоего сайта есть таблицы, про которые призма ничего не знает. И данные она не заливает, а только схему.
proxy-сервер
docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d --build proxy
Конфигурация прокси-сервера прописана в caddy/Caddyfile
Пример отдельного хоста:
То есть запросы на порт 2016 будут проксироваться на api-сервер на порт 4000. В данном случае не важно открыт порт 4000 у api-сервера или нет (вспоминаем написанное выше про внешние и внутренние порты). То есть даже если 4000 порт у него не открыт и нельзя зайти на http://localhost:4000, все равно, когда мы заходим на http://localhost:2016, мы попадаем на http://api:4000