Building a Simple Deb Package
All of the hip kids today are into deploying packages and complex systems with things like Ansible, Docker, Chef, Puppet, Vagrent and Salt Stack. While these deployment tools are awesome, you should not forget about good old fashioned system packages for application deployment. I fully understand there are times when some of these newer deployment tools are a better fit, but, as time goes on, I run across more and more overly complicated and convoluted deployment procedures using these new tools when a simple deb or rpm package could be used. Maybe Im just oldschool, but whenever possible, I prefer to handle application deployment with system packages, such as debs or rpms.
Creating deb packages to deploy applications in Debian or Ubuntu is a fairly simple process. However, I have found that the majority of existing documentation for doing so is overly verbose or more complex than needed. This writeup aims to summaries the process of creating deb packages in just a few simple steps.
Here is a short summary of what this writeup covers:
- How to create a bare bones deb package
- How to optionally add package configuration files
- How to optionally add package dependancies
- How to optionally add package scripts that run before or after installation
Create a Build Directory
The first step is to create a build directory for the deb package.
mkdir ~/package_build_dir cd ~/package_build_dir
Create Your Base Package Directory
Next we will create the base directory that will house our package structure. During the following steps, you will likely want to replace references to "my_package_name" with the actual name of your package.
mkdir -p my_package_name/DEBIAN
Create the Package Control Configuration File
The control file is the core configuration file for a deb package. Its main function is to define the package name, architecture, description, version, etc. The config used below is about as bare bones as you can get. If you want to look into other options which you can define in this file, look here.
Note: I am using
cat <<EOF >> filenamein the following code snippets. If you would rather create these config files in an editor, just open the filename, cut out the first and last lines (i.e. the lines with EOF in them) and copy the configurations into "filename".
cat <<EOF >> my_package_name/DEBIAN/control Package: my-package-name Architecture: all Maintainer: @hackgnar Priority: optional Version: 0.1 Description: Some description EOF
Copy Your Binary/Service/Script/Application Into Your Package
In this step, we create a simple bash script that prints out "this is my package". This bash script will be included in the deb package we are creating. If you already have an application you want to include in the package, feel free to replace the bash script in this step with your application data.
Note: if your package includes more than binaries (i.e. libs, configs, etc), you can create a lib or etc directory in your base package directory to house these files. For more info on this, check out the optional steps listed in this tutorial.
mkdir -p my_package_name/usr/bin cat <<EOF >> my_package_name/usr/bin/mypackage #!/bin/bash echo this is my package EOF chmod 700 my_package_name/usr/bin/mypackage
(OPTIONAL) Add Application Configuration Files
If the application your deb package installs requires configuration files, this step shows how to properly include them.
mkdir -p my_package_name/etc touch my_package_name/etc/myconfig.conf cat <<EOF >> my_package_name/DEBIAN/conffiles etc/myconfig.conf EOF
(OPTIONAL) Add Dependencies to Your Package
Adding dependancies to your deb package forces package management systems (i.e. dpkg, apt-get, aptitude) to install, or require the installation of, other packages.
In this example, we add the vim package as a dependency to our package. If you are using apt-get to install your custom deb, this will cause the package manager to install vim before our new custom package is installed. If you use
dpkg -ito install our new package, this will cause dpkg to fail to install our new package until you manually install the vim package (i.e. apt-get install vim).
cat <<EOF >> my_package_name/DEBIAN/control Depends: vim EOF
(OPTIONAL) Add Bash Scripts That Run Before or After Your Package Installation
Sometimes you may find a need to run bash scripts before or after your packages files are laid down on the file system. This may be needed to configure the base system before installation, start your program differently the first time it runs, etc. This can be done by including what deb packages call "preinst" and "postinst" bash scripts. The following shows how to include a postinst script that simply creates an empty file after your application is installed.
cat <<EOF >> my_package_name/DEBIAN/postinst #!/bin/bash touch /root/touched EOF chmod 755 my_package_name/DEBIAN/postinst
Finally, Build Your Package!
The following step will actually build your new package. After it finishes running, you will have a deb package named my_package_name.deb
dpkg-deb --build my_package_name
(OPTIONAL) Install Your Application
To install your deb package directly from a deb file, you will have to use the
dpkgcommand instead of
aptitudewhich install applications from remote apt repos.
dpkg -i my_package_name.deb
if you have issues with dependancies, run the following and then run the above
sudo apt-get -f install
While this guide is meant to be a practical guide to creating a minimal deb package, it covers most functionality you will typically need when creating deb packages. If you need to utilize advanced package configuration options, try reading over the official deb package documentation. It is a great place to start.
Keep and eye out on this blog for a follow up article on how to create a remote apt repo and host your newly created deb packages.