Introduction
How do you install software on an Ubuntu machine? How do you create a deb file? How does apt-get work? These are the questions I will try to answer in this post, but first a little background.
Background
I love Virtual Computing. I can run tons of virtual servers on a very limited number of physical machines. This allows me to segregate applications exactly as I choose. I can have subversion and Trac running on one and nothing but an email gateway on another, it also gives me a way to try new applications like Splunk without jeopardizing a system and with investing in another box.
The drawback to being able to create new virtual machines on a whim is administering them once they are created. I’ve written a couple of applications that would like to install on all my virtual machines and that is where packaging them as deb files and creating a repository server that apt-get is aware of comes in very handy.
Create a DEB file
The ultimate goal is to be able to type from any of my VMs and have it install properly. All apt-get really does is check all its repository servers for a deb file that contains the “myapp” package, downloads the deb file and installs it. So before we build our repository server (also a VM BTW) we have to create the deb file.
To create the deb file, you need to:
- Create the directory structure
- Create the control file
- Write the install and uninstall scripts
- Build the package
Create the Directory Structure
The directory structure of your package will directly mimic the directory structure of the system, with the files in place. For example, if my application requires placing the script A.sh in /usr/sbin and B in /etc/init.d, my directory structure would like:

Create the Control File
Next, we need to create the control file. The control file is placed in a special directory called DEBIAN. After you create that directory your directory structure should look like:

Inside of the DEBIAN directory, create a file named control. Mine looks like:
Most of the entries are self explanatory, but the one you will want to pay close attention to is the “depends” statement. When a user installs your package, if they haven’t installed any of the dependencies, apt-get will allow them to automatically install them.
Install and Uninstall
The next step is to write the install and uninstall scripts. The files in your package will automatically be copied to their corresponding location on disk, but if you need more configuration that has to be performed in your script, you can add that code to a script called “postinst” in the DEBIAN directory. Conversely, you must reverse any changes made during installation in a script called “prerm” which will be called during uninstallation.
For instance, my package contains an xinetd service, so I am going to add lines to “/etc/services”. My “postinst” file will look like:
And my “prerm” file will look like:
Side Note About postinst and prerm
I find sed to be a very useful tool when editing configuration files from a script. This page contains many useful one sed script that may help you write your install/uninstall scripts.
Build the Package
Now our package is complete, we’ve placed our files in the appropriate places and written our control file, install and uninstall scripts. The last step is to package the results into a deb file. To do this, navigate to one level above your package. So if your package is in ~cpetersen/projects/pacakge, navigate to ~cpetersen/projects. From there execute the following command.
That will create the file ~cpetersen/projects/package.deb. You now have a fully functioning deb file. You could install it using dpkg, but we want to use apt-get, so next we’ll look at creating a repository server.
Setup a Repository Server
The repository server is a simple web server (apache in our case) that happens to store the deb files and some meta-data about them. The first step in getting it up and running is installing apache and the dpkg-dev kit which will allows us to create the index.
Next, create the directory where the repository will live. I created a virtual machine to serve as the repository server. Since this is a dedicated machine, I will create my directory directly at the www-root. This would work as well in an apache virtual server. My www-root is /var/www so my deb files will go into /var/www/repository. Finally, you must index the deb files meta data. You can do this with a program called dpkg-scanpackage that comes with the dpkg-dev package. From the directory that you want to server as your repository (for me it is the root /var/www) execute the following commands:
Your repository server is done. If you want more information, I found this page very helpful. Now make sure apache is running and we can move on to the final step, making your clients aware of the server.
Using Your Server
So now you have your deb file, and you have your repository server. How do your client machines know to you use it? apt-get configures its servers using the /etc/apt/sources.list file. So you need to add your new server to that file. I named my server repo01, and I placed my repository in the www-root directory, so I added the following line to all of my clients /etc/apt/sources.list files:
Don’t forget the trailing ” /” (there is a space there). Now update your clients:
And finally you should be able to install your package:
A Note About Adding Packages
Once your server is up and running and your clients are configured to look for it, it is very easy to add or update packages.
- Copy the deb file to your repository directory
- Re-execute the dpkg-scanpackages command to update the index
- Update your clients with sudo apt-get update
Conclusion
Setting up your own repository server and distributing your internal applications as deb files can simplify administration of numberous machines. There are three basic steps, each of which we outlined in this post:
- Create the deb file
- Setup the repository server
- Configure the clients to use your repository
You should now have a working deb file that you can install using apt-get.