How to setup an offline Ubuntu repository on an Ubuntu machine not connected to the internet

peerchemist
3 min readApr 14, 2023

--

The following procedure is useful if you have an airgapped device which is not connected to the internet and you would like to update it or simply to install something new from the repository. It is also useful on fresh installs if you have limited network connectivity or it is simply slow.

In the tutorial I am working with repository for Ubuntu Kinetic and I am using riscv64 architecture, however this tutorial will work for all modern Ubuntu releases and all officially supported architectures.

The first tool requried is aptly.

Aptly is avaliable in the Ubuntu repository:

sudo apt install aptly

Configuration

Save the configuration file in $HOME/.aptly.conf .

This example configuration file I am using is using the riscv64 architecture. Use the architecture you require, presumably amd64. I have disabled the GPG check because it is not required and makes all of this much harder to configure.

{
"rootDir": "/home/$USER/.aptly",
"downloadConcurrency": 16,
"downloadSpeedLimit": 0,
"architectures": ["riscv64"],
"dependencyFollowSuggests": false,
"dependencyFollowRecommends": false,
"dependencyFollowAllVariants": false,
"dependencyFollowSource": false,
"dependencyVerboseResolve": false,
"gpgDisableSign": true,
"gpgDisableVerify": true,
"gpgProvider": "gpg",
"downloadSourcePackages": false,
"skipLegacyPool": true,
"ppaDistributorID": "ubuntu",
"ppaCodename": "",
"skipContentsPublishing": false,
"FileSystemPublishEndpoints": {},
"S3PublishEndpoints": {},
"SwiftPublishEndpoints": {}
}

Download the repository

Downloading is done with “aptly mirror update” command. The main repository will take about 5.5GB of data, while whole repository (universe multiverse, …) will take over 80GB. In this example I am only downloading the main repository which containes basics like build-essentials and dkms.

aptly mirror create ubuntu-kinetic http://ports.ubuntu.com/ubuntu-ports/ kinetic main
aptly mirror update ubuntu-kinetic

Now this data needs to be made into something useful:

aptly snapshot create localrepo from mirror ubuntu-kinetic
aptly publish snapshot -distribution kinetic -architectures="riscv64" localrepo

This will create public directory you can use as local repo. The public directory will look like this:

.
├── dists
│ └── kinetic
│ ├── Contents-riscv64.gz
│ ├── main
│ │ ├── binary-riscv64
│ │ │ ├── Packages
│ │ │ ├── Packages.bz2
│ │ │ ├── Packages.gz
│ │ │ └── Release
│ │ └── Contents-riscv64.gz
│ └── Release
└── pool
└── main
├── a
│ ├── aalib
│ │ ├── libaa1_1.4p5-50build1_riscv64.deb
│ │ └── libaa1-dev_1.4p5-50build1_riscv64.deb
│ ├── abseil
│ │ ├── libabsl20210324_0~20210324.2-4ubuntu1_riscv64.deb
│ │ └── libabsl-dev_0~20210324.2-4ubuntu1_riscv64.deb
│ ├── accountsservice
│ │ ├── accountsservice_22.08.8-1ubuntu1_riscv64.deb
│ │ ├── gir1.2-accountsservice-1.0_22.08.8-1ubuntu1_riscv64.deb
│ │ ├── libaccountsservice0_22.08.8-1ubuntu1_riscv64.deb
│ │ ├── libaccountsservice-dev_22.08.8-1ubuntu1_riscv64.deb
│ │ └── libaccountsservice-doc_22.08.8-1ubuntu1_all.deb
│ ├── acct
│ │ └── acct_6.6.4-5_riscv64.deb
│ ├── acl
│ │ ├── acl_2.3.1-1_riscv64.deb
│ │ ├── libacl1_2.3.1-1_riscv64.deb
│ │ └── libacl1-dev_2.3.1-1_riscv64.deb
│ ├── acpid
│ │ └── acpid_2.0.33-2ubuntu1_riscv64.deb
│ ├── adcli
│ │ └── adcli_0.9.1-1ubuntu2_riscv64.deb
│ ├── adduser
│ │ └── adduser_3.121ubuntu1_all.deb
│ ├── adsys
│ │ └── adsys_0.9.2_riscv64.deb
│ ├── advancecomp
│ │ └── advancecomp_2.3-1_riscv64.deb
│ ├── adwaita-icon-theme
│ │ └── adwaita-icon-theme_41.0-1ubuntu1_all.deb
...

Move the public directory to a ext4-formatted USB drive and mount it to /media/repo.

Add the local repository in your sources list

Backup the old sources.list file:

sudo mv /etc/apt/sources.list /etc/apt/sources.list.old

Then make new sources.list:

deb [Trusted=yes] file:///media/repo SuiteCodename main restricted universe multiverse 

Where:

  • SuiteCodename is jammy, kinetic, focal, bionic …
  • You can include some or all the components ( main, multiverse, restricted, universe).
  • [Trusted=yes] makes it skip the GPG check, which is needed because there are no signatures.

apt-get away

Try “sudo apt-get update” to see if apt understands the local repository. If all goes well, you can now use the local repository and make system updates.

--

--

peerchemist
peerchemist

Written by peerchemist

Free thinker. Armchair analyst. Peercoin project Lead.

No responses yet