/about /posts /pages

Building Alpine Packages in a Container

2026-03-15

Backstory

There is a quite detailed page on the AlpineLinux Wiki how to create a new Alpine package [1]. Before working on the package recipe, one must configure their development system. According to the documentation, this can be done directly on your host system (which requires Alpine Linux as OS), via chroot, via LXC, some virtualization system (VMWare, Qemu, EC2) or on Xen [2].

However, you can also do it via Docker (or Podman) containers! So, as a result of some coffee and an afternoon's work, a nice, simple Dockerfile popt out. In this post I will briefly go over that file, demonstrate how to start a developer environment and how to build a very very basic Alpine Python package. Maybe someone can profit from that in the future.

Build the Container

The containerfile looks as follows. Extend it with any further packages if you like, it works for me for working on Python packages.

FROM alpine:edge

ENV USER="developer"
ENV NAME="<your-name>"
ENV MAIL="<your-mail>"

RUN apk add --no-cache  \
    alpine-sdk          \
    apkbuild-pypi       \
    atools              \
    sudo

RUN adduser -D ${USER} &&   \
    addgroup ${USER} abuild

# setup the abuild configuration
RUN echo 'PACKAGER="${NAME} <${MAIL}>"' >> /etc/abuild.conf
RUN echo 'MAINTAINER="$PACKAGER"' >> /etc/abuild.conf
RUN echo "%abuild ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/abuild

# For development, add edge/testing and the local repository to the repositories list
RUN echo "https://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories
RUN echo "/home/${USER}/packages/testing/" >> /etc/apk/repositories

# prepare working directory to mount the aports repo
VOLUME /workspace/aports
WORKDIR /workspace/aports
RUN chown ${USER}:${USER} /workspace/aports
USER ${USER}

# generate the abuild key
RUN abuild-keygen -a -i -n

Save it as Dockerfile and build it:

$ docker build -t alpine-developer:latest .

Prepare the Environment

More detailed instructions on how to create and submit a new package to Alpine Linux can be found here [3]. But in short, you need to create an account on gitlab.alpinelinux.org and fork the public aports repository. Then, you can create on your new package in the testing/ directory, work on it and finally, push it and create a merge request.

To build and test the package locally, you can use the container above. So, let's clone your your forked repo (this may take a while) on the host system.

$ git clone git@gitlab.alpinelinux.org:cschaefer/aports.git

Then, in the same directory, we start the developer container and mount the aports repository as a volume:

$ docker run --rm --volume ./aports:/workspace/aports -it alpine-developer:latest

Now, we can start working on a new package. Note, the next section only describes how to generate the template recipe and build it. The actual editing of the file can now either happen directly in the dockerized environment, or "outside" with some code editor. For example, I adapt the APKBUILD file from my host machine using NeoVim and only use Docker for the build. But you can do what you want.

Create a new Package

The next steps will be executed in the dockerized environment. By using the apkbuild-pypi tool, (almost) all necessary information from PyPi will be fetched automatically and a new package in the current directory will be created. In the following example, we will create a new Alpine recipe based on the publicly available parse-type Python package [4].

$ cd testing/
$ apkbuild-pypi create parse_type
Wrote py3-parse-type/APKBUILD
>>> py3-parse-type: Fetching https://files.pythonhosted.org/packages/source/p/parse-type/parse_type-0.6.6.tar.gz
Connecting to files.pythonhosted.org (146.75.116.223:443)
Connecting to files.pythonhosted.org (146.75.116.223:443)
saving to '/var/cache/distfiles/parse_type-0.6.6.tar.gz.part'
parse_type-0.6.6.tar 100% |****************************************************************************************************************| 98012  0:00:00 ETA
'/var/cache/distfiles/parse_type-0.6.6.tar.gz.part' saved
>>> py3-parse-type: Updating the sha512sums in /workspace/aports/testing/py3-parse_type/APKBUILD...
>>> py3-parse-type: Fetching https://files.pythonhosted.org/packages/source/p/parse-type/parse_type-0.6.6.tar.gz
/var/cache/distfiles/parse_type-0.6.6.tar.gz: OK
>>> py3-parse-type: Unpacking /var/cache/distfiles/parse_type-0.6.6.tar.gz...

$builddir redefined:
	OLD: , NEW: $srcdir/parse_type-$pkgver

Requires: py3-parse py3-enum34 py3-six py3-virtualenv py3-ruff

CheckDepends: py3-pytest

Before starting the build, we need to fetch the latest APKINDEX files first, otherwise the initial build might fail.

$ sudo apk update

Then, we can start the package build:

$ cd py3-parse-type/
$ abuild -r

This will then fetch all dependencies, install them, and run all pre-defined steps: build(), check() and package() from the APKBUILD file. Eventually, if everything worked, the built package is moved to the users home directory:

$ ls -al ~/packages/testing/x86_64/
total 72
drwxr-sr-x 1 cs cs   208 Mar 16 22:00 .
drwxr-sr-x 1 cs cs    12 Mar 16 22:00 ..
-rw-r--r-- 1 cs cs  1270 Mar 16 22:00 APKINDEX.tar.gz
-rw-r--r-- 1 cs cs 25075 Mar 16 22:00 py3-parse-type-0.6.6-r0.apk
-rw-r--r-- 1 cs cs  2271 Mar 16 22:00 py3-parse-type-doc-0.6.6-r0.apk
-rw-r--r-- 1 cs cs 34387 Mar 16 22:00 py3-parse-type-pyc-0.6.6-r0.apk

Of course, the APKBUILD file needs some more tweaks to be ready for a merge request (correct URL, Licensing, dependencies, checksum, etc.), but ... this is all documented in the Wiki [3] and not really part of this guide.

Conclusio

Wrapping up, this posts presents a way how to create a small and leightweight dockerized environment for creating Alpine packages. Using apkbuild-pypi we create a recipe based on a Python package available on the official Python Index PyPi. Then, within the docker environment we can easily build and test the recipe.