How to Setup Local APT Repository Server on Ubuntu 20.04

One of the reasons why you may consider setting up a local apt repository server is to minimize the bandwidth required if you have multiple instances of Ubuntu to update. Take for instance a situation where you have 20 or so servers that all need to be updated twice a week. You could save a great deal of bandwidth because all you need to do is to updates all your systems over a LAN from your local repository server.

In this guide, you will learn how to set up a local apt repository server on Ubuntu 20.04 LTS.

Prerequisites

  • Ubuntu 20.04 LTS system
  • Apache Web Server
  • Minimum of 170 GB free disk space on /var/www/html file system
  • Stable internet connection

Step 1) Create a local Apache Web Server

First off, log in to your Ubuntu 20.04 and set up the Apache web server as shown.

$ sudo apt install -y apache2

Enable Apache2 service so that it will be persistent across the reboot . Run following command

$ sudo systemctl enable apache2

Apache’s default document root directory is located in the /var/www/html path. We are later going to create a repository directory in this path that will contain the required packages needed.

Step 2) Create a package repository directory

Next, we will create a local repository directory called ubuntu in the /var/www/html path.

$ sudo mkdir -p /var/www/html/ubuntu

Set the required permissions on above created directory.

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

Step 3) Install apt-mirror

The next step is to install apt-mirror package, after installing this package we will get apt-mirror command or tool which will download and sync the remote debian packages to local repository on our server. So to install it, run following

$ sudo apt update
$ sudo apt install -y apt-mirror

Step 4) Configure repositories to mirror or sync

Once apt-mirror is installed then its configuration ‘/etc/apt/mirrror.list’ is created automatically. This file contains list of repositories that will be downloaded or sync in local folder of our Ubuntu server. In our case local folder is ‘/var/www/html/ubuntu/’. Before making changes to this file let’s backup first.

$ sudo cp /etc/apt/mirror.list /etc/apt/mirror.list-bak

Now edit the file using vi editor and update base_path and repositories as shown below.

$ sudo vi /etc/apt/mirror.list

############# config ###################
set base_path    /var/www/html/ubuntu
set nthreads     20
set _tilde 0
############# end config ##############
deb http://archive.ubuntu.com/ubuntu focal main restricted universe \
 multiverse
deb http://archive.ubuntu.com/ubuntu focal-security main restricted \
universe multiverse
deb http://archive.ubuntu.com/ubuntu focal-updates main restricted \
universe multiverse
clean http://archive.ubuntu.com/ubuntu

Save and exit the file.

APT-Mirror-List-File-Ubuntu-Server

In case you might have noticed that I have used Ubuntu 20.04 LTS package repositories and have comment out the src package repositories as I don’t have enough space on my system. If you wish to download or sync src packages too then uncomment the lines which starts with ‘deb-src’.

Step 5) Start mirroring the remote repositories to local folder

Before start mirroring or syncing, first the copy the postmirror.sh script to folder /var/www/html/ubuntu/var using below cp command.

$ sudo mkdir -p /var/www/html/ubuntu/var
$ sudo cp /var/spool/apt-mirror/var/postmirror.sh /var/www/html/ubuntu/var

Now, it’s time to start mirroring the packages from remote repositories to our system’s local folder. Execute below:

$ sudo apt-mirror

APT-Mirror-Command-Output-Ubuntu-Server

Above command can also be started in the background using below nohup command,

$ nohup sudo apt-mirror &

To monitor the mirroring progress use below,

$ tail nohup.out

In Ubuntu 20.04 LTS, apt-mirror does sync CNF directory and its files, so we have to manually download and copy the folder and its files. So to avoid manually downloading CNF directory, create a shell script with below contents,

$ vi cnf.sh
#!/bin/bash
for p in "${1:-focal}"{,-{security,updates}}\
/{main,restricted,universe,multiverse};do >&2 echo "${p}"
wget -q -c -r -np -R "index.html*"\
 "http://archive.ubuntu.com/ubuntu/dists/${p}/cnf/Commands-amd64.xz"
wget -q -c -r -np -R "index.html*"\
 "http://archive.ubuntu.com/ubuntu/dists/${p}/cnf/Commands-i386.xz"
