This article describes how to set up a debian archive with aptly on a debian 9 “stretch” computer, served by an nginx web server.
Initial setup
- Add a DNS alias for your virtual nginx web site (outside of the scope of this blog post). The examples below assume that apt.mydomain.com is the DNS alias
- Install the required software, logged in as root, give the following command
apt-get install gnupg pinentry-curses nginx aptly
- Logged in as your regular user, do the following:
- Create a gpg keyNote! It is a good idea to do the key generation when logged into a debian desktop and move the mouse about during generation, to get good random values for the key generation.Giving the following command at the command line
gpg --full-generate-key
- At the prompt for key type, just press ENTER to select the default (RSA and RSA)
- At the prompt for key size, type “4096” (without the quotes) and press ENTER
- At the prompt for how long the key should be valid, type “0” without the quotes and press ENTER
- At the prompt for “Real name”, type your real name and press ENTER
- At the prompt for “Email address”, type your email address and press ENTER
- At the prompt for “Comment”, type the host name of your archive web server, e.g. “apt.mydomain.com” and press ENTER
- At the prompt “Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit?”, type “O” (without the quotes) and press ENTER
- At the prompt for a passphrase, give a passphrase you will remember. You will be asked for this passphrase every time every time the repository is published
- Export the public key of the gpg key pair in a form that the web server can use
- First list the keys to find the id of the key
steinar@lorenzo:~$ gpg --list-keys /home/steinar/.gnupg/pubring.gpg --------------------------- pub rsa4096 2017-12-27 [SC] 6B7638490707CCE365DF5415D2BA778731DC1EAC uid [ultimate] Steinar Bang (apt.mydomain.com) <sb@dod.no> sub rsa4096 2017-12-27 [E]
- Then use the id of the key to export the public key of the gpg key pair in a form that the web server can return
gpg --output apt_pub.gpg --armor --export 6B7638490707CCE365DF5415D2BA778731DC1EAC
- Publish the key with the default GPG keyserver
gpg --send-keys 6B7638490707CCE365DF5415D2BA778731DC1EAC
- First list the keys to find the id of the key
- Create a local repository “stable”
aptly repo create -distribution="stable" stable
- Configure an architecture in the archive: open the ~/.aptly.conf file in a text editor, and change the line
"architectures": [],
to
"architectures": ["amd64"],
Note! Without a concrete architecture in place, aptly refuses to publish. So add an architecture here, even you are going to publish packages with architecture “all” (e.g. java, python, shell script). In the example I’m using “amd64” which, despite its name, is appropriate for modern 64 bit intel chips (i5 or i7 of various generations).
- Import a package into “stable” (the example uses the package built in Installing apache karaf on debian stretch)
aptly repo add stable git/karaf-deb-packaging/karaf_4.1.4-1_all.deb
- Publish the archive (switch the gpg-key with the id of your actual repository key):
aptly publish repo --gpg-key="6B7638490707CCE365DF5415D2BA778731DC1EAC" stable
Note! If you get a time out error instead of a prompt for the GPG key passphrase, and you’re logged in remotely to the server, the reason could be that gpg tries to open a GUI pinentry tool. Switch to explictly using a curses-based pinentry and try the “aptly publish” command again. Do the command:
update-alternatives --config pinentry
and select “pinentry-curses” in “Manual mode”
- Create a gpg keyNote! It is a good idea to do the key generation when logged into a debian desktop and move the mouse about during generation, to get good random values for the key generation.Giving the following command at the command line
- Log in as root and do the following
- Create a root directory for a new web server and copy in the public key used to sign the published achive
mkdir -p /var/www-apt cp /home/steinar/apt_pub.gpg /var/www-apt/
- In a text editor, create the file /etc/nginx/sites-available/apt with the following content
server { listen 80; listen [::]:80; server_name apt.mydomain.com; root /var/www-apt; allow all; autoindex on; # Full access for everybody for the stable debian repo location /public { root /home/steinar/.aptly; allow all; } # Allow access to the top level to be able to download the GPG key location / { allow all; } }
Note! I actually started out with also serving HTTPS and signing with letsencrypt, but as it turns out APT doesn’t support HTTPS out of the box, so there was no point in including it in this HOWTO
- Enable the site by creating a symlink and restarting nginx
cd /etc/nginx/sites-enabled ln -s /etc/nginx/sites-available/apt . systemctl restart nginx
- Create a root directory for a new web server and copy in the public key used to sign the published achive
Your APT artchive is now up and running.
Use the new APT archive
To start using the APT archive, do the following on a debian computer:
- Log in as root
- Add the archive key
wget -O - https://apt.mydomain.com/apt_pub.gpg | apt-key add -
- Add the archive by adding the following lines to /etc/apt/sources.list
# My own apt archive deb http://apt.mydomain.com/public stable main
- Update APT to get the information from the new archive
apt-get update
- Install a package from the archive
apt-get install karaf
Future additions and updates of existing packages can be done as your regular user, with no need to log in as root during the process.
Publish a new version of a package
To update an existing package:
- Build a new version of the package
- Add the new version of package to the package archive
aptly repo add stable git/karaf-deb-packaging/karaf_4.1.5-1_all.deb
- Update the publish the package archive (i.e. the package archive served by nginx)
aptly publish update --gpg-key="6B7638490707CCE365DF5415D2BA778731DC1EAC" stable
- Do “apt-get update” on the computers using the archive
- Do “apt-get dist-upgrade” on the computers using the archive, and the package should be upgraded
Remove old versions of a package
To delete old versions of a package:
- Do a query to verify that the expression matches only the packages you want to delete
aptly repo search stable 'karaf (<=4.1.4-4)'
- Remove all packages matching the query
aptly repo remove stable 'karaf (<=4.1.4-4)'
- Remove old versions of the database (this is where the disk usage of the repository is reduced)
aptly db cleanup
2 thoughts on “Setting up a debian package archive with aptly”