Build Your Own Deb File and Repository Server
July 9th, 2007 cpetersen
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 typesudo apt-get install myapp
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:
Package: package
Version: 1.0
Section: web
Priority: optional
Architecture: all
Essential: no
Depends: ruby, sed, xinetd
Installed-Size: 1
Maintainer: Chris Petersen [christopher dot petersen at gmail dot com]
Provides: package
Description: A short description of your package
This should be a longer description of your package,
it can span multiple lines, and should indented with
spaces
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:#!/bin/sh
echo "package 1789/tcp" >> /etc/services
echo "package 1789/udp" >> /etc/services
/etc/init.d/xinetd reload
And my "prerm" file will look like:
#!/bin/sh
sed '/package/d' /etc/services > /tmp/services
mv /tmp/services /etc/services
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.dpkg-deb --build package
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.sudo apt-get install ssh
sudo apt-get install apache2
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:
sudo su
dpkg-scanpackages . /dev/null | gzip -9c > Packages.gz
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:deb http://repo01 /
Don't forget the trailing " /" (there is a space there). Now update your clients:
sudo apt-get update
And finally you should be able to install your package:
sudo apt-get install 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



August 7th, 2007 at 09:16 PM Hi, This article was very informative. I would like to know more about the files which are located in "/var/lib/dpkg/info" of these endings *.list, *.md5sums, *.shlibs, *.list. This folder also has files like *.postinst and *.postrem, which I think you have explained great. Thanks.
August 9th, 2007 at 03:08 AM HI Uma, Great point, I didn't really touch on the /var/lib/dpkg/info at all. My understanding is that your install and uninstall scripts <macro:code> preinst postinst prerm postrm </macro:code> all get copied there using the filename <macro:code> {package_name}.{script_name} </macro:code> It is also my understanding that the package manager keeps track of all the files that were copied onto the file system for this install in the file: <macro:code> {package_name}.list </macro:code> So for the example in the post, the list file would look like: <macro:code> /. /etc /etc/init.d /etc/init.d/B /usr /usr/sbin /usr/sbin/A.sh </macro:code> As for the md5sums, I'm guessing it has to do with signing your package, which I haven't yet tried. shlibs seems to store the dependencies. I've also seen files named <macro:code> {package_name}.conffiles </macro:code> I assume these store the configuration files for the package, but I'm unsure how to use them. If anyone has any insight into these files, please post a reply or a link that may help. Thanks! Chris
September 2nd, 2007 at 10:26 PM Hi, nice article. I have just a question, did you tryed also to build deb packages from rails application? I'm investigate the possibility of using deb/rpm packages to deploy rails apps. What do you think?
September 3rd, 2007 at 06:28 AM [...] Build Your Own Deb File and Repository Server 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. (tags: debian linux repository package deployment howto) [...]
October 6th, 2007 at 09:40 AM Hi Frederico, I haven't tried building a deb file from Rails, but it does sound like an interesting idea. What type of service do you anticipate building? Chris
June 4th, 2008 at 03:25 PM [...] Build Your Own Deb File and Repository Server [...]