
Distribuir software para Debian, Ubuntu, Mint y derivados sin un .deb es entregar trabajo a medias: sin gestión de dependencias, sin actualización limpia, sin eliminación sin rastro. La buena noticia: crear un paquete .deb decente es más sencillo de lo que sugiere su fama. En esta guía completa irás desde el paquete artesanal con dpkg-deb hasta el paquete profesional con debhelper, pasando por scripts de mantenimiento, lintian y repositorio APT propio.
Anatomía de un .deb
Un .deb es solo un archivo ar con tres miembros: debian-binary (versión del formato), control.tar.zst (metadatos y scripts) y data.tar.zst (los archivos que se instalarán, con sus rutas finales). Se puede inspeccionar cualquier paquete del sistema:
ar t /var/cache/apt/archives/htop_*.deb # lista os 3 membros
dpkg-deb --info htop_*.deb # metadados (control)
dpkg-deb --contents htop_*.deb # arquivos e destinos
Método 1: paquete rápido con dpkg-deb
Perfecto para distribuir un binario propio (un programa en Go, un script) dentro de la empresa. Vamos a empaquetar una utilidad ficticia meuapp:
mkdir -p meuapp_1.0.0-1_amd64/{DEBIAN,usr/bin,usr/share/man/man1,etc/meuapp}
cp meuapp meuapp_1.0.0-1_amd64/usr/bin/
gzip -9 -c meuapp.1 > meuapp_1.0.0-1_amd64/usr/share/man/man1/meuapp.1.gz
cp meuapp.conf meuapp_1.0.0-1_amd64/etc/meuapp/
El corazón del paquete es el DEBIAN/control:
cat > meuapp_1.0.0-1_amd64/DEBIAN/control << 'EOF'
Package: meuapp
Version: 1.0.0-1
Section: utils
Priority: optional
Architecture: amd64
Depends: libc6 (>= 2.34), ca-certificates
Maintainer: Nilton Oliveira
Homepage: https://www.linuxpro.com.br
Description: Utilitário de exemplo do LinuxPro
Linha longa da descrição: cada linha do corpo
começa com um espaço. Uma linha só com " ." separa parágrafos.
EOF
Archivos en /etc merecen tratamiento de configuración — declarados en conffiles, el dpkg preserva las ediciones del admin en las actualizaciones:
echo "/etc/meuapp/meuapp.conf" > meuapp_1.0.0-1_amd64/DEBIAN/conffiles
¿Necesita crear un usuario de sistema o habilitar un servicio? Entran los scripts de mantenimiento (preinst, postinst, prerm, postrm), todos ejecutables:
cat > meuapp_1.0.0-1_amd64/DEBIAN/postinst << 'EOF'
#!/bin/sh
set -e
if [ "$1" = "configure" ]; then
getent passwd meuapp >/dev/null || useradd --system --no-create-home --shell /usr/sbin/nologin meuapp
fi
EOF
chmod 755 meuapp_1.0.0-1_amd64/DEBIAN/postinst
Genere el paquete (el --root-owner-group no necesita fakeroot) y pruébelo:
dpkg-deb --build --root-owner-group meuapp_1.0.0-1_amd64
sudo apt install ./meuapp_1.0.0-1_amd64.deb # apt resolve as dependências
dpkg -L meuapp # confere o que foi instalado
sudo apt remove meuapp
Método 2: paquete profesional con debhelper
Para publicar de verdad — con changelog, compilación a partir del código fuente y conformidad con la política Debian — el camino es el debhelper. Instale el banco de trabajo:
sudo apt install build-essential devscripts debhelper dh-make lintian
En la raíz de su código fuente (ej.: meuapp-1.0.0/):
cd meuapp-1.0.0
dh_make --single --native --packagename meuapp_1.0.0 --email nilton@example.com
rm debian/*.ex debian/*.EX # limpa os exemplos
El directorio debian/ generado tiene cuatro archivos esenciales:
debian/control— metadatos del fuente y de los binarios (Build-Dependsaqui!)debian/changelog— la versión viene de ahí; edite condch -idebian/rules— makefile de compilación; con debhelper moderno son 4 líneasdebian/copyright— licencia en formato DEP-5
Un debian/rules típico hoy es solo esto (el dh descubre el resto — Makefile, CMake, Go, Python…):
#!/usr/bin/make -f
%:
dh $@
Si el upstream no tiene sistema de compilación, el debian/install mapea archivos a destinos:
echo "meuapp usr/bin" > debian/install
echo "meuapp.conf etc/meuapp" >> debian/install
¿Tiene unit de systemd? Nómbrelo como debian/meuapp.service y el dh_installsystemd lo instala, habilita y reinicia automáticamente en la actualización. Construya y valide:
dpkg-buildpackage -us -uc -b # sem assinatura, só binário
lintian ../meuapp_1.0.0_amd64.changes # o "linter" oficial da política Debian
Trate las advertencias del lintian como una revisión de código: cada etiqueta tiene explicación con lintian-explain-tags <tag>.
Dependencias automáticas
Nunca adivine versiones de bibliotecas. En el debian/control del binario, use las variables mágicas — el dpkg-shlibdeps calcula las dependencias reales analizando los ELF:
Depends: ${shlibs:Depends}, ${misc:Depends}
Los binarios estáticos de Go/Rust prácticamente no tienen Depends — una de las razones por las que empaqueto mis herramientas en Go.
Versiones y actualizaciones
El formato es [epoch:]versão-upstream[-revisão-debian] — p. ej.: 1.0.0-2 es la segunda revisión del empaquetado de la misma versión 1.0.0. El dpkg compara con dpkg --compare-versions; prueba si tienes dudas:
dpkg --compare-versions 1.0.0-2 lt 1.0.1-1 && echo "upgrade ok"
Repositorio APT propio
Distribuir un .deb suelto mediante descarga es la mitad del camino: lo demás es un repositorio para apt upgrade funcionar. La forma moderna y sencilla con reprepro:
sudo apt install reprepro
mkdir -p /srv/repo/conf
cat > /srv/repo/conf/distributions << 'EOF'
Codename: stable
Suite: stable
Components: main
Architectures: amd64 arm64
SignWith: SEU_KEY_ID_GPG
EOF
reprepro -b /srv/repo includedeb stable meuapp_1.0.0-1_amd64.deb
Sirve /srv/repo con nginx y, en el cliente:
curl -fsSL https://repo.example.com/chave.gpg | sudo tee /usr/share/keyrings/meurepo.gpg > /dev/null
echo "deb [signed-by=/usr/share/keyrings/meurepo.gpg] https://repo.example.com stable main" |
sudo tee /etc/apt/sources.list.d/meurepo.list
sudo apt update && sudo apt install meuapp
Atajo: fpm
Para uso interno, el fpm genera .deb (y .rpm) desde un directorio con un solo comando — sin política Debian, pero lo soluciona rápido:
gem install fpm
fpm -s dir -t deb -n meuapp -v 1.0.0 --description "Meu utilitário"
--depends ca-certificates meuapp=/usr/bin/meuapp
Resumen práctico
- ¿Herramienta interna?
dpkg-deb --buildofpm— 10 minutos - ¿Software publicado?
debhelper+lintianlimpio + repositorio firmado conreprepro - Config en
/etcsiempre enconffiles; usuario de sistema enpostinst; unidad de systemd mediantedh_installsystemd
En el próximo post de esta pareja: el mismo camino para la familia Red Hat con paquetes .rpm — spec file, rpmbuild, mock y createrepo.