Готовим deb из наших бинарников
Go прекрасный язык. Одна из его супер-сил - это возможность собирать все в один бинарник. А это очень удобно, вы можете везде таскать этот файл и использовать на любой машине. Но хочется иметь возможность устанавливать нашу программу простым способом.
С помощью deb пакетов довольно просто можно организовать деплой на ваши сервера. При этом у вас будет версионирование и все такое. Я чаще всего использую ubuntu, поэтому речь будет именно о deb пакетах, которые можно установить/удалить с помощью утилит apt
.
Что же нужно сделать, для создания своего репозитория с пакетами? Можно воспользоваться тем же launchpad.net, например. Но, последнее время, он не очень развивается и выглядит ненадежно. К тому же, его удобно использовать для своих не коммерческих разработок, но использовать его для дистрибуции корпоративного ПО будет проблематично.
Подойдем к проблеме с другой стороны. Во первых, нам нужно собирать deb пакеты, а это очень просто сделать самим с помощью утилиты dpkg-deb
. Во-вторых, нам нужно где-то эти пакеты размещать, и для этого мы воспользуемся супер простым сервером apt репозиториев deb-simple
Сборка пакетов
Для всех своих проектов я использую gb. Структура проекта выглядит примерно так:
project/
|- bin/
| |- project
|- src/
| |- github.com/
| |- 4gophers/
| |- project/
| |- main.go
|- vendor/
Когда я запускаю gb build
, то все бинарники собираются в папке bin
. Таким образом, все что нам нужно - это просто добавить спецификацию нашего будущего deb пакета прям в папку с проектом:
mkdir project/DEBIAN
touch project/DEBIAN/control
В результате будет такая структура:
project/
|- DEBIAN/
| |- control
|- bin/
| |- project
|- src/
|- vendor/
В файле control
нужно указать информацию о нашем пакете. Не забывайте про пустую последнюю строку:
Package: project
Priority: optional
Section: devel
Installed-Size: 100
Maintainer: Ivan Ivanov <test@test.ru>
Architecture: i386
Version: 1.0
Depends: libc6 (>= 2.1)
Description: Short description here
Long description here
- Package — имя вашего пакета
- Priority — приоритет пакета (optional, extra, standard, important, required) для обычных программ лучше ставить optional
- Section — раздел к которому относится данный пакет (admin, base, comm, contrib, devel, doc, editors, electronics, embedded, games, gnome, graphics, hamradio, interpreters, kde, libs, libdevel, mail, math, misc, net, news, non-free, oldlibs, otherosfs, perl, python, science, shells, sound, tex, text, utils, web, x11)
- Installed-Size — размер файлов пакета в килобайтах
- Maintainer — имя и email создателя пакета
- Architecture — архитектура процессора, для которой предназначен пакет (i386, amd64, all, source, all)
- Version — версия пакета
- Depends — в данном поле необходимо указать имена пакетов, от которых зависит ваш пакет (например, библиотеки)
- Description — в первой строке пишем короткое описание пакета, в остальных более подробно
Все что находится в папке project
попадет в пакет. И папка bin
тоже. В этой папке лежит наш бинарный файл, который нужно установить. Чтобы ваши файлы оказались в нужной директории на компьютере пользователя, нужно создать соответствующую структуру каталогов внутри вашей папки с проектом.
Стоит отметить, что такой подход к созданию deb пакетов не самый правильный. Конечно, в нашем случае мы осознанно идем на этот шаг, но вам нужно понимать, что в deb пакет попадет все содержимое папки project
, в том числе папки src
, vendor
и так далее. Конечно, можно скопировать файлы в другую папку, и даже написать скрипт для этого, но все уже придумано до нас. Более правильный способ - это использовать утилиты dh_make
и dpkg-buildpackage
.
Теперь можно собирать пакет. Для этого на уровень выше выполним команду:
dpkg-deb -z8 -Zgzip --build project
На уровень выше будет создан файл project.deb
, который можно устанавливать с помощью команды:
sudo dpkg -i project.deb
Больше информации о правильной сборке deb пакетов можно узнать в официальной документации.
Свой репозиторий пакетов
Теперь переходим к самому интересному. Как же нам распространять наши пакеты? Запустим свой сервер репозиториев, конечно же. А для этого воспользуемся сервером apt репозиториев deb-simple.
Это действительно простой сервер, который устанавливается всего одной командой:
go get github.com/esell/deb-simple
Если go не установлен на той машине, где вы собираетесь запустить сервер с репозиториями, то вы можете собрать бинарник локально и просто скопировать его. Кроме этого, можно использовать docker.
Затем нужно запустить сервер. Это можно сделать с помощью docker, но мне больше нравится использовать supervisord. Вот пример моей конфигурации сервиса:
[program:deb-simple]
command=/home/user/go1.5/bin/deb-simple
directory=/home/user/deb-simple/
autorestart=true
stdout_logfile=none
Тут важно указать путь к бинарнику(command
) и рабочую папку(directory
), в которой мы разместим наш конфиг.
Сервер deb-simple поддерживает https, но пока нам это не нужно. Для репозиториев нужно создать папку repo
. Наш конфиг conf.json
будет выглядит так:
{
"listenPort" : "9090",
"rootRepoPath" : "/home/user/deb-simple/repo",
"supportedArch" : ["all","i386","amd64"],
"enableSSL" : false,
"SSLcert" : "server.crt",
"SSLkey" : "server.key"
}
Чтобы загрузить пакет в свой репозиторий, нужно воспользоваться HTTP API самого сервиса:
curl -XPOST 'http://localhost:9090/upload?arch=amd64' -F "file=@project.deb"
Точно так же для удаления:
curl -XDELETE 'http://localhost:9090/delete' -d '{"filename":"project.deb","arch":"amd64"}'
Нам осталось добавить наш сервер репозиториев к списку в /etc/apt/source.list.d/
. Можно создать отдельный файл с содержимым:
deb http://my-hostname:9090/ stable main
Теперь запускайте sudo apt-get update
и устанавливайте свои программы сколько душе угодно.