Деплоим приложение с Dokku

Деплоим приложение с Dokku

Часто хочется иметь налаженный процесс деплоя для своих пет-проектов. С какими-то серьезными инструментами типа Jenkins заморачиваться не хочется. Есть альтернативы: Github Actions | rsync | Dokku. В этой статье расскажу немного про Dokku, о том как настроить и задеплоить свое первое приложение на примере Telegram бота @ytb_cover_bot, который скачивает для вас превьюшку с видео youtube или трека youtube music. Оговорюсь, что для таких приложений (ботов) есть своя специфика, поэтому в конце задеплоим и обычный веб сайт.

Dokku - это инструмент, позволяющий настраивать и деплоить ваши приложения, как если бы вы это делали на Heroku, но только на вашем сервере. Деплой происходит пушем в ремоут ветку dokku (который хостится на вашем сервере) обычной командой git push. При этом логи деплоя можно увидеть сразу в консоли. У dokku вообще много фичей и настроек, я расскажу лишь только о базовой конфигурации, которой мне хватает.

Установка

Установить его можно как standalone приложение, так и в докере. Я выбрал второй вариант (т.к. с первым были ошибки, возможно из-за скромных свободных ресурсов моего сервера) .

Процесс установки описан тут, дублировать, думаю, нет смысла. Обращу внимание, что нужно не забыть открыть порты на вашем сервере, которые определены для dokku контейнера 3022, 8080, 8443.

Первоначальная настройка dokku

На сервере заходим в контейнер (если вы установили в докере, если нет, то выполняйте все команды в обычной консоли):

docker exec -it dokku bash

Можно кстати в алиасы прописать команду:

nano ~/.bash_aliases
alias dokku="docker exec -it dokku dokku" # add this line then re-login with your linux account

Для доступа к приложениям после деплоя для dokku желательно привязать домен (один для всех приложений). Это необязательный шаг, просто это упрощает доступ (проверьте настройки Wildcard domain *.domain.tld A Record у вашего домен провайдера):

domains:add-global jem-art.ru

В итоге приложения будут доступны по адресу scheme://app-name.jem-art.ru

Если вы (как и я) спустя какое то время забыли к какому домену привязали dokku, то можно посмотреть его в конфиге domains для любого из приложений

dokku domains:report app-name

Domains app enabled:           true
Domains app vhosts:            ytb-image-bot.jem-art.ru
Domains global enabled:        true
Domains global vhosts:         jem-art.ru

Теперь сгенерируем ssh ключ на вашем локальном компьютере откуда вы будете деплоить (чтобы абы кто не мог пушить в ваш dokku)

ssh-keygen -f dokku_rsa

Скопируем контент ключа cat dokku_rsa.pub

И добавим его на сервере в dokku

echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCs6DIF bla bla bla" | dokku ssh-keys:add dokku_rsa

Т.к. мой dokku запущен под докером, то у меня настроен маппинг портов 3022 (сервер) -> 22 (контейнер) и чтобы зарезолвить такой ssh хост, добавим соответствующий конфиг в ~/.ssh/config на локальном компе:

Host dokku.docker 
HostName 104.131.22.43 
Port 3022  
IdentityFile ~/.ssh/dokku_rsa

Создание приложения

Наконец создадим наше приложение ytb-image-bot

dokku apps:create ytb-image-bot

Теперь добавим remote в git

git remote add dokku [email protected]:ytb-image-bot

Теперь при выполнении git push dokku master у нас будет стартовать деплой и перезапуск приложения. Стартанем его чуть позже, а пока добавим еще некоторые настройки.

В репозитории приложения добавим Procfile для того, чтобы описать какую команду надо выполнить чтобы запустить приложение. Т.к. у меня telegram бот, а не веб-сервер, то я добавляю worker: worker: yarn start

Если бы это был веб-сервер, то нужно было бы добавить директиву web - при этом dokku автоматически делает мапинг портов на порт 5000 для вашего приложения (поэтому если не хочется добавлять какие то доп переменные окружения, то лучше чтобы сервер слушал порт 5000).

Не забудем сконфигурировать dokku на использование worker

dokku ps:scale ytb-image-bot worker=1

Добавим нужные env переменные командой с флагом --no-restart через пробел (без флага dokku будет пытаться перезапустить приложение которого еще нет и в итоге так и не проставит переменные)

dokku config:set ytb-image-bot --no-restart TG_TOKEN=YOUR_TOKEN MONGOURL=mongo://blabla21

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

По дефолту dokku во время деплоя не останавливает предыдущую версию приложения, но у меня telegram бот, который работает по long-polling. И если будет запущено 2 инстанса с одним и тем же ключом, то будут сыпаться ошибки, и в итоге dokku прервет деплой новой версии. Для этого выключим zerodowntime

dokku checks:disable ytb-image-bot

Для обычных веб приложений zerodowntime, конечно, топ фича.

Вот и все, делаем комит и пушаем его в dokku git push dokku master

Результат деплоя в консоли. Т к у нас не web-приложение, то https://ytb-image-bot.jem-art.ru/ у нас не отвечает. Зато отвечает @ytb_cover_bot 😊 (как и @easy_peasy_tiktok_bot, который деплоится таким же способом).

Деплоим веб-приложение

Отличий для веб не так много.
Создаем проект на сервере так же как и предыдущий:

dokku apps:create web-test

На локальном компе добавляем ремоут:

git remote add dokku [email protected]:web-test

Добавляем Procfile с директивой web: web: yarn start или web: node index.js

Пушаем git push dokku master

Наслаждаемся результатом 😊 (я ленивая жопа не сделал сертификаты для * доменов, но по http работает) .

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