A computer engineer poking at your cerebral cortex.

Creating local ubuntu mirror for speed and better patch management



If you are like me I am creating new ubuntu server instances all the time. Most of the time I'm using LXC containers on my laptop and testing new software for production and development use. The first thing any sys admin will do is run updates and start installing software. The problem with this is each time you start running updates and installing softawre it depends on the speed of your internet plus the speed of the ubuntu mirror. I do this so often I getting tired of waiting. Even if you do have super fast internet but work at an orginzation that has tons of ubuntu server/desktops this is so nice because it reduces load on your internet pipe while people are running updates and installing software. Whether you have 10 machines or thousands having a local ubuntu mirror is so useful.

My check list for the mirror:
* raspberry pi (You can use any extra machine)
* external hard drive with at least 200GB of free space
* network cable
* internet

You can use either debian or ubuntu to create a local mirror. The first thing you want to do is assign a static IP to your new mirror. Edit your /etc/network/interfaces file and modify as needed:
auto lo eth0
iface lo inet loopback
iface eth0 inet static
	address 192.168.1.101
	netmask 255.255.255.0
	gateway 192.168.1.1

Next thing you want to do is install a package called apt-mirror.
sudo apt-get install apt-mirror

Now you want to mount your giant external hard drive. If your hard drive isn't already formatted for ext4 with fdisk you should search google on how to do this. Lets mount the external hard drive over the current apt-mirror directory.
sudo mount /dev/sdb1 /var/spool/apt-mirror

Now we need to create some directories for the mirror to work correcty.
cd var/spool/apt-mirror
mkdir mirror skel var

Now we need to tell debian/ubuntu what we want to mirror. Edit the /etc/apt/mirror.list file
############# config ##################
#
# set base_path    /var/spool/apt-mirror
#
# set mirror_path  $base_path/mirror
# set skel_path    $base_path/skel
# set var_path     $base_path/var
# set cleanscript $var_path/clean.sh
# set defaultarch  <running host architecture>
# set postmirror_script $var_path/postmirror.sh
# set run_postmirror 0
set nthreads     10
set _tilde 0
#
############# end config ##############

deb-amd64 http://us.archive.ubuntu.com/ubuntu precise main restricted universe multiverse
deb-amd64 http://us.archive.ubuntu.com/ubuntu precise-updates main restricted universe multiverse
deb-amd64 http://us.archive.ubuntu.com/ubuntu precise-security main restricted universe multiverse

deb-i386 http://us.archive.ubuntu.com/ubuntu precise main restricted universe multiverse
deb-i386 http://us.archive.ubuntu.com/ubuntu precise-updates main restricted universe multiverse
deb-i386 http://us.archive.ubuntu.com/ubuntu precise-security main restricted universe multiverse

#deb-src http://us.archive.ubuntu.com/ubuntu precise main restricted universe multiverse
#deb-src http://us.archive.ubuntu.com/ubuntu precise-updates main restricted universe multiverse
#deb-src http://us.archive.ubuntu.com/ubuntu precise-security main restricted universe multiverse

clean http://us.archive.ubuntu.com/ubuntu

Next thing you want to do is clone the mirror. This will take hours/days the first time depending on your connection.
/usr/bin/apt-mirror

Once the first mirror is completed there is a file called postmirror.sh located in the /var/spool/apt-mirror/var/ directory. Lets make it executable so we can run it after the install. This fill will contain all the packages that are out of date.
chmod +x /var/spool/apt-mirror/var/postmirror.sh

Now that you have a local mirror on your external drive there are a few more steps. First thing we want to do is schedule it on cron to run in the middle of the night. I run the cleanup script before I mirror the mirrors because I don't really know how long it will take. Seems to work fine this way.
crontab -e
0 3 * * * /var/spool/apt-mirror/var/postmirror.sh
0 4 * * * /usr/bin/apt-mirror

Now that we have the mirror running by itself lets expose the ubuntu mirror with a web server.
sudo apt-get install apache2

now lets make a symlink to the ubuntu mirror on our external drive.
sudo cd /var/www/
sudo ln -s /var/spool/apt-mirror/mirror/us.archive.ubuntu.com/ubuntu/ /var/www/ubuntu

The installation of the local mirror is now completed. Now its time to configure the client and some DNS stuff. If you have access to a DNS servers or DNS A host records I recommend creating a DNS entry to your local mirror. Say you own the domain name domain.com. I recommend pointing ubuntuMirror.domain.com at your local IP of your ubuntu mirror (in this case its 192.168.1.101). This is an optional step but if you have a giant organization I recommend doing this step. Then if your mirror fails or you need to change the IP address you can adjust 1 DNS record and all your servers are then pointed at the new mirror.

Client setup:
Now we need to point our servers/clients at the new mirror. Edit file /etc/apt/sources.list Now put your DNS name into the file instead of the current one.
deb http://ubuntuMirror.domain.com/ubuntu precise main restricted universe multiverse
deb http://ubuntuMirror.domain.com/ubuntu precise-updates main restricted universe multiverse
deb http://ubuntuMirror.domain.com/ubuntu  precise-security main restricted universe multiverse

You can also do an IP if you didn't do the DNS step.
deb http://192.168.1.101/ubuntu precise main restricted universe multiverse
deb http://192.168.1.101/ubuntu precise-updates main restricted universe multiverse
deb http://192.168.1.101/ubuntu  precise-security main restricted universe multiverse

Now try and run updates and install some packages. You should see everything being pulled from the local ubuntu mirror.
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install vim

Installation completed. You now have your server pointed at your local mirror and can run updates at any time off the local network.

Some extra notes.
I am only mirroring ubuntu 12.04 64 bit and 32 bit versions. Right now that is taking up 173G. You can mirror any number of versions and even mirror debian based mirrors. The only contraint is hard drive space. Many people will also say why don't you just use apt proxy. This is another option but I can't tell you the number of times I needed new packages that I didn't know about and I just prefer to have everything on the local lan. This is especially true for dekstop versions of ubuntu when some packages have tons of dependencies.

Further notes about production patch management.
One of the questions I always ask on interviews is how ubuntu/debian based system administrators handle patch management. The ubuntu mirror creates an indispensable feature. I create a 2nd mirror off the primary mirror and this stays static. I update stage environments and everything runs through QA. If QA approves all the patches and everything is working correctly I then patch production. Then I update the mirror and repeat. This way you don't have software version mismatches if you are creating new servers. It also gives time for QA to test everything and have a full proof mirror you know works with your current software.

Comments and recommendations are welcome. Thanks for reading.