I love containers, it's really cool technology to preserve and distribute environments. To manage
containers I prefer
podman and its friends
podman 4 introduced many cool
features but it's unavailable in Ubuntu 22.04 which is my primary OS, the latest version there is
3.4.4. Thus, I decided to backport
podman from Debian Testing where it's already packaged by
mighty Debian maintainers.
As you might know Canonical drives Launchpad. This is a large portal that combines plenty of tools
around Ubuntu. One of these tools is PPA or Personal Package Archive. It allows you to build and
distribute your custom
deb packages. I used many PPAs in the past but never created my own.
Moreover, I've never tried to build a
deb package. There was a lot of fun ahead :)
deb packages Launchpad accepts so-called source packages as input. Fortunately, I didn't
have to make them from the scratch thanks to the great job of Debian maintainers. Thus, the
backporting process looked as follows:
- Get sources from Debian testing.
- Update the changelog.
- Rebuild the source package in Ubuntu 22.04.
- Upload the resulting artifacts to my PPA.
First of all, it was hard to get the right documentation about package building in Debian. Don't get
me wrong, there is documentation but it's all over the place, it's duplicated and out of date
sometimes. Here are some links I found on
After reading I got the understanding of what tools I should use and what commands need to be run.
All package manipulations I did in the containers. I ran both
docker.io/library/debian:bookworm with one shared volume:
podman run -it --rm -v $(pwd):/mnt docker.io/library/debian:bookworm bash podman run -it --rm -v $(pwd):/mnt docker.io/library/ubuntu:22.04 bash
To build packages you need to install two packages:
build-essential. In the
devscripts will be enough. Don't forget to add source repositories into
/etc/apt/sources.list and update packages index:
echo "deb-src http://debian.org/debian testing main" >> /etc/apt/sources.list apt-get update apt-get install -y devscripts
To get the sources you should run only one command in the Debian container:
apt-get source podman
There will be downloaded three files:
- libpod_4.3.1+ds1-5.dsc - package metadata
- libpod_4.3.1+ds1-5.debian.tar.xz - an archive with building recipes, patches, package changelog and other stuff
- libpod_4.3.1+ds1.orig.tar.xz - source code
dpkg-source script from
devscripts extracts archives applies patches and you will get a source
code directory with the
debian directory within. Basically, that's the only action we should do in
the Debian container. The following operations I made in the Ubuntu container.
Before uploading sources to Launchpad a new entry in the
changelog file should be added. It can be
done with any text editor but there is a dedicated utility
dch that adds a time stamp and bumps
version. You just need to write what has been changed. I didn't change anything so I put only this
upload to ppa:quarckster/containers
Here starts the fun. Launchpad accepts only source packages and to produce such you should run
dpkg-buildpackage -us -uc -sa -S
The command will fail due to missing build dependencies. I decided to ignore them and added
-d flag. After that I got four new files:
Uploading to Launchpad
Debian and Ubuntu provide utility named
dput to upload source packages. All you need to do is just
to specify a path to
.changes files and the PPA name:
dput ppa:quarckster/containers libpod_4.3.1+ds1-5.1ubuntu1ppa1_source.changes
After that, all required files will be uploaded. But before you must sign
.changes with your gpg
debsign -k "<key id>" libpod_4.3.1+ds1-5.1ubuntu1ppa1_source.changes
Actually, it can be done during the building but I didn't want to configure gpg in the container.
Do you remember I ignored build dependencies when I built the source package? Of course, my build failed and I had to repack and upload the whole dependencies graph. Maybe there is a smart way to do that but I didn't figure out anything better than waiting until a build fails, then check the logs, finding missing dependencies and doing a new packaging iteration. I had to upload 38 packages in total.
Now I have modern version of
podman on my operating system. Feel free to use it as well.
Even more fun
I felt a superpower and decided to backport a new networking backend for
podman. It consists of
aardvark-dns. I didn't realize how deep this rabbit hole.
missing only 38 packages because most other dependencies from this graph are available in Ubuntu
On the other hand,
aardvark-dns are completely new packages and all build
dependencies exist only in Debian Testing:
When I uploaded around one hundred packages to my PPA I encountered circular dependency and further backporting stuck.
Rust package manager
cargo has ability to download all dependencies and configure the compiler
to use this local cache for building. You just need two commands:
cargo vendor > .cargo/config.toml cargo generate-lockfile
New files should be included into
orig.tar.xz archive and after that the package was successfully
Packaging is fun :) I want to give credits to Debian maintainers because they do a great job. All I
need to do is just to change a couple of line in the
changelog file and run some commands. The
most interesting part is located in the
rules file which is a
Makefile. It contains the recipe
and all logic.
The only thing that really worried me was the
rulesfile. There is nothing in the world more helpless and irresponsible and depraved than a man in the depths of hacking
rulesfile. And I knew I'd get into that rotten stuff pretty soon. Probably next time.