Easy way to create a Debian package and local package repository

This article describes a simple way to create a home made debian package and include it into a local package repository. Although we could use an existing Debian/Ubuntu package, we will start from scratch by creating and packaging our own trivial application. Once our package is ready, we will include it into our local package repository. This article illustrates a very simplistic approach, however it may serve as a template in many different scenarios.

In this tutorial you will learn:

  • How to create a trivial debian package
  • How to create a local debian repository
  • How to add the repository to the list of software sources

Software Requirements and Conventions Used

Software Requirements and Linux Command Line Conventions
Category Requirements, Conventions or Software Version Used
System Debian
Software The build-essential package
Other A working Apache web server and root permissions
Conventions # – requires given linux commands to be executed with root privileges either directly as a root user or by use of sudo command
$ – requires given linux commands to be executed as a regular non-privileged user

Creating a binary executable

The first thing we need to do, is to create a simple C++ program, compile it and test it. In case you wish to write a simple C program instead visit our comprehensive tutorial to C programming. Our program will do nothing else just print “linuxconfig.org” on the screen. Here is the code:

#include <iostream>
int main() {
    using namespace std;
    cout << "linuxconfig.org\n";
}

Save the above code as linuxconfig.cc. To compile the program we need the g++ compiler, which is provided by the build-essential package. We can install it by running:

$ sudo apt-get install build-essential

To compile the code, we use the following linux command:

$ g++ linuxconfig.cc -o linuxconfig
$ ./linuxconfig
linuxconfig.org

All is looking good. At this point we should have an executable called “linuxconfig” which prints some string on the screen.



Creating a Debian package

Now that we have our small program ready in the form of an executable binary, we can create a debian package. To do that we use the dpkg-deb tool. First of all, we need to create the debian package structure. The only files required to build a debian package are:

  • DEBIAN/control
  • custom files to be part of the package (not required)

First create a directory called linuxconfig. This directory will hold all necessary package files:

$ mkdir linuxconfig

Next, create the DEBIAN directory and the control file:

$ mkdir linuxconfig/DEBIAN
$ vi linuxconfig/DEBIAN/control

Inside the control file, we enter the following information:

Package: linuxconfig
Version: 1.0
Section: custom
Priority: optional
Architecture: all
Essential: no
Installed-Size: 1024
Maintainer: linuxconfig.org
Description: Print linuxconfig.org on the screen

Great, the only thing that is missing is our linuxconfig program. Inside the linuxconfig directory we create a directory tree which represents the path where our program will be installed in the system, and copy the
executable into it:

$ mkdir -p linuxconfig/usr/bin/
$ cp /path/to/linuxconfig linuxconfig/usr/bin/

At this point we are ready to create the package:

$ dpkg-deb --build linuxconfig
dpkg-deb: building package `linuxconfig' in `linuxconfig.deb'.
$ ls
linuxconfig  linuxconfig.deb

You may want to change the name of the package so that it includes the program version and the package architecture. For example:

$ mv linuxconfig.deb linuxconfig-1.0_amd64.deb

All done ! Our package is ready ! (NOTE: this is just an example, the creation of official packages requires more work).

Setting up a local package repository

To create a local package repository we need a working. In this case we will assume the use of Apache with default settings. To install Apache webserver, all we need to do is to run:

$ sudo apt-get install apache2


Once installed, to verify that the webserver works, we can navigate to the IP address of the machine (or to ‘http://localhost’, if running a browser on the machine itself) which,  in our case is http://10.1.1.4. We should see the
famous It works! message.

The web server software is running but no content has been added, yet. The DocumentRoot of the default Apache VirtualHost, is /var/www/html: this is where we will create our repository.

Let’s create the “debian” directory inside /var/www/html and copy the linuxconfig-1.0_amd64.deb package inside it:

$ sudo mkdir /var/www/html/debian
$ sudo cp /path/to/linuxconfig-1.0_amd64.deb /var/www/html/debian/

The next step consists in the generation of a package list. We move into the debian directory, and use the dpkg-scanpackages utility to accomplish the task. You may need to install the dpkg-dev package in case the dpkg-scanpackages command is missing:

$ dpkg-scanpackages . | gzip -c9  > Packages.gz
dpkg-scanpackages: info: Wrote 1 entries to output Packages file.

Our local repository is now ready.

Adding the repository to the software sources

At this point to be able to install our package from the local repository we created, we need to edit the /etc/apt/sources.list file, add the entry relative to it (change IP address to reflect that of your machine), and
synchronize the repositories:

echo "deb [trusted=yes] http://10.1.1.4/debian ./" | tee -a /etc/apt/sources.list > /dev/null

Be sure to add the above [trusted=yes] to avoid the following error message:

 Release' does not have a Release file.                   
N: Updating from such a repository can't be done securely, and is therefore disabled by default.

Synchronize repositories:

$ sudo apt-get update
Ign:1 http://10.1.1.4/debian ./ InRelease
Ign:2 http://10.1.1.4/debian ./ Release
Ign:3 http://10.1.1.4/debian ./ Packages
Ign:3 http://10.1.1.4/debian ./ Packages
Ign:3 http://10.1.1.4/debian ./ Packages
Get:3 http://10.1.1.4/debian ./ Packages [303 B]

To install our package, we can now use the apt-get tool:

$ sudo apt-get install linuxconfig
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following NEW packages will be installed:
  linuxconfig
0 upgraded, 1 newly installed, 0 to remove and 8 not upgraded.
Need to get 3174 B of archives.
After this operation, 1,049 kB of additional disk space will be used.
WARNING: The following packages cannot be authenticated!
  linuxconfig
Install these packages without verification [y/N]? y

Execute:

$ linuxconfig
linuxconfig.org

To remove the package from the system, just run:

$ sudo apt-get remove linuxconfig
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages will be REMOVED:
  linuxconfig
0 upgraded, 0 newly installed, 1 to remove and 3 not upgraded.
After this operation, 1049 kB disk space will be freed.
Do you want to continue? [Y/n] y