Вопрос или проблема
Я собрал программное обеспечение на C++ на своем ноутбуке с Ubuntu 22.04 и использовал checkinstall
для его установки. Это создало соответствующий .deb
файл, и это приятно.
Но теперь я хочу установить этот .deb
файл в контейнер Docker, основанный на “Debian GNU/Linux 11 (bullseye)”, и dpkg
показывает следующую ошибку:
# dpkg --install mypackage-8.0.0_20221030-1_amd64.deb
dpkg-deb: ошибка: архив 'mypackage-8.0.0_20221030-1_amd64.deb' использует неизвестное сжатие для члена 'control.tar.zst', сдаюсь
dpkg: ошибка при обработке архива mypackage-8.0.0_20221030-1_amd64.deb (--install):
dpkg-deb --control subprocess вернул код ошибки 2
Во время обработки были обнаружены ошибки:
mypackage-8.0.0_20221030-1_amd64.deb
Как я могу установить этот .deb
файл в свой контейнер, не компилируя программное обеспечение снова (что означает, что мне нужно будет установить все инструменты сборки C++, чего я хочу избежать…)?
dpkg
в Debian не поддерживает zstd
сжатие. Чтобы вообще иметь возможность извлечь ваш пакет в Debian, вам нужно конвертировать его:
-
извлечь его компоненты:
ar -x mypackage-8.0.0_20221030-1_amd64.deb
-
распаковать их:
zstd -d control.tar.zst zstd -d data.tar.zst
-
сжать их снова:
xz control.tar xz data.tar
-
воссоздать ваш пакет:
rm mypackage-8.0.0_20221030-1_amd64.deb ar -rc mypackage-8.0.0_20221030-1_amd64.deb debian-binary control.tar.xz data.tar.xz
Это создаст пакет, который dpkg
в Debian сможет, по крайней мере, попытаться обработать. Поскольку ваш пакет был собран на Ubuntu 22.04, вы можете столкнуться с проблемами зависимостей.
Для достижения наилучших результатов вам действительно следует собирать пакет на платформе, на которой вы хотите его использовать. В вашем случае это означает либо использовать ubuntu:22.04
в качестве базового образа вашего контейнера, либо пересобрать ваш пакет в контейнере Debian 11.
Основываясь на ответе Стивена Кита, вот пример фрагмента Bash, который делает это автоматически, а затем устанавливает пакеты с помощью dpkg. Обратите внимание, что вам сначала нужно установить zstd:
BUSTEDPKGS="glade2script
glade2script-python3
boot-sav
boot-sav-extra
boot-repair"
apt-get install --download-only $BUSTEDPKGS
tmp=$(mktemp -d)
pushd $tmp
for P in $(echo "$BUSTEDPKGS" | sed 's/[ ]*$/_/g') ; do
PKG=/var/cache/apt/archives/${P}*
echo "============================================================================="
echo " $PKG"
echo "============================================================================="
ar -x $PKG
zstd -d control.tar.zst
zstd -d data.tar.zst
xz control.tar
xz data.tar
/bin/rm -f ${PKG}-XZ.deb
ar -rc ${PKG}-XZ.deb debian-binary *.xz # порядок имеет значение
dpkg -i ${PKG}-XZ.deb
/bin/rm -f *
done
popd
Ответ или решение
Для установки .deb
файла, созданного с использованием checkinstall
на Ubuntu, в контейнер Docker на основе Debian, вы столкнулись с проблемой совместимости, связанной с форматом сжатия. Ваша ошибка гласит, что dpkg
в Debian не поддерживает сжатие zstd
, используемое в вашем .deb
пакете, что приводит к сбоям при попытке установки. В данном ответе мы подробно рассмотрим, как можно конвертировать ваш пакет для успешной установки в окружении Debian.
Шаги для преобразования .deb
файла:
-
Извлечение компонентов пакета:
С помощью командыar
вы можете извлечь содержимое вашего.deb
файла. В терминале выполните:ar -x mypackage-8.0.0_20221030-1_amd64.deb
Эта команда создаст три файла:
debian-binary
,control.tar.zst
, иdata.tar.zst
. -
Декомпрессия файлов:
Необходимо декомпрессировать файлыcontrol.tar.zst
иdata.tar.zst
для последующей обработки. Убедитесь, чтоzstd
установлен в вашей системе (для Debian используйтеapt-get install zstd
):zstd -d control.tar.zst zstd -d data.tar.zst
-
Пересжатие файлов:
После успешной декомпрессии, сожмите файлы в форматеxz
, который поддерживаетсяdpkg
в Debian:xz control.tar xz data.tar
-
Воссоздание пакета:
Удалите старый.deb
файл, а затем воссоздайте его с использованием командыar
:rm mypackage-8.0.0_20221030-1_amd64.deb ar -rc mypackage-8.0.0_20221030-1_amd64.deb debian-binary control.tar.xz data.tar.xz
Установка преобразованного пакета:
Теперь вы можете установить новый .deb
файл в вашем Docker-контейнере, выполнив следующую команду:
dpkg -i mypackage-8.0.0_20221030-1_amd64.deb
Устранение проблем с зависимостями:
Поскольку вы собрали пакет на Ubuntu 22.04, он может иметь зависимости, которых нет в вашей Debian 11. Для лучшего результата рекомендуется:
- Использовать образ
ubuntu:22.04
в качестве базового. Это устранит проблемы с зависимостями и обеспечит совместимость. - Если вы все же хотите работать в среде Debian, рассмотрите возможность установки всех необходимых зависимостей перед установкой пакета.
Пример скрипта для автоматизации:
Вы можете создать Bash-скрипт для автоматизации вышеуказанных шагов. Вот пример:
#!/bin/bash
set -e
PACKAGE_NAME="mypackage-8.0.0_20221030-1_amd64.deb"
# Извлечение компонентов
ar -x $PACKAGE_NAME
# Декомпрессия файлов
zstd -d control.tar.zst
zstd -d data.tar.zst
# Пересжатие файлов в формат xz
xz control.tar
xz data.tar
# Воссоздание пакета
rm $PACKAGE_NAME
ar -rc $PACKAGE_NAME debian-binary control.tar.xz data.tar.xz
# Установка пакета
dpkg -i $PACKAGE_NAME
Заключение
Следуя этим шагам, вы сможете преобразовать и установить ваш .deb
файл в Docker-контейнере на основе Debian. Однако, для достижения наилучших результатов, всегда предпочтительно собирать пакеты в том окружении, где они будут использоваться.