Debian-file Structure and Layout



Many developers may want to make a Debian file (*.deb) so their program/library can be distributed among Debian-based Linux distros. However, a few files are needed and must be manually created. In addition, a proper directory structure must be set. Before developers can create a Debian package, they must first understand what file must be created.


Debian files are compressed "*.ar" files that are renamed with the "*.deb" extension. Inside a Debian file (the "ar" file) are two compressed tar files. These two tars may be compressed with Bzip2, Gzip, xz (lzma2), or lzma. Each tar may be compressed with a format that is different from the other tar file. Once uncompressed entirely, the user will see a directory named "DEBIAN" (that must always be in all caps) and a few other directories. The other directories may remind users of the root (/) directory. Usually for applications, one of those directories will be "usr". This structure allows the Debian installer to know where the file(s) is to be placed. Inside the "usr" folder, users may see folder names that are the same as the directories inside /usr/.

For illustration, if a script named “script-parser” is to be placed in /usr/share/bin/, then the directory structure in the Debian file would be "*DEBIANFILE*/usr/share/bin/script-parser". In other words, any file not in the "DEBIAN" directory will be copied to the place on the system as specified by the directory structure that is in the Debian file. Below is an very basic example of how a package's directory structure should look inside the Debian file. “script-parser_3.7-1_all” is the name of the directory that will soon become a package named “script-parser_3.7-1_all.deb”.


The “DEBIAN” folder contains metadata needed by the Debian file and Debian installers. The files that may be included in here are control, watch, md5sums, compat, prerm, postrm, preinst, postinst, conffiles, copyright, changelog, and rules. However, not all of these files are required. Only the “control” file is mandatory. To make an official (standards compliant) Debian package, “compat” and “copyright” are needed. Each of the mentioned files have a specific structure and use.

If one of the files in the “DEBIAN” folder were to be changed and then repackaged, then the new package would be “script-parser_3.7-2_all.deb”. The “-2” indicates the package's version. The “3.7” refers to the software's version.


"preinst" Script

