This is a script I’ve used to download arbitrary packages (apk files) from Alpine Linux repositories and sign them with my own keys. I run this on x86_64/amd64 hardware to download aarch64 packages for offline installation media.

This script essentially creates an offline repository on a local disk. For any later installation to trust these packages the public key generated below will need to be installed on the relevant system.

It took me a while to realize I could pass multiple repository options to recursively download dependencies for packages across multiple repositories.

apk is a fairly portable tool, and can be installed on multiple operating systems using Alpine’s build artifacts or official package managers for distributions like Arch Linux. The same is true for abuild-sign and similar helper scripts.

#!/usr/bin/env bash

set -e

version=latest-stable
arch=aarch64
declare -a packages=("rsync" "hostapd" "nano")

script_dir=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
abuild_keys_dir="${script_dir}/.abuild"
destination="${script_dir}/apks/${version}/${arch}"

mkdir -p "${destination}"

apk fetch \
    --allow-untrusted \
    --no-cache \
    --repository "https://dl-cdn.alpinelinux.org/alpine/${version}/main" \
    --repository "https://dl-cdn.alpinelinux.org/alpine/${version}/community" \
    --arch ${arch} \
    --recursive \
    --output "${destination}" \
    "${packages[@]}"

apk index \
    --allow-untrusted \
    --verbose \
    --arch aarch64 \
    --rewrite-arch=aarch64 \
    --update-cache \
    --output "${destination}/APKINDEX.tar.gz" "${destination}"/*.apk

# Create signing keys.
if [ ! -d "${abuild_keys_dir}" ]
then
    mkdir -p "${abuild_keys_dir}"
    openssl genrsa -out "${abuild_keys_dir}/abuild.rsa" 2048
    openssl rsa -in "${abuild_keys_dir}/abuild.rsa" -pubout -out "${abuild_keys_dir}/abuild.rsa.pub"
fi

abuild-sign -k "${abuild_keys_dir}/abuild.rsa" -p "${abuild_keys_dir}/abuild.rsa.pub" "${destination}/APKINDEX.tar.gz"