Setting up and managing an APT repository with reprepro

by Sander Marechal

If you are writing software for Debian GNU/Linux or deratives like Ubuntu then setting up an APT repository is a very useful thing to do. It's often not possible to get your software into the official repositories of already released distributions. Setting up an APT repository for your users makes it very easy for them to keep up-to-date with the latest version of your software, far easier than providing .deb's as downloads on your website.

In this tutorial I am going to show you how to set up and manage an APT repository using reprepro. Reprepro makes it very easy to set up APT repositories that use a common /pool directory to store all the package files. Using a /pool directory means that you don't have to duplicate packages (especially source packages) across different distributions and versions. In this regard, reprepro is superior to APT tools such as apt-ftparchive. I am going to assume that you are already familliar with the basic workings of an APT repository.

Setting up reprepro

The distributions file

If you want to provide APT repositories for multiple distributions (Debian, Ubuntu, etcetera) then you should manage them separately. I am going to keep all my repositories under /var/packages/ and set up a repository for Ubuntu Dapper Drake. The directory /var/packages/ubuntu/ is going to be the base of the Ubuntu repository. Create a conf/ in the repository base to hold all the configuration files for this repository. The distributions file contains the information that reprepro needs to manage your repository. My configurations looks like this:

  1. Origin: Lone Wolves
  2. Label: Lone Wolves
  3. Codename: dapper
  4. Architectures: i386 amd64 source
  5. Components: main
  6. Description: Lone Wolves APT Repository
  7. SignWith: yes
  8. DebOverride: override.dapper
  9. DscOverride: override.dapper

The above example contains one block of settings, but you can have multiple blocks separated by a newline in this configuration file. You would have, for example, one block for Ubuntu Dapper Drake, one for Edgy Eft, one for Breezy Badger, etcetera. The Origin, Label and Description field can be filled with whatever you want. The Codename is the specific distribution/version that this block of settings applies to. In this case it's dapper. The Architectures and Components fields speak for themselves. The SignWith fields indicates that you want to create a Release.gpg file, creating a signed APT repository. It is highly recommended that you do so. If you have multiple GPG keys installed on your APT server, you can also replace the "yes" value with something that tells GPG what key to use. A name or a key ID for example. Finally the DebOverride and DscOverride fields tell reprepro what files to use for the override rules. Override rules can be used to override .deb and .dsc configuration fields. The .dsc files always need an override file because .dsc files do not contain Section and Priority information, e.g. optional - games for gnome-hearts.

The options file

The options file is a list of command line options that you want to pass to reprepro everytime you run it. Creating an options file saves you many keystrokes when managing your APT repository. You can only put the long option names in it (e.g. verbose, not v) without the -- prefix. My options file looks like this:

  1. verbose
  2. ask-passphrase
  3. basedir .

If you set the SignWith configuration field to use a GPG key that requires a password then you should set the ask-passphrase option in your options file or set up a GPG-agent to do the signing for you. By default reprepro will not ask you for your passphrase.

The override file

The default location for override files is the override/ directory in the APT base directory. The override file has a very simple layout of "package_name option value". For example, the entry for gnome-hearts looks like this:

  1. gnome-hearts    Priority        optional
  2. gnome-hearts    Section         games

Managing your repository

The configuration of reprepro is now done, so it is time to add at least one package to it so that reprepro will generate all the required files and directories for you. You should always work from the base repository directory or specify the path to the base directory with the --basedir option (commandline options override options specified in the options file). Adding a .deb is very easy:

  1. $ reprepro includedeb <codename> <debfile>

Or, for gnome-hearts:

  1. $ reprepro includedeb dapper ~/gnome-hearts_0.1.2-1_amd64.deb
  2. /home/sander/gnome-hearts_0.1.2-1_amd64.deb: component guessed as 'main'
  3. db: 'gnome-hearts' added to 'dapper|main|amd64'.
  4. Exporting indices...
  5. Successfully created './dists/dapper/Release.gpg.new'