The "Pre-install" script is executed before the package installs. Below is a preinst script from a Python2 interpreter package.
#! /bin/sh
set -e
# remove the python alternatives before installing our own python link
update-alternatives --auto /usr/bin/python >/dev/null 2>&1 || true
update-alternatives --remove python /usr/bin/python1.5 || true
update-alternatives --remove python /usr/bin/python2.1 || true
update-alternatives --remove python /usr/bin/python2.2 || true
[ -L /usr/share/doc/python/html ] || rm -rf /usr/share/doc/python/html
case "$1" in
  if dpkg --compare-versions $2 lt 2.6.1-1~; then
    oldv=$(echo $2 | sed 's/^\(...\).*/\1/')
    if [ "$DEBIAN_FRONTEND" != noninteractive ]; then
     echo "running python pre-rtupdate hooks for python2.7..."
    for hook in /usr/share/python/runtime.d/*.rtupdate; do
     [ -x $hook ] || continue
     if ! $hook pre-rtupdate python$oldv python2.7; then
      hb=$(basename $hook .rtupdate)
      echo >&2 "error running python pre-rtupdate hook $hb"
      echo >&2 "running python failed-pre-rtupdate hook $hb"
      $hook failed-pre-rtupdate python$oldv python2.7
    [ -z "$errors" ] || exit 3
   # 2.4.4-5 is the first version, which adds python2.5 as supported
   # version; need to run an rtinstall python2.5 in the postinst.
  if dpkg --compare-versions $2 lt 2.4.4-5 && [ -x /usr/bin/python2.5 ]; then
    version=$(dpkg -s python2.5-minimal | awk '/^Version:/ {print $2}')
    mkdir -p /var/lib/python
    echo "$version" > /var/lib/python/python2.5_already_installed
   # 2.5.4-6 is the first version, which adds python2.6 as supported
   # version; need to run an rtinstall python2.6 in the postinst.
  if dpkg --compare-versions $2 lt 2.5.4-6 && [ -x /usr/bin/python2.6 ]; then
    version=$(dpkg -s python2.6-minimal | awk '/^Version:/ {print $2}')
    mkdir -p /var/lib/python
    echo "$version" > /var/lib/python/python2.6_already_installed
   # 2.6.6-13 is now the first version, which adds python2.7 as supported
   # version; need to run an rtinstall python2.7 in the postinst.
  if dpkg --compare-versions $2 lt 2.6.6-13 && [ -x /usr/bin/python2.7 ]; then
    version=$(dpkg -s python2.7-minimal | awk '/^Version:/ {print $2}')
    mkdir -p /var/lib/python
    echo "$version" > /var/lib/python/python2.7_already_installed

"postinst" Script

The "Post-install" script runs after the installation. The postinst script is just a shell script like the preinst, prerm, and postrm scripts.

"prerm" Script

The "pre-remove" script (prerm) is executed before the package is removed/uninstalled. This script is a regular shell script. Below is an example prerm script from a Python2 interpreter package.
#! /bin/sh
set -e
case "$1" in
   rm -f /usr/share/python/[co]

"postrm" Script

The "Post Remove" script is a shell script that is run after the package has been uninstalled/removed. Below is a postrm script from a Python2 interpreter package.
#! /bin/sh
set -e
case "$1" in
   rm -rf /etc/python

"changelog" File

The “changelog” file lists the various changes between versions, updates, and patches. Below is an real changelog with most of the file's contents removed for simplification.
python-pip (1.1-3) unstable; urgency=low

  * debian/patches
  - add test_urlparse_uses_fragment.patch (Closes: #677801)

-- Carl Chenet <[email protected]>  Sat, 23 Jun 2012 16:18:21 +0200

python-pip (1.1-2) unstable; urgency=low

  * debian/control
  - Use X-Python-Version >= 2.6 (Closes: #676041)
  - Put python-all (>= 2.6) in B-D and Depends field
  - Put python-all-dev (>= 2.6) in python-pip pkg Depends field
  * Add pip-2.6 manpage
  * debian/python-pip.install
  - add support for multiple 2.x libraries

-- Carl Chenet <[email protected]>  Tue, 15 Dec 2009 02:07:56 +0100

python-pip (0.3.1-1.1) unstable; urgency=low

  * Non-maintainer upload.
  * Add Jakub Wilk's patch to fix FTBFS with Python 2.6 (Closes: #556852)

-- Kumar Appaiah <[email protected]>  Tue, 08 Dec 2009 18:41:05 -0600

python-pip (0.3.1-1) unstable; urgency=low

  * Initial release.  Closes: #522135.

-- Jeff Licquia <[email protected]>  Tue, 21 Apr 2009 21:10:13 -0400

Now, what do the fields mean? We will analyze the last snippet -
python-pip (0.3.1-1) unstable; urgency=low

  * Initial release.  Closes: #522135.

-- Jeff Licquia <[email protected]>  Tue, 21 Apr 2009 21:10:13 -0400

which uses a template like this
software-name (version) distro-series/release; urgency=low

  * Initial release.  optional close bug

-- Maintainer/uploader <email>  datetime

The "Closes: *" is optional and specifies a registered-bug that is now fixed in the update (it may be best to not include "Closes: *"). The distro-release is the codename for the distro version, release, or series. For instance, the example above uses "unstable" which indicates that the package is for the unstable release of Debian. If a developer used "trusty" instead, then that would indicate that the package is for "Ubuntu 14.04 (Trusty)". Codenames for other Debian-based systems are acceptable. When using a codename, it is recommended that the package's version indicate the specified codename. For illustration, "nagdev_1.1-1" indicates that the package contains nagdev version 1.1 and the package version is "1". If a maintainer fixed a bug in the packaging (not the software), then the package would be "nagdev_1.1-2". When packaged for Ubuntu Trusty, the package would be "nagdev_1.1-trusty1".

"conffiles" File

The "conffiles" file lists all of the program's configuration files that are in the Debian package. If there are no configuration files, then "conffiles" can be excluded from the Debian file. The file's contents would list the path and name of each configuration file. For instance, if a package contained a program that needed a configuration file, then the Debian file would have such a file in "*DEBIANFILE*/etc/myapp.conf". So, "conffiles" would contain one line (etc/myapp.conf). There is no need for a slash at the beginning of the line.

"copyright" File

The "copyright" file contains the license information and the list of contributors. Running "dh_make --copyright gpl2" will generate a template copyright file for a project that is licensed under GPL2. Below is a general example of the file's layout.

