Deploy a local repository for Ubuntu VMs to save internet traffic and speed up the entire process.

This guide will show how to configure a local repository server based on Ubuntu 20.04 LTS, 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. We might typically want to setup a local repository to save Internet bandwidth and faster package installation without internet connectivity.

Prerequisites:

  • Ubuntu 20.04 LTS system.
  • Apache Web Server.
  • Minimum of 350 GB free disk space on /var/www/html file system
  • Stable internet connection.
  • Minimum of 4 cores and 8GB RAM.

Checklist for tasks:

  • [x] - Create a VM with required resources. Set hostname and IP.
  • [x] - Create a local Apache Web Server
  • [x] - Create a package repository directory
  • [x] - Install apt-mirror
  • [x] - Configure repositories to mirror or sync
  • [x] - Start mirroring the remote repositories to local folder
  • [x] - Scheduling Automatic Repositories Sync Up
  • [x] - Update the local DNS with hostname.
  • [x] - Accessing Local APT repository via web browser
  • [x] - Configure Ubuntu 20.04 client to use local apt repository server.

Create a VM with required resources. Set hostname and IP

We have created a VM on our test Proxmox (172.16.7.41). Resource details are below.

  • OS: Ubuntu 20.04 LTS server version.
  • RAM: 8GB
  • CPU: 4 CPU
  • HDD: 400GB
  • IP: 172.16.7.199, Gateway: 172.16.4.1, DNS1: 172.16.4.1, DNS2: 8.8.8.8

After setup the VM need to edit the /etc/apt/sources.list file with below contains.

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

Set hostname for this VM

hostnamectl set-hostname ubuntu_repo.cellosco.pe

Sync the VM time with local timezone.

timedatectl list-timezones | grep Dhaka
timedatectl set-timezone Asia/Dhaka

Create a local Apache Web Server

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

apt install -y apache2

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

systemctl enable apache2

Restart Apache2 service

systemctl restart apache2

Enable UFW and allow http service

ufw allow 80
ufw enable
ufw reoload
systemctl enable ufw
systemctl restart ufw

Create a package repository directory

We will create a local repository directory called ubuntu in the /var/www/html path

mkdir -p /var/www/html/ubuntu

Set the required permissions on above created directory.

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

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.

apt install -y apt-mirror

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.

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

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

vim /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

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 copy command.

mkdir -p /var/www/html/ubuntu/var
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:

apt-mirror

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

vim 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

Execute the script to download CNF directory and its files.

chmod 777 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.

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

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 morning daily.

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

crontab -e

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

Update the local DNS with hostname

Update the static dns on Mikrotik router (172.16.4.1)

[nazmul@MikroTik-Core] > ip dns static print where address=172.16.7.199
Flags: D - dynamic, X - disabled 
 #    NAME                          REGEXP                          TYPE     ADDRESS                                                          TTL         
 0    ubuntu_repo.cellosco.pe                                                172.16.7.199                                                     1d

Accessing Local APT repository via web browser

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

http://ubuntu_repo.cellosco.pe/ubuntu/mirror/archive.ubuntu.com/ubuntu/dists/

image

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.

vim /etc/apt/sources.list

deb http://ubuntu_repo.cellosco.pe/ubuntu/mirror/archive.ubuntu.com/ubuntu focal main restricted
deb http://ubuntu_repo.cellosco.pe/ubuntu/mirror/archive.ubuntu.com/ubuntu focal-updates main restricted
deb http://ubuntu_repo.cellosco.pe/ubuntu/mirror/archive.ubuntu.com/ubuntu focal universe
deb http://ubuntu_repo.cellosco.pe/ubuntu/mirror/archive.ubuntu.com/ubuntu focal-updates universe
deb http://ubuntu_repo.cellosco.pe/ubuntu/mirror/archive.ubuntu.com/ubuntu focal multiverse
deb http://ubuntu_repo.cellosco.pe/ubuntu/mirror/archive.ubuntu.com/ubuntu focal-updates multiverse
#deb http://ubuntu_repo.cellosco.pe/ubuntu/mirror/archive.ubuntu.com/ubuntu focal-backports main restricted universe multiverse
deb http://ubuntu_repo.cellosco.pe/ubuntu/mirror/archive.ubuntu.com/ubuntu focal-security main restricted
deb http://ubuntu_repo.cellosco.pe/ubuntu/mirror/archive.ubuntu.com/ubuntu focal-security universe
deb http://ubuntu_repo.cellosco.pe/ubuntu/mirror/archive.ubuntu.com/ubuntu focal-security multiverse