Howto Setup a Private Package Repository with reprepro and nginx
As the number of servers I am responsible for grows, I have been trying to eliminate all non packaged software in production. Although ubuntu and Debian have massive software repositories, there are some things which just aren't available yet or are internal meta packages. Once the packages are built they need to be deployed to servers. The simplest way to do this is to run a private apt repository. There are a few options for building an apt repository, but the most popular and simplest seems to be reprepro. I used Sander Marechal and Lionel Porcheron's reprepro howtos as a basis for getting my repository up and running.
nginx is a lightweight http server (and reverse proxy). It performs very well serving static files, which is perfect for a package repository. I also wanted to minimise the memory footprint of the server, which made nginx appealing.
To install the packages we need, run the following command:
$ sudo apt-get install reprepro nginx
Then it is time to configure reprepro. First we create our directory structure:
$ sudo mkdir -p /srv/reprepro/ubuntu/{conf,dists,incoming,indices,logs,pool,project,tmp}
$ cd /srv/reprepro/ubuntu/
$ sudo chown -R `whoami` . # changes the repository owner to the current userNow we need to create some configuration files.
/srv/reprepro/ubuntu/conf/distributions
Origin: Your Name Label: Your repository name Codename: karmic Architectures: i386 amd64 source Components: main Description: Description of repository you are creating SignWith: YOUR-KEY-ID
/srv/reprepro/ubuntu/conf/options
ask-passphrase basedir .
If you have a package ready to load, add it using the following command:
$ reprepro includedeb karmic /path/to/my-package_0.1-1.deb \ # change /path/to/my-package_0.1-1.deb to the path to your package
Once reprepro is setup and you have some packages loaded, you need to make it so you can serve the files over http. I run an internal dns zone called "internal" and so the package server will be configured to respond to packages.internal. You may need to change the server_name value to match your own environment. Create a file called
/etc/nginx/sites-available/vhost-packages.confwith the following content:
server {
listen 80;
server_name packages.internal;
access_log /var/log/nginx/packages-access.log;
error_log /var/log/nginx/packages-error.log;
location / {
root /srv/reprepro;
index index.html;
}
location ~ /(.*)/conf {
deny all;
}
location ~ /(.*)/db {
deny all;
}
}Next we need to increase the server_names_hash_bucket_size. Create a file called
/etc/nginx/conf.d/server_names_hash_bucket_size.confwhich should just contain the following line:
server_names_hash_bucket_size 64;
Note: Many sites advocate sticking this value in the http section of the
/etc/nginx/nginx.conf configfile, but in Debian and Ubuntu
/etc/nginx/conf.d/*.confis included in the http section. I think my method is cleaner for upgrading and clearly delineates the stock and custom configuration.
To enable and activate the new virtual host run the following commands:
$ cd /etc/nginx/sites-enabled $ sudo ln -s ../sites-available/packages.internal.conf . $ sudo service nginx reload
You should get some output that looks like this
Reloading nginx configuration: the configuration file /etc/nginx/nginx.conf syntax is ok configuration file /etc/nginx/nginx.conf test is successful nginx.
Now you can add the new repository to your machines. I recommend creating a file called
/etc/apt/sources.list.d/packages.internal.listand put the following line in the file:
deb http://packages.internal/ubuntu/ karmic main
To make the machine aware of the new repository and associated packages, simply run:
$ sudo apt-get update
That's it. Now you have a lightweight package repository with a lightweight webserver - perfect for running in a virtual machine. Depending on your setup you could probably get away with using 256Mb of RAM and a few gig of disk.

RSS Feed
Hey Dave, Good concise
Anonymous wrote:Hey Dave,
Good concise howto.
I have a similar setup at work also using approx on the same machine though to proxy the standard ubuntu repos too.
apache2 proxies to approx running on port 81 for /ubuntu
My sources list is then just:
deb http://apt/ubuntu karmic main deb http://apt/ubuntu karmic-updates main deb http://apt/ubuntu karmic-security main deb http://apt/internal karmic main
Thanks for the handy reference!
Alan S. Rojer wrote:You might consider fixing a typo in vhost-packages.conf: access_log should be /var/log/nginx/packages-access.log (or similar); as configured, both logs are going to the error.log. E.g.:
access_log /var/log/nginx/packages-access.log;In my adaptation, I ditched the sites-available/enabled vhost thingy, avoiding complicating symlinks, and just dropped the conf-file in /etc/nginx/conf.d (it's under puppet control so the vhost symlink thing seems sort of redundant). Many thanks!
RE: Thanks for the handy reference!
Dave wrote:Alan, thanks for noticing the error. I've updated the post.
Why increase
Dominic wrote:Why increase 'server_names_hash_bucket_size'? That seems to be something you'd do if you had a very long server name (it doesn't increase the maximum number of buckets, just their size).
But in the example above the server name is only 18 characters long, and the default bucket size is something like 32.
Is this something you actually "need" to do, or is it a superstition, copied from config to config?
Bucket Sizes
Dave wrote:I can't remember what the problem was I was having back when I wrote this, but increasing the server_names_hash_bucket_size to 64 fixed it.
Post new comment