How to create a Debian .deb package
CEO & Founder of Server Density.
Published on the 5th February, 2010.
A few weeks ago we announced that the agent for our server monitoring application, Server Density, was available as a Debian or Red Hat package, with associated repositories. Over my next few posts I will be outlining how we created our Linux-based packages and repositories, and what our steps are going to be to improve these processes in the future.
Structure of a Debian package
Debian packages must adhere to a strict directory structure. This includes a so-called control file and other scripts that look after what happens during installation of the package. Here’s a sample of our directory structure:
The control file, DEBIAN/control
The control file is the core of the Debian package; it contains all relevant metadata. Things such as package name, version, supported architectures, and dependancies are all included in this file. Here is what our current control file looks like:
Depends: python (>=2.3)
Maintainer: Ryan Duffield
Description: The Server Density monitoring agent.
The conffiles, DEBIAN/conffiles
Configuration files, or “conffiles”, are files that are included within a Debian package that may be changed by a user. When uninstalling the package, a user or system administrator dealing with the package may not want his or her configuration files removed. Running
sudo apt-get remove sd-agent will remove all installed package files except for those listed in the DEBIAN/conffiles file. Here is what ours looks like:
If a user truly wants to remove everything including the configuration files, this can be done by using the purge command instead of remove:
sudo apt-get purge sd-agent.
The md5sums file (DEBIAN/md5sums)
This file is a list of MD5 checksums for all files contained within the package that will actually be extracted to the system. This can be most easily generated using a combination of commands:
$ find . -type f ! -regex '.*.hg.*' ! -regex '.*?debian-binary.*' ! -regex '.*?DEBIAN.*' -printf '%P ' | xargs md5sum > DEBIAN/md5sums
The postinst and prerm scripts, DEBIAN/postinst and DEBIAN/prerm
Many packages need to perform actions before or after specific events during the package installation or uninstallation process. Debian packages accommodate for this via scripts. For instance, after installation, our agent package installs its init script automatically; it also needs to byte-compile our Python libraries. Below is the script that is run after installation, postinst:
python -m compileall /usr/bin/sd-agent/
update-rc.d -f sd-agent defaults
Similarly, the agent removes those byte-compiled Python libraries and init script from system startup after uninstallation. This is handled by prerm:
if [ "$1" = "remove" ]; then
update-rc.d -f sd-agent remove
The rest of it
The remainder of the directory structure must resemble the resultant structure after installation of the package. For example, because the agent is installed to /usr/bin/sd-agent, there is a usr/bin/sd-agent directory within our package root.
Creating the package
When all of the above is in place, creating the actual Debian package, or .deb file, is easy:
$ dpkg -b pkg-debian/ sd-agent_1.4.2_i386.deb
$ dpkg-deb: building package
Mistakes made along the way
This was our first attempt at creating a Debian package, so, naturally, some mistakes were made along the way!
Our initial control file was wrong; specifically, our Installed-Size value was calculated incorrectly. I had originally read that this value was supposed to be expressed in bytes. However, after releasing our first package, I noticed that apt-get displayed a message notifying me that the agent would take up over 100 MB of disk space. This was obviously incorrect. This field’s value needs to be expressed in kilobytes, as outlined here.
Another mistake made was accidentally including Mercurial’s various files (.hg folder, .hgignore, etc.) in the first package version. This was kindly pointed out by one of our customers, and promptly fixed. If one wants to see a list of files currently “owned” by a given package, one can do so by using dpkg with the -L switch. For instance, to see the files that the Server Density agent is responsible for, one can run:
dpkg -L sd-agent
Other Linux packages
As mentioned, we also created a Red Hat package for the agent, and Debian and Red Hat repositories. My next article will outline how we created the Red Hat RPM for the agent.