Building binary deb packages: a practical guide

(internalpointers.com)

104 points | by tblr 1423 days ago

9 comments

  • NCommander 1423 days ago
    Wow, this is horrible advice. I'm a Debian Developer and an Ubuntu Core Developer. What this will do is create a package that doesn't properly handle dependencies and be incredibly fragile.

    Debian and Ubuntu automatically resolve shared library dependencies are build time through dpkg-shlibs and friends. Debian's maintainer manual is likely the most detailed guide: https://www.debian.org/doc/manuals/maint-guide/start.en.html

    However, it's a bit hard to grok, so I'm going to point people at the guide that got linked in the comments before I got here: https://saveriomiroddi.github.io/Learn-to-prepare-PPA-packag...

    • onli 1423 days ago
      It's not horrible advice, and none of the links is helpful if you want to achieve the stated goal in the article: Simply distributing a binary.

      It's completely fine to package them in a deb. You especially should know that debs are really simple and work quite well for that. You place the binary along with the needed resource files (configuration for example) in the relative directory structure, add a minimal amount of meta information, and call one command to create the .deb. Easy and fast, and the result is very reliable, it will work everywhere.

      And then you have the official way of abstraction over abstraction, "explained" with completely unreadable documentation, needing a dozen helper tools and environment variables, guided by documentation that fails to explain even just the basics of what it is you'd actually do if you followed that documentation.

      No, the simple way shown by the submitted article is exactly correct.

      Start with that. If it works, then you maybe take the next step later and set up a PPA, assuming the deb is not only for yourself.

      • hordeallergy 1422 days ago
        The second half of your comment is exactly the experience I recently had when trying for the first time. I quit and built a container image instead.
      • growse 1422 days ago
        I think it's bad advice, but not necessarily for the same reason. For the simple case of "I want to distribute a binary", there are far easier ways to make a deb - I use FPM, but there are other tools that will also do it in a one-liner.

        For someone new to this, the article's 5-steps are certainly not "practical".

        • onli 1422 days ago
          Well, a binary often needs at least one configuration file, so it's probably not just that. I think it's easy enough: You just precreate the directory structure, place the files, add DEBIAN/control, and then it's one command. If it can be even easier that's really cool :)
    • closeparen 1423 days ago
      With respect, I think this is a harmful attitude to take. People end up writing huge masses of Puppet/Chef/Ansible, or resorting to heavyweight technologies like Docker, just to place some files on a server. This problem is solved quite well by dpkg since forever, and it's a disservice to the community that this fact is obscured by so much cruft that only distro maintainers really need to know.
      • dirtydroog 1423 days ago
        Seconded, I tried to package up a publicly available header-only tar.gz into a debian package for our private repo and found it impossible to do. I gave up.
        • GoblinSlayer 1422 days ago
          I just stole the process from another project that uses binary packaging.
    • mehrdadn 1423 days ago
      I've read more than one complaint about Debian's packaging process being a nightmare. I have no horse in the race, but since you're here, I wanted to mention this because it sounds like you're not aware of it (and could possibly help change things).
      • NCommander 1422 days ago
        No, I'm aware it is. Most of the problems is people trying to use it to distribute binary source code. Using it for source builds and debian/rules is a lot saner and straight forward.

        These types of debs cause problems with system upgrades and I groan whenever I see something that uses checkinstall or similar; there are add-on deb sites that basically do that, and you get a mess in the resulting system. A lot of this is why snap got made.

        I'll admit that the Debian package format could be better in this regard, but the packaging format is primarily for use by dpkg-buildpackage and building the distro.

        Disclaimer: this is my own views and not those of either the Debian or Ubuntu projects.

        • mehrdadn 1422 days ago
          Interesting... by "binary source code" do you mean "binary" (executables)? Do you mean you see distributing binaries as a not-intended use case for .debs, and that they should all result in builds straight from source? Or am I misunderstanding what you're saying? Because I feel like the people who use Debian or Ubuntu (or Arch or Fedora or...) aren't really longing for the experience of building everything from source like Gentoo users might.
    • spokspeakspoke 1423 days ago
      Been going through the Debian Maintainer process by reading through the Debian official docs. The internalpointers blog post is hand's down more lucid than anything I read on the wiki. I think the other comments here reflect that sentiment.
      • NCommander 1422 days ago
        The best equivalent I can give is this is roughly like opening up a MSI file, and replacing its guts. It works but you're asking for a really fragile system in return.

        What is the problem with distributing a tarball if you're sending binaries?

        If you're making debs, you still need to make a Debian repo and sign it, and then you still have the problem your dependencies are fucked up or won't easily work across versions.

        What are you trying to solve that a tarball or rsync can't?

        • defanor 1422 days ago
          Not OP, but also packaging binaries into .debs, and the primary reasons for that (as opposed to using tarballs or rsync) are centralized package management, including dependency checks, and scripts to execute on installation (e.g., add system users).
        • Mashimo 1422 days ago
          > What are you trying to solve that a tarball or rsync can't?

          End users can install a deb with one click without having to know about where to put the files, or how to create a shortcut in menu.

    • rubicks 1423 days ago
      Seconded. shlibs exist for a reason, not the least of which is automagic Depends resolution.
    • voltagex_ 1423 days ago
      How many of the problems here will be picked up by your package linter?
    • GoblinSlayer 1422 days ago
      If deb allowed installation of packages with unmet dependencies, then automatic dependencies could be workable.
  • infinity0 1423 days ago
    It should be noted that none of this article applies to actual development that goes on in the Debian distribution from https://www.debian.org

    Official Debian development, being FOSS oriented, proceeds from Debian source packages instead, and one never creates a binary package from scratch as described in the article. Instead, we use `dpkg-buildpackage` and other similar tools. The creation of the source package is the hard part, having to follow all the aspects of Debian policy, including technical matters around quality.

    • dijit 1423 days ago
      Is there a guide on doing things that way? I've read some of the guides for making .deb packages (as I had to do so recently) and I have to be honest, what I encountered was "messy", articles and documentation that would work if followed but they didn't look even slightly similar.

      I'm too embarrassed to even link to the sources that I created.

      • pabs3 1423 days ago
        The official entry point for getting packages into Debian is here:

        https://mentors.debian.net/intro-maintainers

        Debian packaging documentation is unfortunately a swamp, since people continue to write new guides instead of improving existing ones.

    • secabeen 1423 days ago
      Agreed. We use this technique to distribute commercial software to our workstations.
    • zwetan 1423 days ago
      what if you need to distribute a .deb containing binaries that target other operating system ?

      example: I got a tool that allow from any Windows/macOS/Linux to package a runtime+script to any Windows/macOS/Linux

      the Windows .exe can not be compiled from sources under Linux, so this particular runtime can never be distributed on Debian official?

      • pabs3 1423 days ago
        Debian contains cross-compilers for Windows (but not macOS yet), so you can compile a .exe and build that into a .deb easily.

        https://packages.debian.org/search?keywords=mingw

        Probably the right thing for you to do is switch to WinGet on Windows and the Apple Store for macOS.

  • raziel2p 1423 days ago
    I still go to FPM (https://github.com/jordansissel/fpm) for any distro-native packaging needs I have.
    • app4soft 1423 days ago
      For user apps on Linux I would prefer to use portable AppImage, instead of regular packages.
      • ghostpepper 1423 days ago
        I misread your post at first because, once upon a time, portable meant that software would work on Linux _and_ other platforms.
        • app4soft 1422 days ago
          > portable meant that software would work on Linux _and_ other platforms.

          "portable" and "crossplatform" ("multiplatform") are different degrees of software.

  • Athas 1423 days ago
    I think this guide glosses over the most difficult aspect: writing a package whose executables are generated reasonably reproducibly, using tools from other Debian packages. I've been a satisfied Debian user for over ten years, but I gave up on trying to package my own software. I could certainly figure out how to manually create a `.deb` with an executable and some man pages, but not how to automate the creation of that `.deb` in a way that lives up to my expectations of quality.

    In contrast, I managed to submit software to Homebrew after two weeks of macOS, and to Nixpkgs within two days of running NixOS.

    • infinity0 1423 days ago
      As I mentioned in the other comment, the creation of a Debian source package has a lot of barriers, some of them good and for quality purposes, some of them bad and due to historical cruft. Documentation is also not very newbie-friendly. The actual automatic reproduction of a binary from a source package is simple - `dpkg-buildpackage`.

      The tradeoff you get with other distributions being quick, is less quality assurance. Also, Debian still has a policy of working on 10 architectures, and this slows things down significantly sometimes. The other distributions you mentioned don't have this constraint.

      • Conan_Kudo 1423 days ago
        > The tradeoff you get with other distributions being quick, is less quality assurance

        The crux of the problem is that all current official Debian packaging methods supported by Debian are sufficiently arcane and obtusely documented to the point that it's a high barrier to entry for people to do it right.

        Personally, I've been doing RPM and Debian packaging for over a decade now, and it boggles the mind how much more complicated doing _correct_ Debian packaging is for essentially the same that happens on an RPM distribution like Fedora or openSUSE.

        One of the reasons that I started using debbuild[1] for building Debian packages years ago was that I felt like I could get something that closely resembled a policy-compliant Debian package without impossible amounts of guesswork. Combined with macros adapted from Fedora and other distros[2] as an interface for Debian packaging policies, I can package things rather easily for Debian/Ubuntu using the much more straightforward guidelines from Fedora as a base.

        As it turns out, it doesn't take that much effort to make packages that comply with Fedora/openSUSE Packaging Guidelines and Debian Policy with this tool, and it has drastically simplified my ability to maintain software across distributions in a way that still cleanly integrates with the distribution platform.

        I wish that debbuild would be an officially supported mechanism in Debian, but it's probably unlikely without a Debian Developer advocating for it (and I suspect no one there would, as they probably like the existing system...).

        [1]: https://github.com/debbuild/debbuild

        [2]: https://github.com/debbuild/debbuild-macros

        (Disclaimer: I am now the current developer of debbuild and debbuild-macros, though I wasn't when I first started using it)

      • pabs3 1423 days ago
        Got any examples of barriers? Debian packaging is trending towards entirely automatic, but we aren't quite there yet and there are a lot of things we could do to change that, mostly in dpkg-dev and debhelper.

        https://wiki.debian.org/AutomaticPackagingTools

      • debiandev 1422 days ago
        DD here. The main "barrier" is the level of quality required.

        Simply throwing a bunch of files into a package or a container is very quick.

        Making an official Debian package is not supposed to be quick. DDs thoroughly review and test the software they are packaging. While packaging I often chase missing licensing information, find plenty of bugs, write systemd unit/init files and sandboxing, write manpages, functional tests, and sometimes find serious vulnerabilities.

        I worked on various packaging and deploying systems, and most other distributions don't come anywhere close to this level of scrutiny.

        I should also add that becoming a DD requires years of commitment and proven track record of work.

        The next time someone complains that making a container is very easy in comparison they should ask themselves: how much can I trust a software source with a very low entry bar?

        • GoblinSlayer 1422 days ago
          Gatekeeping is the goal of debian packaging documentation? Right, that goal is certainly perfectly achieved.
          • debiandev 1422 days ago
            huh?
            • LadyCailin 1419 days ago
              I think the point they’re trying to make is that having a high barrier to entry should be accomplished through means other than having a hard or confusing barrier to entry.
      • mehrdadn 1423 days ago
        > The tradeoff you get with other distributions being quick, is less quality assurance.

        I dare say, if Ubuntu is any indication, Pacman packages consistently feel higher-quality than deb packages. Unlike on Ubuntu, on Arch, you can actually update your packages without breaking something...

    • readams 1423 days ago
      Sbuild for deb and mock for rpm make this pretty easy. Not super easy. But pretty easy.
      • snuxoll 1423 days ago
        This, nobody should be manually calling rpmbuild or dpkg-buildpackage themselves. Doing this makes it easy to miss dependencies or other funky things you have done to your environment.
    • pizza234 1423 days ago
      > but not how to automate the creation of that `.deb` in a way that lives up to my expectations of quality.

      Can you clarify what do you exactly mean with this?

      • Athas 1423 days ago
        Basically what infinity0 described in his sibling comments. I want to have a source package that can be used to build the binary package in a deterministic and reproducible way.
        • pizza234 1423 days ago
          This post describes how to do that, via PPAs: https://is.gd/Eu55IG.
          • Athas 1423 days ago
            Thanks. That may have been useful to me once, although my motivation was to get my software in the main Debian package set, which I think is quite a different thing from PPAs.

            Also... look at that guide. Why is it so difficult and obtuse? Why do I have to run so many odd tools, including apparently modifying some file in /etc and running other stuff as root? In contrast, this was my first contribution to Nixpkgs: https://github.com/NixOS/nixpkgs/commit/0b8efd8724e59964bad0... Easily as reproducible as anything Debian, and apart from installing Nix it didn't require any funkyness in the build environment. I tested the definition by running 'nix-build . -A oclgrind' in my checkout of the Nixpkgs repository. I managed this after running NixOS for two days.

            This is the same software that I also contributed to Homebrew: https://github.com/Homebrew/homebrew-core/commit/1268459f761... Again, a simple declarative-ish package description (written in Ruby, which is not my favourite, but it's better than the weird Makefile/shell amalgamations that are used by DPKG and RPM).

            Both Nix and Homebrew have serious limitations compared to Debian (Homebrew in particular is aggressively limiting its scope to gain simplicity and in particularly doesn't care as much about reproducibility). But as a user, I must admit I have not missed what Debian provides that these do not. Whenever I tried to package stuff for Debian, I felt that I was paying a tax for unclear gain. It's a shame, because I like Debian for over a decade, and I am strongly sympathetic to the idea of the project in principle.

            • sm_ts 1422 days ago
              > Also... look at that guide. Why is it so difficult and obtuse? Why do I have to run so many odd tools

              I agree that Debian packaging is difficult/odd/arguably obtuse; I guess it's a legacy matter. Your phrasing can be interpreted as if the guide itself is obtuse, it's not clear :)

              > including apparently modifying some file in /etc and running other stuff as root?

              It's important to read and understand it fully. Anything you do it as root is required only to run a preview build locally. This is an optional step, so no, one doesn't need to perform admin configurations/operations if they don't want to, although performing a local build is a desirable step.

              > In contrast, this was my first contribution to Nixpkgs

              This is not a proper comparison, as you're comparing an entirely manual procedure versus using a packaging tool.

              A proper (closer) comparison is probably against the tool that the guide references: https://github.com/saveriomiroddi/ppa_packaging, where you just declare all the metadata, and invoke a script that takes care of everything.

              All in all, I'm personally puzzled about why there aren't tools around to simplify/automate Debian packaging. I've started the small tool mentioned above (`ppa_packaging`), but I'll likely not continue working on it, as my experience with niche projects is that, while useful in their (narrow) domain, they're very resource-intensive to maintain.

            • slgeorge 1422 days ago
              Mostly because all of these systems came AFTER Debian.

              I mean Debian packaging is a terrible pain - but I have to have empathy with the fact that it's a technical system and more importantly an online community that's been doing it's thing since 1993.

              The fact is that with such a long-running system there's more than one way to do everything.

              The way we discuss/learn technology has also partly changed. Most of the documentation for Debian is extensive manuals - there's "not enough" intro text, and then "too much" detailed documentation

              And then there's the "cost of change". Lots of Debian developers have been packaging using their particular versions of tools for a long time and are happy with them.

              In many ways Debian works because the people working on it care about quality and the tooling is second order to the efforts they make.

  • mavu 1422 days ago
    This is better: https://github.com/phusion/debian-packaging-for-the-modern-d...

    (someone with the applicable knowledge please fork and continue it)

  • anttisalmela 1423 days ago
    • JdeBP 1422 days ago
      Ironically, that gets the service management wrong.

      The memcached people have provided a systemd service unit since 2011, for 8 years at the time that M. Bernat wrote that article. One quite clearly does not use the -d and -P options, nor Type=forking. memcached is Type=simple per its authors.

      Indeed, Type=forking in a systemd service unit is a good indicator that its author does not understand service management. It is invariably wrong because almost no programs actually speak the forking readiness protocol. (They fork for rather different reasons, which do not in fact adhere to the requirements of the forking readiness protocol.) See it, and you know to treat pronouncements about how daemonization works from that source with a great deal of suspicion.

      One such here is "memcached is started with the -d flag and will fork when it is ready to accept requests". In fact, memcached with -d forks before pretty much all of its initialization, and long before it is ready to accept requests. It hasn't even opened its listening sockets, or opened any data files or started any worker threads, at that point. Client services started because "memcached is ready" can fail to even connect to it. It might indeed yet fail whilst initializing, and never become ready.

      Really, memcached should have been runnable under inetd as a "wait" service from the start, which it unfortunately is not. That could have been adapted into a program that speaks the LISTEN_FDS protocol; and it would have a memcached.socket unit, with Accept=No and some ListenStream and ListenDatagram settings, and a Type=simple memcached.service unit. Then clients would have been able to reliably connect to the socket as soon as the service was started, and queue up until the service begins to accept() them when it becomes ready. Early socket opening in action.

      * https://github.com/memcached/memcached/blob/c460f0e13a35dcec...

      * http://jdebp.uk./FGA/unix-daemon-readiness-protocol-problems...

  • perlgeek 1422 days ago
    <plug>

    I've written a book about Debian packaging that spends most of its page count on building Debian packages with debhelper/dh, the approach that most (or all?) official packages use.

    Here's a link for the HN crowd to get it for free: https://leanpub.com/debian/c/pm

    Happy to answer any questions as good as I can :-)

    </plug>

  • j1elo 1423 days ago
    Debian packaging lacks a practical guide that is comprehensive enough to cover all modern use cases, but at the same time doesn't lack focus and goes to the point. The official docs are very extensive, but then they lack self-references to guide the reader to the interesting parts, or surprisingly lacks information that one would expect to find in there.

    You will read about debian/rules file, but then open one from any example project and only see a single rule calling "dh". Turns out debhelper is there doing things for you. On to read about debhelper. But now sometimes you'll see some rules file that uses the target "override_dh_autoreconf", which was not explained, not even hinted, in the previous docs. On to read more.

    Did you think you got everything? Not so fast!

    You'll document yourself about debian/control files and see that using some variable-like names are common in lots of projects. For example this is used a lot:

    Depends: ${misc:Depends}, ${shlibs:Depends}

    On with the same issue. For some reason (which new users reading the docs shouldn't really have to care), "shlibs:Depends" seems to be used all over the place, but it is not mentioned, hinted, or even suggested in a mere "see also" paragraph in the docs about debian/control. If you are thorough enough you'll end up seeing a quick mention in a different section (8. Shared Libraries), and turns out the actual definition of this variable has to be checked out from "dpkg-shlibdeps", an independent package.

    Now how to actually build a package?

    In the old days, the debian/rules file contained all the steps, but all is now helpfully abstracted by simply calling debhelper (dh). But calling debian/rules itself is abstracted also by dpkg-buildpackage. Calling dpkg-buildpackage is itself covered by debuild. And debuild is possibly covered by calling git-buildpackage. There is a crazy pile of tools calling tools calling other tools, that is nothing but extremely confusing for newcomers.

    For the 99% of times you just want a local package for local installation, dpkg-buildpackage is what you want. But getting to that conclusion is not something you get pointed to from a brief introduction from an official manual. You get to that conclusion after either studying all tools and putting order to all scattered knowledge in your head, or after blindly following some random blog of forum post (which tend to be correct because thankfully all this tooling doesn't change much over time)

    EDIT to stress that all information is there, but the official docs lack a good enough effort of linking or including everything in such a way that it follows a logical learning process for newcomers.

    • gorgoiler 1423 days ago
      Where do Debian maintainers collect their institutional knowledge, these days?

      In the past it felt like DSCs uploaded to the FTP queues were the equivalent of committing code on a software project. Are they all in one git repository now, that can be tracked outside the project?

      Nothing beats being able to read the code for learning how a system actually works.

      • debiandev 1422 days ago
        DD here.

        apt-get install maint-guide ...and then read:

        file:///usr/share/developers-reference/index.html file:///usr/share/doc/maint-guide/html/index.en.html

        Also look at existing packages and talk to DDs. Avoid random wikis.

        I worked on many deployment systems and reading these guides made me a better engineer overall.

        • gorgoiler 1422 days ago
          Thanks!

          The problem I saw from parent and other posts was that there’s two sets of information you need to build a package:

          (1) the sources and debian patches, where the last public release of these is available from packages.debian.org

          (2) knowing the right command to run to build the package.

          In the old days you could guarantee everything would build via dpkg-buildpackage though you’d need to know to add -r fakeroot.

          It sounded like nowadays it’s more complicated than that?

          • j1elo 1422 days ago
            The process itself seems to be very similar if not exactly the same.

            The problem is not that, but the way to get there, and how the information is structured and presented, especially if you start from having no idea, or if you want to build your debian/ files from a blank slate and being able to read in a centralized resource about definitions of every line you add (which I think should be possible to do, for any system in general).

      • pabs3 1423 days ago
        Some packages use git for maintaining the packaging, but the Debian archive and build servers are still based on Debian source packages (.dsc files).
      • pabs3 1423 days ago
        Debian maintainers collect their institutional knowledge from participating in package maintenance, following Debian mailing lists and other communication forums etc.
  • exabrial 1423 days ago
    We use the JDeb maven plugin to package up our one-jar. Those are uploaded using Maven Wagon to a Nexus repository that our Ubuntu servers look at. It's beautiful how frictionless our deploys are.