How to create a local APT repository?
From the Ubuntu Help wiki:
There are 4 steps to setting up a simple repository for yourself
1.Install
dpkg-dev
2.Put the packages in a directory
3.Create a script that will scan the packages and create a file apt-get update can read
4. Add a line to your sources.list pointing at your repositoryInstall dpkg-dev
Type in a terminal
sudo apt-get install dpkg-dev
The Directory
Create a directory where you will keep your packages. For this example, we'll use
/usr/local/mydebs.
sudo mkdir -p /usr/local/mydebs
Now move your packages into the directory you've just created.
Previously downloaded Packages are generally stored on your system in the
/var/cache/apt/archives
directory. If you have installed apt-cacher you will have additional packages stored in its /packages directory.The Script update-mydebs
It's a simple three liner:
#! /bin/bash cd /usr/local/mydebs dpkg-scanpackages . /dev/null | gzip -9c > Packages.gz
Cut and paste the above into gedit, and save it as update-mydebs in ~/bin. (the tilde '~' means your home directory. If ~/bin does not exist, create it: Ubuntu will put that directory in your PATH. It's a good place to put personal scripts). Next, make the script executable:
chmod u+x ~/bin/update-mydebs How the script works:
dpkg-scanpackages looks at all the packages in mydebs, and the output is compressed and written to a file (Packages.gz) that apt-get update can read (see below for a reference that explains this in excruciating detail). /dev/null is an empty file; it is a substitute for an override file which holds some additional information about the packages, which in this case is not really needed. See deb-override(5) if you want to know about it.
Sources.list
add the line
deb file:/usr/local/mydebs ./
to your /etc/apt/sources.list, and you're done.
CD Option
You can burn the directory containing the debs to a CD and use that as a repository as well (good for sharing between computers). To use the CD as a repository, simply run
sudo apt-cdrom add
Using the Repository
Whenever you put a new deb in the mydebs directory, run
sudo update-mydebs sudo apt-get update
Now your local packages can be manipulated with Synaptic, aptitude and the apt commands: apt-get, apt-cache, etc. When you attempt to apt-get install, any dependencies will be resolved for you, as long as they can be met.
Badly made packages will probably fail, but you won't have endured dpkg hell.
*To make an offline Repository Over LAN *
Install a Local Apache Webserver
# apt-get install apache2
By default, Debian's Apache package will set up a website under /var/www
on your system. For our purposes, that's fine, so there's no reason to do anything more. You can easily test it by pointing your favorite browser at http://localhost
You should see the default post-installation web page which is actually stored in /var/www/index.html
Create a Debian Package Repository Directory
chose to create a directory /var/www/debs
for this. Under it, you should create "architecture" directories, one for each architecture you need to support. If you're using just one computer (or type of computer), then you'll only need one -- typically "i386" for 32-bit systems or "amd64" for 64 bit. If you are using some other architecture, I'll assume you probably already know about this.
Now just copy the ".deb" package files for a given architecture into the appropriate directories. If you now point your favorite web browser at http://localhost/debs/amd64
(for example) you'll see a listing of the packages for 64 bit systems.
Create a Packages.gz file
Now we need to create a catalog file for APT to use. This is done with a utility called "dpkg-scanpackages". Here's the commands I use to update the AMD64 packages on my LAN:
# cd /var/www/debs/
# dpkg-scanpackages amd64 | gzip -9c > amd64/Packages.gz
Make the repository known to APT
Now the only thing left to do is to let APT know about your repository. You do this by updating your /etc/apt/sources.list file. You'll need an entry like this one:
deb http://localhost/debs/ amd64/
I used the actual hostname of my system instead of localhost -- this way the code is the same for all of the computers on my LAN, but localhost will do just fine if you are running just one computer.
Now, update APT:
# apt-get update
Creating an Authenticated Repository
I've had a look at the answers here and on other sites and most have the (IMHO big) disadvantage that you're setting up an unauthenticated repository. This means you need to run apt-get
with --allow-unauthenticated
to install packages from it. This can be a security risk, especially in scripts where the packages you're installing might not all be from your local repository.
Note that I haven't covered here how to make it available over the LAN, but that's fairly generic config using Apache or nginx (see the other answers here).
Setup the repo directory
mkdir /home/srv/packages/local-xenial
cd /home/srv/packages/local-xenial
Then add a line like this to sources.list
:
deb file:/home/srv/packages/local-xenial/ ./
Adding and Removing Packages
remove packages
rm /home/srv/packages/local-xenial/some_package_idont_like
add packages
cp /some/dir/apackage.deb /home/srv/packages/local-xenial
now run the following script which generates the Packages, Release and InRelease files and signs them with your gpg private key:
#!/bin/bash
if [ -z "$1" ]; then
echo -e "usage: `basename $0` DISTRO
where DISTRO is the Ubuntu version codename (e.g. 14.04 is trusty)\n
The way to use this script is to do the changes to the repo first, i.e. delete or copy in the .deb file to /srv/packages/local-DISTRO, and then run this script\n
This script can be run as an unprivileged user - root is not needed so long as your user can write to the local repository directory"
else
cd /srv/packages/local-"$1"
# Generate the Packages file
dpkg-scanpackages . /dev/null > Packages
gzip --keep --force -9 Packages
# Generate the Release file
cat conf/distributions > Release
# The Date: field has the same format as the Debian package changelog entries,
# that is, RFC 2822 with time zone +0000
echo -e "Date: `LANG=C date -Ru`" >> Release
# Release must contain MD5 sums of all repository files (in a simple repo just the Packages and Packages.gz files)
echo -e 'MD5Sum:' >> Release
printf ' '$(md5sum Packages.gz | cut --delimiter=' ' --fields=1)' %16d Packages.gz' $(wc --bytes Packages.gz | cut --delimiter=' ' --fields=1) >> Release
printf '\n '$(md5sum Packages | cut --delimiter=' ' --fields=1)' %16d Packages' $(wc --bytes Packages | cut --delimiter=' ' --fields=1) >> Release
# Release must contain SHA256 sums of all repository files (in a simple repo just the Packages and Packages.gz files)
echo -e '\nSHA256:' >> Release
printf ' '$(sha256sum Packages.gz | cut --delimiter=' ' --fields=1)' %16d Packages.gz' $(wc --bytes Packages.gz | cut --delimiter=' ' --fields=1) >> Release
printf '\n '$(sha256sum Packages | cut --delimiter=' ' --fields=1)' %16d Packages' $(wc --bytes Packages | cut --delimiter=' ' --fields=1) >> Release
# Clearsign the Release file (that is, sign it without encrypting it)
gpg --clearsign --digest-algo SHA512 --local-user $USER -o InRelease Release
# Release.gpg only need for older apt versions
# gpg -abs --digest-algo SHA512 --local-user $USER -o Release.gpg Release
# Get apt to see the changes
sudo apt-get update
fi
Example Contents of conf/distributions file
Origin: My_Local_Repo
Label: My_Local_Repo
Codename: xenial
Architectures: i386 amd64
Components: main
Description: My local APT repository
SignWith: 12345ABC
Links
https://wiki.debian.org/RepositoryFormat
http://ubuntuforums.org/showthread.php?t=1090731
https://help.ubuntu.com/community/CreateAuthenticatedRepository