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:
- Origin: Lone Wolves
- Label: Lone Wolves
- Codename: dapper
- Architectures: i386 amd64 source
- Components: main
- Description: Lone Wolves APT Repository
- SignWith: yes
- DebOverride: override.dapper
- 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:
- verbose
- ask-passphrase
- 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:
- gnome-hearts Priority optional
- 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:
- $ reprepro includedeb <codename> <debfile>
Or, for gnome-hearts:
- $ reprepro includedeb dapper ~/gnome-hearts_0.1.2-1_amd64.deb
- /home/sander/gnome-hearts_0.1.2-1_amd64.deb: component guessed as 'main'
- db: 'gnome-hearts' added to 'dapper|main|amd64'.
- Exporting indices...
- 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:
- $ reprepro -A amd64 list dapper gnome-hearts
- dapper|main|amd64: gnome-hearts 0.1.2-1
- $ reprepro -A amd64 remove dapper gnome-hearts
- removing 'gnome-hearts' from 'dapper|main|amd64'...
- db: 'gnome-hearts' removed from 'dapper|main|amd64'.
- Exporting indices...
- Successfully created './dists/dapper/Release.gpg.new'
- Deleting files no longer referenced...
- 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:
- ## Lone Wolves Ubuntu APT repository
- deb http://packages.jejik.com/ubuntu dapper main
- deb-src http://packages.jejik.com/ubuntu dapper main
- ## Lone Wolves Debian APT repository
- deb http://packages.jejik.com/debian stable main
- deb-src http://packages.jejik.com/debian stable main
Here is what the Apache configuration file looks like:
- <VirtualHost *>
- DocumentRoot /var/packages
- ServerName packages.jejik.com
- ErrorLog /var/log/apache2/error.log
- LogLevel warn
- CustomLog /var/log/apache2/access.log combined
- ServerSignature On
- # Allow directory listings so that people can browse the repository from their browser too
- <Directory "/var/packages">
- Options Indexes FollowSymLinks MultiViews
- DirectoryIndex index.html
- AllowOverride Options
- Order allow,deny
- allow from all
- </Directory>
- # Hide the conf/ directory for all repositories
- <Directory "/var/packages/*/conf">
- Order allow,deny
- Deny from all
- Satisfy all
- </Directory>
- # Hide the db/ directory for all repositories
- <Directory "/var/packages/*/db">
- Order allow,deny
- Deny from all
- Satisfy all
- </Directory>
- </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.
Comments
#1 Anonymous
#2 Aussie
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)
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
#5 Sander Marechal (http://www.jejik.com)
Reprepro then does all the magic by itself.
#6 The Beast
#7 Sander Marechal (http://www.jejik.com)
#8 mzilikazi
apt-get install approx
Easy to configure too. Simply edit /etc/apt/approx.conf
#9 Anonymous Coward
#10 Ajamison
#11 Sander Marechal (http://www.jejik.com)
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/)
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)
#14 Adrian Purser
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)
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
$ 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)
You shouldn't have to use different basedirs, but it is a valid workaround.
#18 Adrian Purser
Comments have been retired for this article.