Monday, January 25, 2016

Simple Deb Package Creation

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:

  1. How to create a bare bones deb package
  2. How to optionally add package configuration files
  3. How to optionally add package dependancies
  4. 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 >> filename in 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

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
    echo this is my package
    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

(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 -i to 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

(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
    touch /root/touched
    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 dpkg command instead of apt-get or aptitude which 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 dpkg command again

    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.

No comments:

Post a Comment