---
title: "📦 Создание .deb пакета | dpkg-deb"
date: 2025-06-03T14:35:45+03:00
draft: false
tags: [linux, package, tutorial]
---

> Заметка является моим вольным переводом статьи
**internal / pointers**:
[Building binary deb packages: a practical guide](https://www.internalpointers.com/post/build-binary-deb-package-practical-guide)

# 📄 Инструкция по созданию `deb` пакета

Файл deb - это архив, содержащий данные программы и другие необходимые ресурсы.
Он используется для простого распространения и установки программ для Debian/Ubuntu и производных от них. Имеет расширение файла `.deb`.
Файлы `.deb` удобны, когда приложению необходимо позаботиться о дополнительных зависимостях,
выполнить интеграцию с рабочим столом, запускать сценарии до и после установки и так далее.


## 🩻 Анатомия `deb` пакета

`.deb` - это стандартный архив Unix, содержащий приложение и другие служебные файлы.
Наиболее важным из них является управляющий файл **control file**
в котором хранится информация о пакете и программе, которую он устанавливает.

Пакет `.deb` содержит набор папок, имитирующих типичную файловую систему Linux, таких как `/usr`, `/usr/bin`, `/opt` и так далее.
Файл, помещенный в один из этих каталогов, будет скопирован в то же место в реальной файловой системе во время установки.
Так, например, двоичный файл, помещенный в `<.deb>/usr/local/bin/binaryfile`, будет установлен в `/usr/local/bin/binaryfile`.

Все файлы пакетов `.deb` соответствуют определенному соглашению об именовании:

```text
<name>_<version>-<revision>_<architecture>.deb
```

То есть:

* `<name>` – название приложения;
* `<version>` – номер версии приложения;
* `<revision>` – номер версии текущего пакета;
* `<architecture>` – аппаратная архитектура.

Например, необходимо сделать пакет для программы под названием `hello` версии `1.0`, созданную для 64-разрядных процессоров ARM.
Имя файла `.deb` будет выглядеть примерно так `hello_1.0-1_arm64.deb`.


## 🧰 Создание `deb` пакета

Убедитесь, что в вашей системе установлена программа `dpkg-deb`: она необходима для создания окончательного архива.


### 📂 1. Создание рабочего каталога

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

```sh
mkdir hello_1.0-1_arm64
```

### 🗃️ 2. Создание внутренней структуры

Поместите файлы программы туда, куда они должны быть установлены в целевой системе.
Например, необходимо, чтобы программа была установлена в `/usr/local/bin`:

```sh
mkdir -p hello_1.0-1_arm64/usr/local/bin
```

Флаг `-p` для команды `mkdir` создаст вложенные каталоги.  
Далее нужно скопировать исполняемый файл в этот каталог:

```sh
cp ~/YourProjects/Hello/hello hello_1.0-1_arm64/usr/local/bin
```


### 🕵🏻‍♀️ 3. Создание управляющего файла

Файл `control` находится в каталоге `DEBIAN`.  
Обратите внимание на заглавные буквы. Аналогичный каталог с именем `debian` (в нижнем регистре)
используется для хранения исходного кода так называемых [пакетов с исходным кодом](https://www.debian.org/doc/debian-policy/ch-source.html).
Это руководство посвящено бинарным пакетам, поэтому оно нам не нужно.

Давайте сначала создадим папку `DEBIAN`:

```sh
mkdir helloworld_1.0-1_arm64/DEBIAN
```

А затем создайте пустой управляющий файл:

```sh
touch helloworld_1.0-1_arm64/DEBIAN/control
```


### 📝 4. Заполнение управляющего файла

Файл `control` - это просто список полей данных. Для бинарных пакетов существует минимальный набор обязательных полей:

* `Package` – название программы;
* `Version` – версия программы;
* `Architecture` – целевая архитектура;
* `Maintainer` – имя и адрес электронной почты лица, ответственного за обслуживание пакета;
* `Description` – краткое описание программы.

Для примера:

```text
Package: hello
Version: 1.0
Architecture: arm64
Maintainer: Ivan Sumkin <info@test.com>
Description: Программа, которая приветствует вас.
 Вы можете добавить более подробное описание здесь. Обратите внимание на пробелы в начале этого абзаца.
```

Файл `control` может содержать дополнительные полезные поля, такие как [`раздел`](https://www.debian.org/doc/debian-policy/ch-archive.html#s-subsections),
к которому он принадлежит, или [список зависимостей](https://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps).

Последнее чрезвычайно важно, если для корректной работы вашей программы требуются внешние библиотеки.  
При желании вы можете заполнить его вручную, но есть вспомогательные инструменты, которые облегчат эту задачу.
Как это сделать будет показано в следующих нескольких абзацах.


### 🛠️ 5. Создание `deb` пакета

Это последний шаг. Вызовите `dpkg-deb` следующим образом:

```sh
dpkg-deb --build --root-owner-group <package-dir>
```

Итак, в нашем примере:

```sh
dpkg-deb --build --root-owner-group <helloworld_1.0-1_arm64>
```

Флаг `--root-owner-group` делает все содержимое пакета `deb` принадлежащим пользователю `root`, что является стандартным способом.  
Без такого флага все файлы и папки принадлежали бы пользователю, которые могли бы отсутствовать в системе, в которую был бы установлен deb-пакет.

Приведенная выше команда сгенерирует файл `.deb` рядом с рабочим каталогом или выдаст сообщение об ошибке,
если что-то не так или отсутствует внутри пакета.  
Если операция прошла успешно, пакет `,deb` готов к распространению.


## 🎯 Тестирование `deb` пакета

Рекомендуется протестировать ваш deb-пакет после его создания.  
Вы можете установить его как любой другой обычный deb-пакет:

```sh
sudo dpkg -i <package>
```

Убедитесь, что его также можно легко удалить. Вы можете просто удалить пакет:

```sh
sudo dpkg -r <appname>
```

Или удалить его вместе с конфигурационными файлами (если таковые имеются):

```sh
sudo dpkg -P <appname>
```

Убедитесь, что приложение было удалено правильно, выполнив:

```sh
dpkg -l | grep <appname>
```

Команда `dpkg -l` выводит список всех установленных пакетов, в то время как `grep` выполняет поиск по `<имя_программы>`.  
Если приложение было удалено правильно, выходные данные должны быть пустыми.


### 🐞 Иногда установка `.deb` идёт неправильно

Особенно, когда вы имеете дело со сценариями до/после установки или удаления, которые в какой-то момент дают сбой.
Это типичное сообщение об ошибке от `dpkg`, что препятствует какому-либо прогрессу.

```text
Package is in a very bad inconsistent state - you should reinstall it before attempting a removal.
```

Хитрость заключается в том, чтобы переместить все ссылки на ваш поврежденный пакет в безопасное место
(например, в каталог `/tmp`), а затем принудительно удалить его, например, так:

```sh
sudo mv /var/lib/dpkg/info/<packagename>.* /tmp/
sudo dpkg --remove --force-remove-reinstreq <packagename>
```


## 👨‍👩‍👦 Забота о внешних зависимостях

Вы можете сгенерировать их автоматически с помощью `dpkg-shlibdeps`. Программа проанализирует ваш двоичный код и выполнит поиск внешних символов.

```sh
dpkg-shlibdeps -O path/to/binary/file
```

Флаг `-O` выведет зависимости.  
Скопируйте выход терминала и вставьте его в раздел `Depends` вашего файла `DEBIAN/control`.
После этого вы можете избавиться от файла `debian/control`.


## 🤖 Запускайте скрипты до или после установки и удаления пакета

Четыре файла: `postinst`, `preinst`, `postrm` и `prerm` называются сценариями сопровождающего.

Эти файлы находятся в каталоге `DEBIAN` и, как следует из их названий,
`preinst` и `postinst` запускаются до и после установки,
в то время как `prerm` и `postrm` выполняются до и после удаления.
Они должны быть помечены как исполняемые файлы.
Кроме того, не забудьте указать права доступа: они должны быть в диапазоне от `0555` до `0775`.