You can include .dsc, .udeb and .changes files with the commands includedsc, includeudeb and include respectively. The list command shows you what packages reside in the repository, and you can remove packages again with the remove command:

  1. $ reprepro -A amd64 list dapper gnome-hearts
  2. dapper|main|amd64: gnome-hearts 0.1.2-1
  3.  
  4. $ reprepro -A amd64 remove dapper gnome-hearts
  5. removing 'gnome-hearts' from 'dapper|main|amd64'...
  6. db: 'gnome-hearts' removed from 'dapper|main|amd64'.
  7. Exporting indices...
  8. Successfully created './dists/dapper/Release.gpg.new'
  9. Deleting files no longer referenced...
  10. deleting and forgetting pool/main/g/gnome-hearts/gnome-hearts_0.1.2-1_amd64.deb

Setting up Apache

Now that the repository has been created it's time to let the world access it. At my registrar I have set up the packages.jejik.com subdomain to point to the IP address of my APT server. I am going to create a virtual host that points to the /var/packages/ directory and, at the same time, hides the conf/ and db/ directory. The db/ directory is created by reprepro when you add your first package. The result is that people will be able to add lines such as the folowing to their /etc/apt/sources.list file:

  1. ## Lone Wolves Ubuntu APT repository
  2. deb http://packages.jejik.com/ubuntu dapper main
  3. deb-src http://packages.jejik.com/ubuntu dapper main
  4.  
  5. ## Lone Wolves Debian APT repository
  6. deb http://packages.jejik.com/debian stable main
  7. deb-src http://packages.jejik.com/debian stable main

Here is what the Apache configuration file looks like:

  1. <VirtualHost *>
  2.         DocumentRoot /var/packages
  3.         ServerName packages.jejik.com
  4.         ErrorLog /var/log/apache2/error.log
  5.  
  6.         LogLevel warn
  7.  
  8.         CustomLog /var/log/apache2/access.log combined
  9.         ServerSignature On
  10.  
  11.         # Allow directory listings so that people can browse the repository from their browser too
  12.         <Directory "/var/packages">
  13.                 Options Indexes FollowSymLinks MultiViews
  14.                 DirectoryIndex index.html
  15.                 AllowOverride Options
  16.                 Order allow,deny
  17.                 allow from all
  18.         </Directory>
  19.  
  20.         # Hide the conf/ directory for all repositories
  21.         <Directory "/var/packages/*/conf">
  22.                 Order allow,deny
  23.                 Deny from all
  24.                 Satisfy all
  25.         </Directory>
  26.  
  27.         # Hide the db/ directory for all repositories
  28.         <Directory "/var/packages/*/db">
  29.                 Order allow,deny
  30.                 Deny from all
  31.                 Satisfy all
  32.         </Directory>
  33. </VirtualHost>

After this, it's a matter of restarting Apache and you should be able to access your repository from apt. Reprepro has many more functions than I have explained in this article. For example, you can use it to synchrionise with other APT repositories as well. Personally I don't have a need for that so I have not explored these features. I use my own APT repository primarily for distributions where my software cannot be added to the official repositories anymore. However, this article should give you more than enough information to manage your own repository for the software you write and/or package.

Creative Commons Attribution-ShareAlike

Comments

#1 Anonymous

Great! Thanks for this howto.

#2 Aussie

I have a quick question that is sort of related to this.

I look after a number of PCs for my home. (most of them are either Debian or Ubuntu). Is it the same steps to set up a private repository for my network?

What I want to do, is have one PC become a repository/server for all the PCs in my network. so instead of pulling packages or updates from the web all the time, I get them from a local server. (Thus, saving my monthly internet usage, as well as the Ubuntu server resources.)

#3 Sander Marechal (http://www.jejik.com)

Yes, you could do it that way. You could use reprepro to fetch all the packages from the central debian or ubuntu repository to your local server, then adjust the /etc/apt/sources.list on your clients to point to your local server instead.

I do vaguely remember reading about an easier way to do this with Debian. A way specifically designed for mirroring Debian's master archive, but I don't remember where I read that. I suggest you check the Debian sysadmin documentation or ask around on their mailing lists about that.

The upside about using reprepro for that is that you can easily modify and overwrite the upstream debian/ubuntu packages. You could for example decide to repackage software with support for mp3 or video drivers or other non-free things that Debian and Ubuntu cannot distribute normally.

#4 Anonymous Coward

How do you do to add source repository to be fully compiliant with GPL license?

