Building Debian Packages

I’ve been playing around with the idea of using debian packages to deploy updates to various servers (virtual machines, dev servers, production servers etc). I was curious to see how this could work for a variety of tasks, but mostly I needed a way to help keep our development virtual machine up to date without physically maintaining a virtual disc that all developers use. Because we each modify the vm to fit in our specific environment, the need to enforce the existence of *packages* and not specific *configuration* is paramount – this turned out to be a godsend for us.

When I started researching how to build a .deb package I was a little overwhelmed by the initial information that turned up in a web search, but after digging around and testing I found that building a package is pretty easy. My initial confusion stemmed from the fact that all the examples I found documented how to include application source that gets compiled when the package is installed … I did not want to compile source code, I just wanted to supply a list of dependencies and supply a few apache configuration files. Rest assured, you can bundle up configuration file changes into a debian package, let me show you how. For this example, I will show you how to ensure the server has needed packages installed, and we will add a virtual host configuration for a new site.

Preparing for the build

The internals to a .deb are fairly straightforward. First you need a directory called “DEBIAN” that contains a few files that detail and control the processing during installation; this directory and all files contained in it MUST be named exactly as you see them below. Secondly, you need to include the full target directory structure for any files that you want to copy over during installation. You can have as many directory structures as needed for your package.

Example:

+ setup
    + DEBIAN
        - control
        - debian-binary
        - postinst
        - postrm
        - preinst
        - prerm
    + etc
        + apache2
            + sites-availalble
                - mysite

Explanation:

  • setup: This is just the top level directory that holds the contents you want to package up – call it whatever you want
  • DEBIAN: This is the directory that holds the instructions for deploying the package. This must be in all caps.
  • DEBIAN/control: This is the control file for the package. It contains meta data and dependancy information – more on this later.
  • DEBIAN/debian-binary: This file just contains the version number for the package manager you are using.
  • DEBIAN/postinst: This is a shell script that gets executed after installation
  • DEBIAN/postrm: This is a shell script that gets executed after removal
  • DEBIAN/preinst: This is a shell script that gets executed before installation
  • DEBIAN/prerm: This is a shell script that gets executed before removal
  • etc/apache2/sites-available: This is the directory structure that matches the target system. This structure gives the package the path on where to copy over the “mysite” file
  • mysite: this is the apache virtual host configuration file that i want to copy to the server

Configuration

DEBIAN/control

We need to add our configuration data to the control file.

Also, since our application uses some PHP features for CuRL and memcache, I need to make sure that the target system has the appropriate packages installed.

Full details on the control file can be found here, but for our needs we can just use the following:

Package: serversetup
Version: 1.0
Section: devel
Priority: optional
Architecture: amd64
Depends: memcached, php5-curl, php5-memcache
Installed-Size: 4
Maintainer: My Name <my@email.com>
Description: Setup package for MySite

Explanation:

  • Package: This is the name of your package.
  • Version: This is the version number of your package. Make sure to increment for subsequent releases.
  • Section: This is the section where the package is stored in the Debian FTP sites.
  • Priority: This is the priority for installation of the package. Setting this helps apt sort the package properly when installing multiple items.
  • Architecture: This is chip architecture you are packaging for.
  • Depends: This is the list of packages that need to be installed for your package to install/run properly
  • Installed-Size: This is the amount of space that will be taken up by installing the package.
  • Maintainer: This is the name and email of the person who maintains the package
  • Description: This is a brief summary of the package contents

DEBIAN/debian-binary

This file just contains the version number for the package manager. So just put the text: “2.0″ followed by a line break.

mysite

This file contains the apache virtual host configuration.

<VirtualHost *>
    ServerName mysite.com
    DocumentRoot /var/www/vhosts/mysite/pub
</VirtualHost>

Scripts

This package is pretty simple, so we really only need to worry about running a few commands after the package is installed. For our purposes here, the postinst script will fit our needs.

#!/bin/bash

# add document root
mkdir -p /var/www/vhosts/mysite/pub
echo "<h1>Empty Document Root</h1>" > /var/ww/vhosts/mysite/pub/index.html

# enable vhost
a2ensite mysite
/etc/init.d/apache2 restart

Building the Package

Now that we have our control file defined and our scripts written, we can move on to bundling all these files together into an actual debian package. To do this, we just run a single command:

dpkg -b /path/to/setup serversetup_1.0_amd64.deb

Obviously you need to adjust the first parameter to match the location of your setup directory, and you may adjust the name of your .deb file to meet your needs. Typically you will want to name it something in line with the pattern “package_version_architecture.deb”.

Full detains on naming conventions can be found here.

Installing the Package

One of the great things about debian packages is the auto solving of dependancy issues. The thing with manually installing a local package via dpkg is that it does not resolve the dependancies for you, it just errors out and lists what you need to resolve yourself.

If you want to have the dependancies resolved for you, use gdebi instead to install packages. All dependencies specified in your control file will be handled just like installing a remote package via apt-get.

sudo gdebi /path/to/serversetup_1.0_amd64.deb

Taking it Further

By using this method it is now possible for all developers in my group to create their own virtual machine and get up and running with minimal effort. My setup package details all the needed packages that we use for development to make sure that the virtual machine is running everything we need it too. I also bundled some php extensions that we use for charting and debugging so setting these items up is a minimal task.

I’m currently looking at using debian packages to deploy large scale php application updates to a cluster of servers. In theory we should be able to set up an apt repository and allow each individual server pull down and install updates with the built in package manager.

Have any comments or ideas on how to make this better? Please share!


One Response to “Building Debian Packages”

Leave a Reply