Programster's Blog

Tutorials focusing on Linux, programming, and open-source

Set Up A Local Ubuntu / Debian Mirror with Apt-Mirror

For most users, setting apt to dynamically use the closest mirrors is enough as they are just running their one or two machines. However, if your premises has a terrible internet connection, or you are running lots of computers/servers, then you will want to set up a own mirror on your local network. This tutorial will set you up so that you have an ubuntu/debian mirror that is accessible through the web (http). You do not have to have your mirror accessible this way and FTP/NAS are good alternatives, but I chose http because it's really simple/easy.

You might want to combine this with my tutorial on how to set up a mirror for CentOS, which can be run on the same host.

There is currently a bug whereby Ubuntu 16.04 clients can only update from 16.04 mirrors due to the apt-mirror package still needing to be backported or some other solution. I recommend for now you use a 16.04 host for mirroring.

Part 1 - Set Up Apt Mirror

sudo apt-get install apt-mirror

Set up a cron job to run apt-mirror at a period of your choice by editing the cron file at /etc/cron.d/apt-mirror. This will be run as the apt-mirror user.

I set my mirror to run daily at midnight by adding the following line:

@daily /usr/bin/apt-mirror

Configure the mirror list at /etc/apt/mirror.list. Below is an example that will mirror both 64bit and 32 bit architectures since by default, apt-mirror will only mirror the same architecture as the host.

############# end config ##############
# copy below this line

# Ubuntu 20.04 mirroring.
deb focal main restricted universe multiverse
deb focal-security main restricted universe multiverse
deb focal-updates main restricted universe multiverse
deb focal-proposed main restricted universe multiverse
deb focal-backports main restricted universe multiverse

deb-src focal main restricted universe multiverse
deb-src focal-security main restricted universe multiverse
deb-src focal-updates main restricted universe multiverse
deb-src focal-proposed main restricted universe multiverse
deb-src focal-backports main restricted universe multiverse


I did try using (because I'm in the UK), but it kept failing to fetch the i386 packages

If you don't need this mirror to support net installations (e.g. just an update mirror instead), then you can remove all occurrences of the following texts: main/debian-installer and restricted/debian-installer

Debian Mirroring

If you are interested in setting up mirroring for Debian, then you could add the following.

# Debian 8 Jessie
deb jessie main contrib non-free
deb jessie main/debian-installer main contrib non-free
deb jessie-updates main contrib non-free

deb-src jessie main contrib non-free
deb-src jessie-updates main contrib non-free

# Debian 9 Stretch
deb stretch main contrib non-free
deb stretch main/debian-installer main contrib non-free
deb stretch-backports main contrib non-free
deb stretch-updates main contrib non-free
deb stretch-proposed-updates main contrib non-free

deb-src stretch main contrib non-free
deb-src stretch-backports main contrib non-free
deb-src stretch-updates main contrib non-free
deb-src stretch-proposed-updates main contrib non-free

# Debian 10 Buster
deb buster main contrib non-free
deb buster main/debian-installer main contrib non-free
deb buster-backports main contrib non-free
deb buster-updates main contrib non-free
deb buster-proposed-updates main contrib non-free

deb-src buster main contrib non-free
deb-src buster-backports main contrib non-free
deb-src buster-updates main contrib non-free
deb-src buster-proposed-updates main contrib non-free


Bandwidth Limiting

For your initial syncronization, you may want to implement banwidth limiting. To do this, edit the /etc/apt/mirror.list file and add the following lines within the config section.

#Bandwidth limiting. 
set limit_rate [number of Kilobytes]k
set nthreads     1

You will need to ensure that there is only one set nthreads line, and remember that the limit_rate is in kilobytes, not kilobits. 1 megabit is equal to 125 kilobytes.

Manually Running apt-mirror

If you wish to manually run the apt-mirror command, be sure to do it as the apt-mirror user.

sudo su apt-mirror

Otherwise, you will be shown the following error messages...

flock() on closed filehandle LOCK_FILE at /usr/bin/apt-mirror line 206.
apt-mirror is already running, exiting at /usr/bin/apt-mirror line 209.

... and be tempted to run it with sudo to resolve the issue. Unfortunately that will cause the files to be owned by root which will cause them to require being run by root in future, so be sure to use the apt-mirror user.

Part 2 - Set Up Apache Webserver

Install Apache to allow serving the mirrored files over http.

sudo apt-get install apache2

Run the following to configure apache

sudo echo '<VirtualHost *:80>

    DocumentRoot /var/www
        <Directory /var/www/>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted

    ErrorLog ${APACHE_LOG_DIR}/error.log

    # Possible values include: debug, info, notice, warn, error, crit,
    # alert, emerg.
    LogLevel warn

    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>' | sudo tee /etc/apache2/sites-enabled/000-default.conf

Create a symlink to the downloaded files in your apache www directory so that whenever someone navigates to the "website" they are automatically taken to the mirror files.

sudo ln -s /var/spool/apt-mirror/mirror/ /var/www/ubuntu
sudo chown www-data:www-data /var/www/ubuntu
sudo rm -rf /var/www/html
sudo service apache2 restart

Configure Clients

Once your mirror is up and running, you need to configure your other computers to use it for updates.


Last updated: 16th May 2022
First published: 16th August 2018