#5 Sander Marechal (http://www.jejik.com)

As far as reprepro is concerned, a source repository is just another architecture. As you can see in the listing of my conf/distributions I have specified three archirectures: i386, amd64 and source. Source packages are added to the repository with the includedsc command instead of the includedeb command.

Reprepro then does all the magic by itself.

#6 The Beast

This is for Aussie. I have also been looking at setting up a local repository for my network. It looks like apt-proxy might be viable, but there are links to similar projects from that page. Good luck.

#7 Sander Marechal (http://www.jejik.com)

Thanks for that link The Beast. It looks really useful :-)

#8 mzilikazi

Another useful tool for mirroring an apt repo is approx:
apt-get install approx

Easy to configure too. Simply edit /etc/apt/approx.conf

#9 Anonymous Coward

I can never get the override files to kick in.

#10 Ajamison

Where is the repository meta data stored ? I ran the comman it succeded in adding packages but I did not realize i had to manually move the packages to the folder i wanted them in so i moved them and now the meta data fails how do i make it refresh the file location

#11 Sander Marechal (http://www.jejik.com)

Ajamison: On my system I did not have to move the packages manually. Reprepro copied them automatically for me to the correct location. Perhaps there is an error in your configuration?

As for the metadata, that is stored in the usual place for a package repository: Under the indices/ and dists/ directories in various files like Contents.gz and Release.

#12 Guillaume Yziquel (http://yziquel.homelinux.org/)

The SignWith setting you described doesn't deal with multiple gpg keys. I tried adding a key identifier, but I have trouble making it working.

There's also this ask-passphrase which is deprecated compared to gpg-agent. Again, still struggling to make it work.

Thanks a lot for this doc.

#13 Sander Marechal (http://www.jejik.com)

@Guillaume: The article was written over three years ago. It's no wonder some things have been deprecated in that time :-)

#14 Adrian Purser

I'm bit of a noob at debian package management. I'm trying to setup a repository that can host the same version of my app for various versions of ubuntu, hardy, jaunty and karmic. Is this possible or do I have to create a repository for each?

If I try to add the same version (but with a different deb package file) using different codenames I get the following error -

File "pool/non-free/i/imergescroll/imergescroll_1.0.7_i386.deb" is already registered with other md5sum!

Thanks.

#15 Sander Marechal (http://www.jejik.com)

Adrian, just make sure the package names are different. E.g:

imergescroll_1.0.7~hardy1_i386.deb
imergescroll_1.0.7~hardy2_i386.deb
imergescroll_1.0.7~jaunty1_i386.deb
imergescroll_1.0.7~karmic1_i386.deb

The 1.0.7 refers to the upstream version of the package. The ~hardy, ~karmic, etcetera point to the distribution version. The number after that is the package version. In the above example there are two imergescroll packages for Hardy, both based on the 1.0.7 upstream source code. This happens for example when the contents of the debian/ directory changes (e.g. a new control file, added dependencies, etcetera) but the program itself does not change.

#16 Adrian Purser

Thanks for your reply. I'm still having trouble and I think it's just down to my inexperience with this. I'm still getting the following error -

$ sudo reprepro -Vb . includedeb karmic incoming/imergescroll_1.0.7~karmic1_i386.deb
incoming/imergescroll_1.0.7~karmic1_i386.deb: component guessed as 'non-free'
File "pool/non-free/i/imergescroll/imergescroll_1.0.7_i386.deb" is already registered with other md5sum!
(file: '4397e99047dcee4e64b4328238bd68c8 84880', database:'28e6f5f0428c3b64e8f6e6daac362e26 84684')!
There have been errors!

Do I need to specify a different basedir for each distribution ? It seems to be stripping the codename from the filename when adding to the pool.

Thanks again for your help.

Regards

Adrian

#17 Sander Marechal (http://www.jejik.com)

It shouldn't do that. Did you just rename the .deb file or did you change the files in the debian/ directory and rebuild the package? You should do the latter since IIRC reprepro reads the version information and the like from the package itself, not the filename.

You shouldn't have to use different basedirs, but it is a valid workaround.

#18 Adrian Purser

That was it, that worked a treat. Thankyou very much.

Comments have been retired for this article.