Debian Package tool
dpkg is used on Debian, Ubuntu, Kali, Linux Mint,
and other Debian based Linux distributions.
This tutorial covers the basics of creating custom
and managing them with
We will cover the process of creating your own
deb file to distribute
your package easily.
It is aimed at people who are interested in learning the basics of
creating and managing packages in Debian based distributions.
Read more about
The .deb file format
.deb file is a Debian package, but really it is just a standard
Unix archive (
dpkg tool is the Debian package manager and
apt is a higher level
tool for managing packages which uses
dpkg under the hood.
List installed packages
List packages with
dpkg -l # List installed packages dpkg -s mypkg # Get status of specific package apt list --installed # List installed packages apt list # List *all* packages in available repos
Create a package
You can make and distribute your own
.deb package very easily.
To start fresh, create a new directory named after your package.
This directory will store the package metadata and the package contents.
Inside the project directory, there needs to be one special
DEBIAN) with one special file inside it (
Read more about Debian control file fields.
# Minimum required structure for a package mypkg-1.0.0/ # Directory └── DEBIAN/ # Directory └── control # File
A more practical example with a post-installation script:
mypkg/ # Directory ├── DEBIAN/ # Directory │ └── control # Control file │ └── postinst # Post install script ├── etc/my.ini # Optionally any other files that you need to include └── opt/mylib/ # on the destination system during installation
This is a minimal example of the
Package: mypkg Version: 1.0.0 Maintainer: Your Name <firstname.lastname@example.org> Description: My test package, please ignore Homepage: https://github.com/username/projectname Architecture: all Depends: git, python3 (>=3.5), openjdk-8-jre-headless|openjdk-8-jre|openjdk-8-jdk-headless|openjdk-8-jdk
Depends line is optional, but frequently needed.
The example above shows how to add multiple dependencies,
how to specify a minimum version with python3,
and how to add a dependency that is satisfied by one of many options.
There are many versions of java listed and any one will satisfy the requirement.
If none of them are installed, it will start from the first
one in the list and try to install it.
This way, it will work if the user has version 8 of the JDK or JRE in full or headless variant.
If none of them are installed it will install the smallest version (the headless jre).
Build the package by running
dpkg -b on the project directory like this:
# Build mypkg directory in to .deb package dpkg -b ./mypkg ./mypkg_1.0.0-0_amd64.deb # Naming format: <name>_<version>-<release>_<arch>.deb # Version is the version number of the app being packaged # Release number is the version number of the *packaging* itself. # The release number might increment if the package maintainer # updated the packaging, while the version number of the application # being packaged did not change. # Inspect information like size, version, dependencies dpkg -I mypkg.deb
# Example output of `dpkg -i mypkg.deb` new debian package, version 2.0. size 666 bytes: control archive=301 bytes. 238 bytes, 6 lines control Package: mypkg Version: 1.0.0 Maintainer: Your Name <email@example.com> Description: My test package, please ignore Architecture: all Depends: git, python3 (>= 3.5), openjdk-8-jre-headless|openjdk-8-jre|openjdk-8-jdk-headless|openjdk-8-jdk
It's a special little package, but it's lonely without any files to install. Normally a package has some contents like a shared library, man pages, documentation, an executable program, or systemd service files.
The next thing we'll need to do is add files to the package. Some examples of things you might include are:
- an executable or a shell script launcher in
- man pages in
- configuration files in
- libraries in
- header files in
In this example, we'll add a shell launch script for a Java JAR file:
#!/bin/bash # Launch script to kick off Java JAR (/usr/bin/mylauncher) java -jar /usr/share/java/myapp.jar "$@"
Be sure to
chmod +x the script and place it in the
List configuration files in
This will allow configuration files to optionally remain when
uninstalling (remove vs purge).
It also prevents updates from overwriting configuration files.
Pre/post install scripts
#!/bin/bash # This `DEBIAN/postinst` script is run post-installation mkdir /dir/needed/for/package
There are some other variables you can specify in the
These can be useful to warn people if your package conflicts with another package that is already installed. You can also replace or enhance existing packages. If other packages would make your package work better, you can recommend and suggest other packages when the user installs your package.
Read more about package interrelationship fields.
Print package information
You can use
apt-cache to get some information about
# Print details about a package file (size, version, dependencies) dpkg -I mypkg.deb # Print status (is it installed?) dpkg -s <package_name> # Show package info (even uninstalled ones from repos) apt-cache show <package_name>
Print package contents
If you want to review the contents of a
.deb package before installing
it, you can print the contents with the
dpkg -c mypkg-1.0.0-0_amd64.deb
Extract package contents
If you want to extract the contents of a
-X flag for verbose extraction,
-x for quiet extraction.
dpkg -X mypkg-1.0.0-0_amd64.deb /where/to/exctact/
Install a package
Usually, two options are available for installing .deb packages.
dpkg and the other is
apt which is built on top of
If you don't have the dependencies installed you will have to install them
yourself if you use
Alternatively, you can use
I recommend using
apt because it still uses
dpkg under the hood,
but it handles dependencies and is more user-friendly.
# Install package along with any dependencies it needs sudo apt install ./mypkg.deb # Install package, ignore and warn about unmet dependencies sudo dpkg -i mypkg.deb # If you need to install dependencies that were not # installed because you used `dpkg -i` instead of `apt install` sudo apt --fix-broken install # Get status of package dpkg -s mypkg
Searching for packages in apt repositories
You can use
apt-cache to search for packages
apt repositories. These will need to be
apt install though not
Search like this:
apt-cache search alien
Uninstall a package
You can uninstall a package using
remove but it will leave the
To also remove the configuration files, use
dpkg --remove package_name # Leaves config files dpkg --purge package_name # Removes config files too # Or with apt apt remove package_name apt purge package_name
Listing files that belong to a package
This can be useful when trying to figure out what the executable file names are in /usr/bin or when trying to find local documentation.
# List all files that are included in the `ruby` package dpkg -L ruby dpkg -L ruby2.5-doc
Find which package owns a file
If you have a file on your system and you want to see if it belongs to a
package, you can use
dpkg -S <filepath> to see which package owns it.
You can also use
apt-file search <filename> to see which packages in
the repositories contain a file with that name.
For example "What package created this /etc/qwerty.conf file?" or
"Which package owns this executable?", or
"Which packages do I need to install to get
gl.h?" can be answered with:
# Figure out which package owns a specific file dpkg -S /etc/qwerty.conf dpkg -S /usr/bin/python3 # Search apt repositories for packages that contain file # Find any package that includes a `gl.h` apt-file search "gl.h"
Only Use trusted packages and repositories only. You install packages with root privileges and you will be giving full reign on your machine with a package. Do not run any package you are not 100% confident it is from a trusted source.
GPG signing is a good way to ensure integrity and authenticity, that is, it has not been modified and the package came from the expected author.
You can learn more about how to sign files with GPG in my GPG Basics Tutorial. GPG is a great cryptography tool to be familiar with and worth taking the time to learn it. You can also use it to encrypt emails so only the intended recipient can read it, encrypting archives or PDFs, verifying signatures from others, and and many other practical uses.
.rpm and other formats
If you need a RedHat
.rpm file to install in CentOS, RedHat, or Fedora,
you can use the
alien tool to convert packages.
sudo apt install alien alien --help alien --to-rpm my_pkg.deb
Some other options are:
-d, --to-deb Generate a Debian deb package (default). -r, --to-rpm Generate a Red Hat rpm package. --to-slp Generate a Stampede slp package. -l, --to-lsb Generate a LSB package. -t, --to-tgz Generate a Slackware tgz package.
I do not have much experience with this tool but it is worth a mention. The debhelper tool provides some utility and code generation features. Here is how you can install it and explore more.
sudo apt install debhelper man dh # See what tools are available by entering dh_<tab><tab> # Get the autocomplete options # Generate a new Debian package template sudo apt install dh-make # From inside a directory w/ name like: mypkg-1.0.0 dh_make --createorig
You should now feel comfortable working with and creating your own Debian packages, how to get information about a package, how to find which package a file belongs to, and other common tasks.