Creating a Package Repository for Alpine Linux

Posted by Afam Agbodike

As part of our dockerization efforts we needed some software that was not available in the publicly available alpine linux repositories (such as Consul and Weave) and decided to build our own repository so we would have a standard place to put them. While creating the repository it became clear that the existing documentation was outdated, so I decided I would document the steps needed to get a repository set up for Alpine Linux.

Some important sections of the Alpine Linux documentation are out of date and haven’t been updated since 2012. I’m sure there is great knowledge available in the IRC channel, but that is less accessible than a good set of online documentation. I was tasked with creating a repo for packaging software that is not available in the public repos, but the entry for the APKINDEX File Format documentation did not work for me.

Note: These instructions are for creating a new repository for custom packages, not a repository mirror.

Seting up the Repository

Decide where you want the repository to live and all the packages will go in this directory. For this example I will create the repository in the /repo/ directory.

Notes: The files should live in the repository under the appropriate architecture. Repositories can be a simple directory or an http, https, ftp location. You will leave out the architecture when adding a repo. In this example all the apk files will be placed in /repo/x86_64/. For my own testing I simply copied a few of the packages from one of the public repositories into my repo. I suggest using just one or two for testing because when you index the packages you will get an error if it some dependencies are missing. Continue to copy the dependencies until you’ve got everything that is required.

You will need to index the packages to create the repository once you have all the packages (.apk files) you want / need in the repository directory:

apk index -o /repo/x86_64/APKINDEX.unsigned.tar.gz /repo/x86_64/*.apk

Copy the unsigned index to where the signed index will be:

cp /repo/x86_64/APKINDEX.unsigned.tar.gz /repo/x86_64/APKINDEX.tar.gz

In order to add the new repository to your list of repositories you will need to edit the apk repositories file (/etc/apk/repositories) and add the location of your repository. (/repo in this example.)

Testing the Unsigned Repository

Comment out any other repositories in your list of repos (/etc/apk/repositories) by placing a # character at beginning of any line to be commented. This is not entirely necessary but makes it easier to see that things are working properly.

Update your available packages:

apk update

This should output a warning about the untrusted signature:

WARNING: Ignoring /repo/x86_64/APKINDEX.tar.gz: UNTRUSTED signature
OK: 27 distinct packages available

You will notice that there are 27 packages in the snippet above. These are not packages in the repository you created but instead are already pre-installed system packages. The number of available packages may be different in your case. You should now re-run the update command and allow it to use untrusted repositories:

apk update --allow-untrusted

This should include the packages in your repo in the count of available packages. In my example there were 11 packages in my repository, resulting in a total of 38 packages:

OK: 38 distinct packages available

Search for one of the packages you added to your repo:

apk search <PACKAGE_NAME> --allow-untrusted

This will list all packages matching the string PACKAGE_NAME.

If you got the same results as the steps above then you now have a valid (but untrusted) Alpine Linux repository.

Making the New Repository Trusted

Create a Keypair:

apk add abuild
abuild-keygen -a -i

It will then prompt you for a filename to save the keypair: `Enter file in which to save the key

In this case we will use ‘alpine-devel@example.com-5629d7e6.rsa’ which will create the ‘alpine-devel@example.com-5629d7e6.rsa’ and ‘alpine-devel@example.com-5629d7e6.rsa.pub’ keypair and copy the public key to /etc/apk/keys/.

Make sure you keep a copy of your private key somewhere safe because you will need it if you add any packages to the repo in the future since you will need to re-sign the updated index.

Note: The standard practice for naming the key is to use the email address of the mailing list (‘alpine-devel@example.com’ in this example) as a prefix for the filename of the keypair followed by an alphanumeric suffix (‘5629d7e6’ in this example), which is generated by the abuild-keygen tool.

Sign the APKINDEX

abuild-sign -k ~/alpine-devel@example.com-5629d7e6.rsa /repo/x86_64/APKINDEX.tar.gz

Note: You need to give it the full path of the private key or it will be unable to find it.

Testing the Signed Repository

Your repository should now be complete! The last thing to do is that if everything worked as expected, you should no longer need to us the --allow-untrusted flag to use your packages:

apk update

This should include the packages in your new repo in the count of available packages:

OK: 38 distinct packages available

At this point, you will probably want to re-enable any of the repositories that were commented out of your /etc/apk/repositories during the first test above.