Creating apt repository with reprepro on Ubuntu

If you create deb packages and would like to distribute them in a more centralized way instead of asking your users to download them and install them manually, then setting up an apt repository is the way to go.
The following walk-through sets up signed Ubuntu repository.

1. Install GnuPG and generate a GPG key.

In order to create a secure APT repository you might want to  sign your debian packages. You'll need a GPG key in order to do that.

The “builder” name mentioned is a debian convention, indicating that the builder of the package signed it. The GPG key used will be the one you set up above, providing you’re running the command as the same user you set up the key with.

For more information on how to create a deb package read this article.

2. Install and Configure reprepro.

3. Create the file system layout for the repository.

If you would like to support multiple platforms besides Ubuntu, then you need to create similar directory structure specifying the distribution name as outlined bellow:

4. Configuring the repository.

The reprepo utility that will create the repository uses four config files, which are searched in the directory specified with --confdir or in the conf/ subdirectory of the basedir.

If a file options exists, it is parsed line by line. Each line can be the long name of a command line option (without the --) plus an argument, where possible. Those are handled as if they were command line options given before (and thus lower priority than) any other command line option. (and also lower priority than any environment variable).

To allow command line options to override options file options, most boolean options also have a corresponding form starting with --no.

The file distributions is always needed and describes what distributions to manage, while updates is only needed when syncing with external repositories and pulls is only needed when syncing with repositories in the same reprepro database.

The last three are in the format control files in Debian are in, i.e. paragraphs separated by empty lines consisting of fields. Each field consists of a fieldname, followed by a colon, possible whitespace and the data. A field ends with a newline not followed by a space or tab.

The other two files "updates" and "pulls" can be omitted if not needed.

The important options in the distribution configuration files are:
Codename - this required field is the unique identifier of a distribution and used as directory name within dists/ It is also copied into the Release files. Note that this name is not supposed to change. You most likely never ever want a name like testing or stable here (those are suite names and supposed to point to another distribution later).

Architectures - this required field lists the binary architectures within this distribution and if it contains source (i.e. if there is an item source in this line this Distribution has source. All other items specify things to be put after "binary-" to form directory names and be checked against "Architecture:" fields). This will also be copied into the Release files. (With exception of the source item, which will not occur in the topmost Release file whether it is present here or not).

SignWith - when this field is present, a Release.gpg file will be generated. If the value is "yes" or "default", the default key of gpg is used. Otherwise the value will be given to libgpgme to determine to key to use. If there are problems with signing, you can try gpg --list-secret-keys value to see how gpg could interprete the value. If that command does not list any keys or multiple ones, try to find some other value (like the keyid), that gpg can more easily associate with a unique key. If this key has a passphrase, you need to use gpg-agent or the insecure option --ask-passphrase.

DscOverride - when this field is present, it describes the override file used when including .dsc files.

For the purpose of this tutorial the override.precise file can be left empty:

5. Building the repository and adding packages to it.

To add a deb package to the repository run:

To list the available deb packages in the repository execute:

To remove the package from the repository run:

6. Configuring repository access. 

The easiest way to make the repository accessible is by configuring a virtual host in Apache.

Copy the pgp key to the root of your web server so customers can download it and install it on their systems:

Now on one of your customers systems download the repository key and add it to the keyring:

Then add the new repositry source in /etc/apt/sources.list or in a separate file in /etc/apt/sources.list.d/

One drawback of using reprepro is that you can't have multiple versions of the same package. Once you add the latest version of a package the previous one will be automatically deleted.