{"id":691,"date":"2026-09-06T14:47:34","date_gmt":"2026-09-06T17:47:34","guid":{"rendered":"https:\/\/www.linuxpro.com.br\/2026\/09\/criando-pacotes-deb\/"},"modified":"2026-09-08T08:29:11","modified_gmt":"2026-09-08T11:29:11","slug":"criando-pacotes-deb","status":"publish","type":"post","link":"https:\/\/www.linuxpro.com.br\/es\/2026\/09\/criando-pacotes-deb\/","title":{"rendered":"Criando pacotes .deb para Debian e derivados"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" alt=\"Mascote do LinuxPro fechando com fita uma caixa marcada com a espiral do Debian na esteira de empacotamento\" src=\"\/wp-content\/uploads\/2026\/09\/pacotes-deb-v2.webp\" width=\"1052\" height=\"652\" \/><\/p>\n<p>Distribuir software para Debian, Ubuntu, Mint e derivados sem um <code>.deb<\/code> \u00e9 entregar trabalho pela metade: sem gest\u00e3o de depend\u00eancias, sem atualiza\u00e7\u00e3o limpa, sem remo\u00e7\u00e3o sem rastro. A boa not\u00edcia: criar um pacote .deb decente \u00e9 mais simples do que a fama sugere. Neste guia completo voc\u00ea vai do pacote artesanal com <code>dpkg-deb<\/code> ao pacote profissional com <code>debhelper<\/code>, passando por scripts de manuten\u00e7\u00e3o, lintian e reposit\u00f3rio APT pr\u00f3prio.<\/p>\n<h2>Anatomia de um .deb<\/h2>\n<p>Um <code>.deb<\/code> \u00e9 s\u00f3 um arquivo <code>ar<\/code> com tr\u00eas membros: <code>debian-binary<\/code> (vers\u00e3o do formato), <code>control.tar.zst<\/code> (metadados e scripts) e <code>data.tar.zst<\/code> (os arquivos que ser\u00e3o instalados, com seus caminhos finais). D\u00e1 para inspecionar qualquer pacote do sistema:<\/p>\n<pre><code class=\"language-bash\">ar t \/var\/cache\/apt\/archives\/htop_*.deb   # lista os 3 membros\ndpkg-deb --info htop_*.deb                # metadados (control)\ndpkg-deb --contents htop_*.deb            # arquivos e destinos<\/code><\/pre>\n<h2>M\u00e9todo 1: pacote r\u00e1pido com dpkg-deb<\/h2>\n<p>Perfeito para distribuir um bin\u00e1rio pr\u00f3prio (um programa em Go, um script) dentro da empresa. Vamos empacotar um utilit\u00e1rio fict\u00edcio <code>meuapp<\/code>:<\/p>\n<pre><code class=\"language-bash\">mkdir -p meuapp_1.0.0-1_amd64\/{DEBIAN,usr\/bin,usr\/share\/man\/man1,etc\/meuapp}\ncp meuapp meuapp_1.0.0-1_amd64\/usr\/bin\/\ngzip -9 -c meuapp.1 > meuapp_1.0.0-1_amd64\/usr\/share\/man\/man1\/meuapp.1.gz\ncp meuapp.conf meuapp_1.0.0-1_amd64\/etc\/meuapp\/<\/code><\/pre>\n<p>O cora\u00e7\u00e3o do pacote \u00e9 o <code>DEBIAN\/control<\/code>:<\/p>\n<pre><code class=\"language-bash\">cat > meuapp_1.0.0-1_amd64\/DEBIAN\/control << 'EOF'\nPackage: meuapp\nVersion: 1.0.0-1\nSection: utils\nPriority: optional\nArchitecture: amd64\nDepends: libc6 (>= 2.34), ca-certificates\nMaintainer: Nilton Oliveira <nilton@example.com>\nHomepage: https:\/\/www.linuxpro.com.br\nDescription: Utilit\u00e1rio de exemplo do LinuxPro\n Linha longa da descri\u00e7\u00e3o: cada linha do corpo\n come\u00e7a com um espa\u00e7o. Uma linha s\u00f3 com \" .\" separa par\u00e1grafos.\nEOF<\/code><\/pre>\n<p>Arquivos em <code>\/etc<\/code> merecem tratamento de configura\u00e7\u00e3o \u2014 declarados em <code>conffiles<\/code>, o dpkg preserva as edi\u00e7\u00f5es do admin nos upgrades:<\/p>\n<pre><code class=\"language-bash\">echo \"\/etc\/meuapp\/meuapp.conf\" > meuapp_1.0.0-1_amd64\/DEBIAN\/conffiles<\/code><\/pre>\n<p>Precisa criar usu\u00e1rio de sistema ou habilitar um servi\u00e7o? Entram os scripts de manuten\u00e7\u00e3o (<code>preinst<\/code>, <code>postinst<\/code>, <code>prerm<\/code>, <code>postrm<\/code>), todos execut\u00e1veis:<\/p>\n<pre><code class=\"language-bash\">cat > meuapp_1.0.0-1_amd64\/DEBIAN\/postinst << 'EOF'\n#!\/bin\/sh\nset -e\nif [ \"$1\" = \"configure\" ]; then\n    getent passwd meuapp >\/dev\/null || useradd --system --no-create-home --shell \/usr\/sbin\/nologin meuapp\nfi\nEOF\nchmod 755 meuapp_1.0.0-1_amd64\/DEBIAN\/postinst<\/code><\/pre>\n<p>Gere o pacote (o <code>--root-owner-group<\/code> dispensa fakeroot) e teste:<\/p>\n<pre><code class=\"language-bash\">dpkg-deb --build --root-owner-group meuapp_1.0.0-1_amd64\nsudo apt install .\/meuapp_1.0.0-1_amd64.deb   # apt resolve as depend\u00eancias\ndpkg -L meuapp                                # confere o que foi instalado\nsudo apt remove meuapp<\/code><\/pre>\n<h2>M\u00e9todo 2: pacote profissional com debhelper<\/h2>\n<p>Para publicar de verdade \u2014 com changelog, compila\u00e7\u00e3o a partir do c\u00f3digo-fonte e conformidade com a pol\u00edtica Debian \u2014 o caminho \u00e9 o <code>debhelper<\/code>. Instale a bancada:<\/p>\n<pre><code class=\"language-bash\">sudo apt install build-essential devscripts debhelper dh-make lintian<\/code><\/pre>\n<p>Na raiz do seu c\u00f3digo-fonte (ex.: <code>meuapp-1.0.0\/<\/code>):<\/p>\n<pre><code class=\"language-bash\">cd meuapp-1.0.0\ndh_make --single --native --packagename meuapp_1.0.0 --email nilton@example.com\nrm debian\/*.ex debian\/*.EX   # limpa os exemplos<\/code><\/pre>\n<p>O diret\u00f3rio <code>debian\/<\/code> gerado tem quatro arquivos essenciais:<\/p>\n<ul>\n<li><code>debian\/control<\/code> \u2014 metadados do fonte e dos bin\u00e1rios (<code>Build-Depends<\/code> aqui!)<\/li>\n<li><code>debian\/changelog<\/code> \u2014 vers\u00e3o vem daqui; edite com <code>dch -i<\/code><\/li>\n<li><code>debian\/rules<\/code> \u2014 makefile do build; com debhelper moderno s\u00e3o 4 linhas<\/li>\n<li><code>debian\/copyright<\/code> \u2014 licen\u00e7a no formato DEP-5<\/li>\n<\/ul>\n<p>Um <code>debian\/rules<\/code> t\u00edpico hoje \u00e9 s\u00f3 isto (o <code>dh<\/code> descobre o resto \u2014 Makefile, CMake, Go, Python\u2026):<\/p>\n<pre><code class=\"language-bash\">#!\/usr\/bin\/make -f\n%:\n\tdh $@<\/code><\/pre>\n<p>Se o upstream n\u00e3o tem sistema de build, o <code>debian\/install<\/code> mapeia arquivos para destinos:<\/p>\n<pre><code class=\"language-bash\">echo \"meuapp usr\/bin\" > debian\/install\necho \"meuapp.conf etc\/meuapp\" >> debian\/install<\/code><\/pre>\n<p>Tem unit do systemd? Nomeie como <code>debian\/meuapp.service<\/code> e o <code>dh_installsystemd<\/code> instala, habilita e d\u00e1 restart no upgrade sozinho. Construa e valide:<\/p>\n<pre><code class=\"language-bash\">dpkg-buildpackage -us -uc -b   # sem assinatura, s\u00f3 bin\u00e1rio\nlintian ..\/meuapp_1.0.0_amd64.changes   # o \"linter\" oficial da pol\u00edtica Debian<\/code><\/pre>\n<p>Trate os avisos do <code>lintian<\/code> como um code review: cada tag tem explica\u00e7\u00e3o com <code>lintian-explain-tags &lt;tag&gt;<\/code>.<\/p>\n<h2>Depend\u00eancias autom\u00e1ticas<\/h2>\n<p>Nunca chute vers\u00f5es de bibliotecas. No <code>debian\/control<\/code> do bin\u00e1rio, use as vari\u00e1veis m\u00e1gicas \u2014 o <code>dpkg-shlibdeps<\/code> calcula as depend\u00eancias reais analisando os ELF:<\/p>\n<pre><code class=\"language-bash\">Depends: ${shlibs:Depends}, ${misc:Depends}<\/code><\/pre>\n<p>Bin\u00e1rios Go\/Rust est\u00e1ticos praticamente n\u00e3o t\u00eam <code>Depends<\/code> \u2014 uma das raz\u00f5es de eu empacotar minhas ferramentas em Go.<\/p>\n<h2>Vers\u00f5es e upgrades<\/h2>\n<p>O formato \u00e9 <code>[epoch:]vers\u00e3o-upstream[-revis\u00e3o-debian]<\/code> \u2014 ex.: <code>1.0.0-2<\/code> \u00e9 a segunda revis\u00e3o do empacotamento da mesma vers\u00e3o 1.0.0. O dpkg compara com <code>dpkg --compare-versions<\/code>; teste na d\u00favida:<\/p>\n<pre><code class=\"language-bash\">dpkg --compare-versions 1.0.0-2 lt 1.0.1-1 && echo \"upgrade ok\"<\/code><\/pre>\n<h2>Reposit\u00f3rio APT pr\u00f3prio<\/h2>\n<p>Distribuir .deb avulso por download \u00e9 metade do caminho \u2014 o resto \u00e9 um reposit\u00f3rio para <code>apt upgrade<\/code> funcionar. O jeito moderno e simples com <code>reprepro<\/code>:<\/p>\n<pre><code class=\"language-bash\">sudo apt install reprepro\nmkdir -p \/srv\/repo\/conf\ncat > \/srv\/repo\/conf\/distributions << 'EOF'\nCodename: stable\nSuite: stable\nComponents: main\nArchitectures: amd64 arm64\nSignWith: SEU_KEY_ID_GPG\nEOF\nreprepro -b \/srv\/repo includedeb stable meuapp_1.0.0-1_amd64.deb<\/code><\/pre>\n<p>Sirva <code>\/srv\/repo<\/code> com nginx e, no cliente:<\/p>\n<pre><code class=\"language-bash\">curl -fsSL https:\/\/repo.example.com\/chave.gpg | sudo tee \/usr\/share\/keyrings\/meurepo.gpg > \/dev\/null\necho \"deb [signed-by=\/usr\/share\/keyrings\/meurepo.gpg] https:\/\/repo.example.com stable main\" | \n  sudo tee \/etc\/apt\/sources.list.d\/meurepo.list\nsudo apt update && sudo apt install meuapp<\/code><\/pre>\n<h2>Atalho: fpm<\/h2>\n<p>Para uso interno, o <a href=\"https:\/\/fpm.readthedocs.io\/\" rel=\"noopener\" target=\"_blank\">fpm<\/a> gera .deb (e .rpm) de um diret\u00f3rio em um comando \u2014 sem pol\u00edtica Debian, mas resolve r\u00e1pido:<\/p>\n<pre><code class=\"language-bash\">gem install fpm\nfpm -s dir -t deb -n meuapp -v 1.0.0 --description \"Meu utilit\u00e1rio\" \n  --depends ca-certificates meuapp=\/usr\/bin\/meuapp<\/code><\/pre>\n<h2>Resumo pr\u00e1tico<\/h2>\n<ul>\n<li><strong>Ferramenta interna?<\/strong> <code>dpkg-deb --build<\/code> ou <code>fpm<\/code> \u2014 10 minutos<\/li>\n<li><strong>Software publicado?<\/strong> <code>debhelper<\/code> + <code>lintian<\/code> limpo + reposit\u00f3rio assinado com <code>reprepro<\/code><\/li>\n<li>Config em <code>\/etc<\/code> sempre em <code>conffiles<\/code>; usu\u00e1rio de sistema no <code>postinst<\/code>; unit do systemd via <code>dh_installsystemd<\/code><\/li>\n<\/ul>\n<p>No pr\u00f3ximo post desta dupla: o mesmo caminho para a <a href=\"\/2026\/09\/criando-pacotes-rpm\/\">fam\u00edlia Red Hat com pacotes .rpm<\/a> \u2014 spec file, rpmbuild, mock e createrepo.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Distribuir software para Debian, Ubuntu, Mint e derivados sem um .deb \u00e9 entregar trabalho pela metade: sem gest\u00e3o de depend\u00eancias, sem atualiza\u00e7\u00e3o limpa, sem remo\u00e7\u00e3o sem rastro. A boa not\u00edcia: criar um pacote .deb decente \u00e9 mais simples do que a fama sugere. Neste guia completo voc\u00ea vai do pacote artesanal com dpkg-deb ao pacote &#8230; <a title=\"Criando pacotes .deb para Debian e derivados\" class=\"read-more\" href=\"https:\/\/www.linuxpro.com.br\/es\/2026\/09\/criando-pacotes-deb\/\" aria-label=\"Read more about Criando pacotes .deb para Debian e derivados\">Read more<\/a><\/p>","protected":false},"author":0,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11,33,2,3],"tags":[335,15,198,337,336,5],"class_list":["post-691","post","type-post","status-publish","format-standard","hentry","category-debian","category-howtos","category-linux","category-ubuntu","tag-deb","tag-debian","tag-dpkg","tag-empacotamento","tag-pacotes","tag-ubuntu"],"_links":{"self":[{"href":"https:\/\/www.linuxpro.com.br\/es\/wp-json\/wp\/v2\/posts\/691","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.linuxpro.com.br\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.linuxpro.com.br\/es\/wp-json\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/www.linuxpro.com.br\/es\/wp-json\/wp\/v2\/comments?post=691"}],"version-history":[{"count":3,"href":"https:\/\/www.linuxpro.com.br\/es\/wp-json\/wp\/v2\/posts\/691\/revisions"}],"predecessor-version":[{"id":1197,"href":"https:\/\/www.linuxpro.com.br\/es\/wp-json\/wp\/v2\/posts\/691\/revisions\/1197"}],"wp:attachment":[{"href":"https:\/\/www.linuxpro.com.br\/es\/wp-json\/wp\/v2\/media?parent=691"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.linuxpro.com.br\/es\/wp-json\/wp\/v2\/categories?post=691"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.linuxpro.com.br\/es\/wp-json\/wp\/v2\/tags?post=691"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}