Original source may be found at:
Files: debian/*
Copyright: Copyright YEAR Some-Name-or-Team <[email protected]>
License: other
  The Debian packaging information is licensed under the same license
  as the rest of this software.

Files: *
Copyright: Copyright © YEAR Some-Name-or-Team <[email protected]>

The developers are:
One per line

License: Name
  license terms
  remember the proper indent
  and place a dot on each blank-line

For more info -

FUN FACT: On Debian-based systems, /usr/share/common-licenses/ contains various license files. This is where dh_make gets the license info.

"rules" Script

The "rules" script is a make-script that acts like a Makefile for the Debian package. The “rules” script also defines the actions that must take place during certain events such as installation, building, etc. The "dh_make" command generates "rules" scripts. However, developers may need to tweak the script if some special task needs to be performed. However, many developers will be fine using the generated script. Below is a rules script from a Python2 interpreter package. After that is a basic example of a "rules" script. Remember that the “rules” script uses tabs, not spaces, for the indentation.

#!/usr/bin/make -f
PYTHON2=$(shell pyversions -vr)
PYTHON3=$(shell py3versions -vr)
   dh $@ --with python2,python3
   set -ex; for py in $(PYTHON3) ; do \
     python$$py build; \
   set -ex; for py in $(PYTHON3) ; do \
     python$$py install --root=$(CURDIR)/debian/tmp --install-layout=deb; \
   rm -rf build
   rm -rf *.egg-info

NOTE: Running "./DEBIAN/rules clean" will execute the code under "override_dh_auto_clean". Replacing "clean" with "install" in the previous command would cause the code under "override_dh_auto_install" to run.

Basic Form:
#!/usr/bin/make -f
# -*- makefile -*-
  dh $@

For more info -

"compat" File

The "compat" file contains the debhelper compatibility level. Most “compat” files contain a “9”. When running the “dh_make” command, the proper number will be placed in the file.

"md5sums" File

This file contains md5 checksums for each file contained in the Debian package. On each line, there is one checksum and the path and name of the file pertaining to the checksum. For example, a line will look something like "28ddc2f3640720aa73a569668751df5f usr/bin/dh_python2". Checksums are not made for the files contained in the DEBIAN folder.

"watch" File

The watch file is used to watch for updated packages. This file lists the "watch" version and the weblink where newer packages may be found. This weblink may contain regex to help find the exact link the the newest file. To test a “watch” file to ensure that it works, run “uscan --no-symlink --verbose --no-download”. Below is an example “watch” file.

version=3 pip-(.*)\.tar\.gz

For more info -

"control" File

The "control" file is the most important file. Each field must be on its own line. The "Description" field may span several lines, but they must be indented with one space, and empty lines must contain a dot (also after the indentation). Many of the possible fields are explained below.

Package - The package's name is specified in this field. The package's name may only use lower-case letters (a-z), the plus and minus signs (+-), periods/dots (.), and numbers (0-9). The name must have at least two characters and the first one must be a letter or a number. This field is required.

Source - This is used to name the source code package, if the binary package uses a name that is different from the source package.

Version - The package's/software's version is defined her. This field is required.

Architecture - The supported processor type is specified in this field. Accepted values include "all", "source", "amd64", "armel", "mips", etc. Only one value may be used in binary packages. This field is required.


Maintainer - The name and email address of the maintainer in the format "NAME <EMAIL>". This field is required.

Uploaders - Co-maintainers; additional maintainers; the format is the same as it is for the "Maintainer" field. Multiple values are separated with commas.

Changed-By - Name and email address of the person that prepared the package. The format used is the same as with the "Maintainer" field.

Installed-Size - This field's value is an estimated installation size in kilobytes.

Depends - The list of needed software. Each package is separated by a comma and the version comes after the package's name and is in parenthesis. For instance, list files like this {pkg1 (version), some-pkg (version)}.

NOTE: Listing “
” with the “Depends” will represent a wild card for the needed shared libraries.

Pre-Depends - This field is just like "Depends" except the listed packages must be installed before this package.

Suggests - Suggested/Recommended packages are listed in this field. These packages are not needed, but may be useful to have installed. The package list is formatted just like the "Depends" field.

Conflicts - Conflicts lists packages that cannot co-exist with the package being installed. If a conflict exists, the package cannot be installed and the package manager may suggest that such packages be removed. The package list is formatted just like the "Depends" field.

Breaks - The list of packages that become obsolete/useless due to the package installation are listed here. Such packages can typically be safely removed without issues. Perhaps, the package being installed supplies the listed "breaks". Therefore, it is unnecessary to have a package/program installed twice. The package list is formatted just like the "Depends" field.

Provides - This field lists the provided packages/software. The listed software is usually also listed in "Breaks" so that packages are not duplicated. If a package needs some other software (like a library), it is better to list it as a dependent package rather than including it in the package that needs it. The provided packages are listed without the version numbers, and they are separated by a comma. Here is an example of the use of "Provides". A programmer makes an improved version of BASH. The package's name cannot be "bash" since that name is already used by the original BASH shell. However, the programmer names the package (in the control file) "xbash". The "Provides" field has the value "bash" which indicates that the software (or some of the software) installed from the package is named "bash". The "Breaks" field would contain "bash" since the BASH package is planned to be replaced by the XBASH package. On such a system, the "bash" executable is still found, but the package is different. This allows users to use the enhanced version of a program while programs can still depend on and use a "bash" executable.

NOTE: A "virtual package" is one that does not have its own package. Rather, it is included with another package and is listed in the "Provides" filed of another package.

Enhances - This field is just like "Suggests", but the listed packages enhance the functionality of the package. Plugins are an excellent example of listed packages.

Section - The section field indicates the type of software in the package. Accepted values for the “Section” field are listed below. (For more info -

admin, cli-mono, comm, database, debug, devel, doc, editors, education, electronics, embedded, fonts, games, gnome, gnu-r, gnustep, graphics, hamradio, haskell, httpd, interpreters, introspection, java, kde, kernel, libdevel, libs, lisp, localization, mail, math, metapackages, misc, net, news, ocaml, oldlibs, otherosfs, perl, php, python, ruby, science, shells, sound, tasks, tex, text, utils, vcs, video, web, x11, xfce, zope


Priority - The priority is used to help solve package conflicts. The possible values for "Priority" are "required", "important", "standard", "optional", and "extra". The "required" packages are absolutely necessary for proper system functioning. "important" packages are those that are commonly used or expected on a Unixoid system. "standard" packages are small packages that are usually installed by default. Most packages are "optional" meaning the package is not required and is expected to not conflict with packages of other priorities. "extra" packages are usually specialized packages that are expected to conflict with packages of other priorities.

Homepage - The URL for the software's\package's main website is placed here.

Description - This is where the developer can include a description of the package so user's can read about the package in the package manager before deciding to install the package. This also helps users ensure they need/want the package or that this is the package they expect. The first line is the short-description. The long-description starts on the second line, and the whole long-description is indented with one space. This field is required.

Build-Depends - Lists packages needed for building source, but the packages are only needed on some architectures. For example, "Build-Depends: libsomething [!i386]" indicates that the listed package is not needed if the system architecture is i386. As for another example, "Build-Depends: libsparc [sparc]" indicates that the library will only be needed on a sparc system.

Build-Depends-Indep - Lists packages needed for building source no matter what the architecture may be.
Build-Conflicts - Similar to "Build-Depends", this field lists packages that conflict only during build-time.

Build-Conflicts-Indep - Similar to "Build-Depends-Indep ", this field lists packages that conflict only during build-time.

Built-Using - This field lists the packages used to build/compile the source. This field can be used to reproduce a binary Debian file (a Debian file containing binaries). Exact version numbers must be used.

Standards-Version - The version number of the Debian Policy Standard used in this control file is specified including the major, minor, and major patch versions. The minor patch version is optional (example: or 2.3.0). To figure out the latest version number, look at the bottom of this webpage ( which is also the manual/documentation for the latest Debian Policy Standard. Alternately, users can type “apt-cache show debian-policy | grep Version” in a command-line to see which version their Debian tools support.

Essential - This field indicates whether the package can be removed from the system or not. A value of "yes" means the package cannot be uninstalled. A value of "no" is the same as not having the field.

Vcs-* - Vcs stands for "Version Control System" and is used to indicate where the source is developed. Possible field names include Vcs-Arch, Vcs-Bzr, Vcs-Cvs, Vcs-Darcs, Vcs-Git, Vcs-Hg, Vcs-Mtn, and Vcs-Svn. The values are the addresses to the source code project. Multiple Vcs-* fields may be used. The Vcs-Browser field accepts a URL to a repository interface as a value.
Package-Type - One of two possible values are accepted by this field. If the package is a binary Debian file, then use a value of "deb". The second value is "udeb" for micro Debian packages.

Dgit - This field contains a Git commit hash and various info for the Git repo from which the package's contents originated.

X-* - User-defined fields begin with an "X".

Below is an example from a Python Debian package.
Package: python
Source: python-defaults
Version: 2.7.3-4+deb7u1
Architecture: all
Maintainer: Matthias Klose <[email protected]>
Installed-Size: 658
Depends: python2.7 (>= 2.7.3-1~), python-minimal (= 2.7.3-4+deb7u1)
Suggests: python-doc (= 2.7.3-4+deb7u1), python-tk (= 2.7.3-4+deb7u1)
Conflicts: python-central (<< 0.5.5)
Breaks: python-bz2 (<< 1.1-8), python-csv (<< 1.0-4), python-email (<< 2.5.5-3), update-manager-core (<< 0.200.5-2)
Replaces: python-dev (<< 2.6.5-2)
Provides: python-ctypes, python-email, python-importlib, python-profiler, python-wsgiref
Section: python
Priority: standard
Description: interactive high-level object-oriented language (default version)
Python, the high-level, interactive object oriented language,
includes an extensive class library with lots of goodies for
network programming, system administration, sounds and graphics.
This package is a dependency package, which depends on Debian's default
Python version (currently v2.7).

As for the syntax for specifying versions, the syntax is simple. Versions are inside parenthesis. To specify version ranges, use the standard equality-test signs where ">=" is "equal to or greater than", "=" is "equal to", "<<" is "less than", and so on. The versions may be completely typed out (like "2.7.3-1+deb7u1" for a Python2 package) or partially typed (like "2.7" for any 2.7 version of Python2).

The architectures specified for packages are in square-brackets. The accepted formats are "os-arch", "arch", and "os" where "os" specifies a Unixoid operating system and "arch" indicates the architecture. When using "os-arch", keep the hyphen in the text. The word "any" is a wildcard that can be used for the OS or architecture. Some specific examples of this syntax includes [i386], [amd64], [any-i386], [linux-any], [hurd-any], etc. If a "!" is after the first square-bracket, then that means "not". So, [!i386] means "not for an i386". The "|" means "or". Developers can use the "|" to specify a package if the one previously listed did not install due to a set condition (as seen in an example below). "|" is also used to list alternatives. Some possible "Build-Depends" fields may look like one of the lines below.

Build-Depends: pkg1 [!i386] | pkg2 [!amd64]
Build-Depends: pkg1 [linux-any], pkg2 [any-i386], pkg3 [!linux-any]

NOTE: “all” and “any” are not quite the same. The difference is discussed below.

“all” vs “any”

In the “Architecture” field, developers can specify “all” or “any”. Both of these values have different meanings. It is important to know the difference when creating and uploading packages.

any - “any” is a wildcard that represents any architecture. Such code is portable. The code may be C++ that is written in a way that will work on a variety of systems as depending on the compiler that is used. For instance, a developer could make a source package (a Deb that contains src) that contains C++ code. The package contains a Makefile. A user or server (like Launchpad) obtains this package and then compiles the code for the desired platform.

When uploading to Launchpad or other repo/PPA servers, the source package is built for each architecture automatically. So, the developer only needs to create the source package. For instance, when uploading source files and *.change files to Launchpad, the Launchpad server will create a package for amd64 and i386 hardware.

all - “all” is not a wildcard. Rather, “all” states that the software will work as it is packaged without further packaging. For instance, shell scripts, wallpapers, themes, cursors, etc. should be packaged using the “Architecture” value of “all”.

Other Files

Debian source control files (*.dsc) are like "control" files, but these are for source packages. Supported source formats include 1.0, 3.0 (native), and 3.0 (quilt). The Debian tools used to create Debian packages can generate a *.dsc from a “control” file.

Debian changes files (*.changes) are used by Debian software to process updates to the package.

For more info -

Check out the packages on this PPA ( archive/ubuntu/nag-dev-ppa) that I have helped develop.


  • slide.jpg
    43.3 KB · Views: 146,661

Members online