How to create a Ubuntu repository server

This guide will show how to configure a local repository server based on Ubuntu Bionic, but it can be adapted to a previous version of Ubuntu or even to any distribution using Aptitude as the main package management system, like Debian or Mint. You might typically want to setup a local repository to save Internet bandwidth.

In this tutorial you will learn:

  • How to install the required software on the server
  • How to select which repositories to mirror on the server
  • How to mirror selecting repositories locally on the server
  • How to configure the Linux client to use the local repository server

As stated above we are not considering a public or country mirror for this tutorial, but if you want to implement it consider that:

  • Your network bandwidth becomes very important
  • You need to register the repository to the Ubuntu list of mirrors
  • You must sync the mirror at least four times a day
  • Because you must mirror all previous versions you might need 2 TB or more of disk space


Updating packages list from the local repos.

Updating packages list from the local repos.

Software Requirements and Conventions Used

Software Requirements and Linux Command Line Conventions
Category Requirements, Conventions or Software Version Used
System Ubuntu 18.04.2 (Bionic Beaver) LTS
Software Apache http 2.x, apt-mirror
Other Privileged access to your Linux system as root or via the sudo command, Minimum 200 GB of disk space for the repository
Conventions # – requires given linux commands to be executed with root privileges either directly as a root user or by use of sudo command
$ – requires given linux commands to be executed as a regular non-privileged user

How to create a Ubuntu repository server step by step

  1. Installing the required software on the server.

    As a first step we need to install the Apache HTTP Server which is under the package named apache2, with the command:

    $ sudo apt install apache2


    Installing Apache HTTP

    Installing Apache HTTP

    Then make sure the service runs at startup:

    $ sudo systemctl enable apache2
    

    If everything is fine we will move to the default DocumentRoot Directory (which is /var/www/html).
    There we can then create the sub-directory /var/www/html/ubuntu and assign it to the appropriate owner, in this case www-data ( the user under which Apache HTTP runs ).

    $ sudo mkdir -p /var/www/html/ubuntu
    $ sudo chown www-data:www-data /var/www/html/ubuntu
    

    It is strongly recommended that the DocumentRoot or at least the ubuntu subfolder is on a filesystem belonging to a logical volume; this way we can enlarge it online, with no downtime.
    At the time of my testing 171.5 GiB are the absolute minimum space needed if also mirroring the src packages; so to plan for the future it is recommended to have at least 300 GiB of disk space.

    This is mainly an estimation if choosing one version of Ubuntu; if it is needed to mirror packages for different versions the space requirements will increase considerably.

  2. The main tool that allows us to create a local repository is apt-mirror, to install it execute:

    $ sudo apt install apt-mirror
    

    In case the package is not found make sure to refresh the packages list first with:

    $ sudo apt update
    
  3. Selecting which repositories to mirror on the server.

    Once apt-mirror is installed we can make a backup copy of its configuration file /etc/apt/mirror.list, after that you make sure the line containing the option set base_path points to the correct path for our repository (by default is /var/spool/apt-mirror ).

    $ sudo cp /etc/apt/mirror.list /etc/apt/mirror.list.org
    

    So you can now use your favorite editor (vi or nano for instance) to change the base_path option in the mirror.list file to /var/www/html/ubuntu; you need also to specify you are mirroring the bionic distro (change accordingly if you have a different Ubuntu version) repos, always in the mirror.list configuration file.

    mirror.list config file

    mirror.list config file

    In case you don’t have much space on disk you can choose to not mirror src packages; so you will comment the relative lines:

    mirror.list config file

    mirror.list config file



    Next you copy an important script into /var/www/html/ubuntu/var/

    $ sudo mkdir -p /var/www/html/ubuntu/var 
    $ sudo cp /var/spool/apt-mirror/var/postmirror.sh /var/www/html/ubuntu/var/
    
  4. Mirroring the selected repositories locally on the server.

    Now is time to create a local mirror, keep in mind that an initial mirroring (from archive.ubuntu.com only for this tutorial) can take a lot of time and slow down your connection so I would suggest you start this job at night.
    To start mirroring the remote repos packages to the local server simply execute the command:

    $ sudo apt-mirror
    

    If you need to, you can interrupt this process ( with the classic CTRL+C combo ) and restart it later; it will resume from where was left.

    Eventually we will get to the point when the clean.sh and postmirror.sh scripts are executed, it is a sign the mirroring process has been completed.

    End of mirroring process.

    End of mirroring process.

  5. Configuring automatic sync process by using cron scheduler.

    After our first sync is completed we need to create a cron job to make sure that we have an automatic up to date local repository; for instance we want this task to run every night at 2:00 AM and therefore:

    $ sudo crontab -e
    

    Then we edit the crontab to add the following line:

    00 	02 	*	 *	 *	/usr/bin/apt-mirror
    

    And save and exit (using vi, nano or whatever editor is set).

Configuring the Linux client to use the local repository server

  1. Configuring the local repository list.

    In any client which is going to use our local repository we need to edit the configuration file /etc/apt/sources.list specifying our local repo and disabling any remote one.

    In our case the following repositories have been downloaded:

    Server local repositories

    Server local repositories



    NOTE

    It is recommended to comment any line in the /etc/apt/sources.list file referring to repositories not mirrored in our server, for instance, in this case, any line starting with deb-src and containing bionic-backports have been commented.

    If you don’t do that you might get the error
    Release file has not been found when running the command apt update on the client.

    First of all we replace any string archive.ubuntu.com with our local mirror IP, in this case 10.0.0.42. Of course your local IP address could be different.

    $ sudo  sed -i.bak0 "s/archive\.ubuntu\.com/10\.0\.0\.\42/g" /etc/apt/sources.list
    

    This command will create the backup file /etc/apt/sources.list.bak0 and replace any archive.ubuntu.com string with 10.0.0.42.

    A further adjustment is running again sed in this way:

    $ sudo  sed -i.bak1 "s/ubuntu/ubuntu\/mirror\/archive\.ubuntu\.com\/ubuntu/g" \ /etc/apt/sources.list
    

    This is necessary as apt-mirror appends the path mirror/archive.ubuntu.com/ubuntu to our base path. Here it will be created a further backup file

    /etc/apt/sources.list.bak1.
    

    For the purpose of this tutorial we are only mirroring packages or repositories from archive.ubuntu.com; of course you can add other unofficial repositories in the mirror.list file in the server, but then you have to re-run apt-mirror there and edit on any client the sources.list file accordingly.

  2. Update local repository index.
    Now you need to make sure the port 80 is not blocked by the client firewall and then you can run:

    $ sudo apt update
    

    And you are ready to go.

    Updating packages list from the local repos.

    Updating packages list from the local repos.

Conclusion

Setting up a local repository in Ubuntu is not difficult as it might seem and it can come handy provided you have adequate local network and disk resources.