Как я Telegram бота на Go писал. Часть пятая. Docker-изируй это!
На днях наконец-то решил добраться до такой хайповой темы как Docker:
Docker — программное обеспечение для автоматизации развёртывания и управления приложениями в среде виртуализации на уровне операционной системы. Позволяет «упаковать» приложение со всем его окружением и зависимостями в контейнер, который может быть перенесён на любую Linux-систему с поддержкой cgroups в ядре, а также предоставляет среду по управлению контейнерами. Изначально использовал возможности LXC, с 2015 года применял собственную библиотеку, абстрагирующую виртуализационные возможности ядра Linux — libcontainer. С появлением Open Container Initiative начался переход от монолитной к модульной архитектуре. (Википедия)
И, в качестве эксперимента, решил развернуть одного из своих ботов на VDS внутри контейнера для простоты переноса и развёртывания. Бот написан на Go и, соответсвенно, это делает развёртывание немного нетривиальным (на самом деле, если читать документацию и уметь пользоваться поисковыми системами, то всё довольно просто).
Начнём.
Во-первых, необходимо установить Docker. На моём ноутбуке с Ubuntu 16.04 всё завелось довольно просто по инструкции из документации.
На этом моменте должно быть понятно, что основной файл для Docker - Dockerfile
. В этом файле описывается, что необходимо “сделать” контейнеру: какой базовый образ использовать, какие зависимости уствновить, какие переменные окружения задать.
Во-вторых, необходимо написать Dockerfile для бота (или любого другого приложения) на Go. У Go есть свои “особенности” связанные с GOROOT
или GOPATH
. Но до нас уже постарались и сделали базовый образ в котором необходимо только установить зависимости (я сделал “в лоб”, но по уму лучше все зависимости получать одним из многих менеджеров зависимостей, например, Godep, про который я писал ранее), собрать приложение и запустить:
# Используем базовый образ для Go
FROM golang:latest
# Создадим директорию
RUN mkdir /app
# Скопируем всё в директорию app
ADD . /app/
# Установим рабочей папкой директорию app
WORKDIR /app
# Получим зависимости, которые использовали в боте
RUN go get github.com/botanio/sdk/go
RUN go get gopkg.in/telegram-bot-api.v4
# Соберём приложение
RUN go build -o main .
# Запустим приложение
CMD ["/app/main"]
В-третьих, требуется собрать Docker-образ командой
docker build -t my_bot .
Флаг -t
позволяет задать образу тег, которые будет являться именем образа. Точка в конце команды указывает, что собираться образ нужно из текущей директории.
Собранный образ будет “храниться” в локальном Docker Registry - хранилище образов. Посмотреть все доступные образы можно командой
docker image ls
Среди них должен быть наш новый образ.
Теперь свежесозданный образ можно запустить выполнив следующую команду:
docker run my_app
На этом можно было бы закончить, но нет.
В-пятых, требуется каким-то образом перенести наш образ на VDS. Самый простой способ - воспользоваться возможностями Docker Hub - глобальным Docker Registry. В бесплатном плане есть возможность создать один приватный образ и, кажется, сколько угодно бесплатных (приавтность/публичность образа меняется через веб-морду).
Для этого потребуется зарегистрироваться в Docker Hub и с этими данными залогиниться через утилиту docker
:
docker login
После успешного входа можно заливать образ в Hub. Делается это очень просто:
- Зададим тег образу по формату, которого требует Hub:
docker tag my_app USERNAME/my_app:latest
, гдеUSERNAME
ваш логин в Docker Hub,latest
- своего образа версия в Docker Hub (можно не указывать) - Зальём образ в registry:
docker push USERNAME/my_app:latest
В-шестых, заходим на наш VDS (если нет VDS, то можно локально или на другом компьютере) с настроенным по инструкции выше Docker и выполняем команду docker run USERNAME/my_app:latest
. Docker получит образ из Hub, сохранит в локальный Regestry и запустит. Если всё сделано правильно, то бот (или любое другое приложение) должно заработать.
На этом пока всё.