done

save and close the script.

Execute the script to download CNF directory and its files.

$ chmod +x cnf.sh
$ bash  cnf.sh

This script will create a folder with name ‘archive.ubuntu.com’ in the present working directory. Copy this folder to mirror folder,

$ sudo cp -av archive.ubuntu.com  /var/www/html/ubuntu/mirror/

Note : If we don’t sync cnf directory then on client machines we will get following errors, so to resolve these errors we have to create and execute above script.

E: Failed to fetch http://x.x.x.x/ubuntu/mirror/archive.ubuntu.com/ubuntu/dists/\
focal/restricted/cnf/Commands-amd64  404  Not Found [IP:169.144.104.219 80]
E: Failed to fetch http://x.x.x.x/ubuntu/mirror/archive.ubuntu.com/ubuntu/dists/\
focal-updates/main/cnf/Commands-amd64  404  Not Found [IP:169.144.104.219 80]
E: Failed to fetch http://x.x.x.x/ubuntu/mirror/archive.ubuntu.com/ubuntu/dists/\
focal-security/main/cnf/Commands-amd64  404  Not Found [IP:169.144.104.219 80]

Scheduling Automatic Repositories Sync Up

Configure a cron job to automatically update our local apt repositories. It is recommended to setup this cron job in the night daily.

Run ‘crontab -e’ and add following command to be executed daily at 1:00 AM in the night.

$ sudo crontab -e

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

Save and close.

Note: In case Firewall is running on Ubuntu Server then allow port 80 using following command

$ sudo ufw allow 80

Step 6) Accessing Local APT repository via web browser

To Access our locally configured apt repository via web browser type the following URL:

http://<Server-IP>/ubuntu/mirror/archive.ubuntu.com/ubuntu/dists/

Local-Apt-Repository-Web-Ubuntu

Step 7) Configure Ubuntu 20.04 client to use local apt repository server

To test and verify whether our apt repository server is working fine or not, I have another Ubuntu 20.04 lts system where I will update /etc/apt/sources.list file so that apt command points to local repositories instead of remote.

So, login to the system, change the following in the sources.list

http://archive.ubuntu.com/ubuntu
to
http://169.144.104.219/ubuntu/mirror/archive.ubuntu.com/ubuntu

Here ‘169.144.104.219’ is the IP Address of my apt repository server, replace this ip address that suits to your environment.

Also make sure comment out all other repositories which are not mirrored on our apt repository server. So, after making the changes in sources.list file, it would look like below:

Ubuntu-Client-Sources-list

Now Run ‘apt update’ command to verify that client machine is getting update from our local apt repository server,

$ sudo apt update

Apt-Update-Ubuntu-Client

Perfect, above output confirms that client machine is successfully able to connect to our repository for fetching the packages and updates. That’s all from this article, I hope this guide helps you to setup local apt repository server on Ubuntu 20.04 system.

Also Read : 14 Useful ‘ls’ Command Examples in Linux

8 thoughts on “How to Setup Local APT Repository Server on Ubuntu 20.04”

  1. Nice tutorial, but I get an blocking error, when I have tried to apt update && apt upgrade in the first time.

    I have founded that you need to add [trusted=yes] after deb instances in your sources.list.
    Otherwise, you will have the following error :

    ‘https://askubuntu.com/questions/1087342/due-to-repository-has-no-release-file-errors-apt-get-update-failed-in-ubuntu’
    After that, apt update && apt upgrade has been running successfully 🙂

  2. Francis Ketterman

    How often do you need to rerun the cnf.sh script? And if you have multiple repositories you are mirroring do you need to run one for each? Also I am assuming that if you do not use the i386 architecture you do not need to include that line in your file?

    Thank you,

    1. Hi Francis,
      You would need to run cnf.sh script once. If you have multiple repositories for different versions of Ubuntu then you should execute this script.
      In case you are not creating repositories of 32-bit packages then you can comment out the line in script which is downloading 32-bit package

  3. Thank you for this guide.
    But the cnf.sh script does not download the required files when I run it.

    Not sure what I am doing wrong

Leave a Reply

Your email address will not be published. Required fields are marked *