I have a Dockerfile to build a Docker image that is based on Alpine Linux. Now I need to install a package as part of this Dockerfile.

Currently I have:

RUN apk update && \
    apk upgrade && \
    apk add git

Apparently this is a bad idea, as the result is non-deterministic. Instead, it depends on the point in time at which I build the image, which version of git is getting installed.

What is the correct way of doing this?

I guess that I have to tell updated, upgrade and add which versions to use, but how do I do this?

I have seen that apk supports pinning of repositories, but that is not what I want (at least I think so), because I do not want to pin a repository, but a package.

In other words: If git could be installed via npm, I'd be able to run:

npm install git@1.9.2

(or whatever version I want to have). What is the equivalent to this for Alpine Linux?


You can set "sticky" versions like this:

# Both are equal
apk add packagename=1.2.3-suffix
apk add 'packagename<1.2.3-suffix'

That will upgrade packages only until the specified version. You can then safely use …

apk upgrade

to upgrade all packages, while packages with versions will remain with their version. To set a minimum version just use …

apk add "packagename>1.2.3-suffix"

In case you can't find a package, while you can see it in the UI for Alpine packages, update your sources/package database:

apk update

The package repository can be found here:


Never pin packages from the "edge" branch of the alpine package repo, as these are in test and may be revoked. (At pkgs.alpinelinux.org/packages, click "edge" and change it to the alpine image version you use, and click "search" again.)


Currently, there is no way to install arbitrary older versions of a package from official repositories in Alpine Linux. The best thing you can achieve is using repositories of the earlier releases:

# cat /etc/alpine-release

# echo 'http://dl-cdn.alpinelinux.org/alpine/v3.2/main' >> /etc/apk/repositories

# apk update
fetch http://dl-cdn.alpinelinux.org/alpine/v3.3/community/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.3/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.2/main/x86_64/APKINDEX.tar.gz

# apk add bash==4.3.33-r0
(1/1) Updating pinning bash (4.3.33-r0)
OK: 13 MiB in 17 packages

# apk add bash==4.3.42-r3
(1/2) Upgrading bash (4.3.33-r0 -> 4.3.42-r3)
Executing bash-4.3.42-r3.post-upgrade
(2/2) Purging ncurses5-libs (5.9-r1)
Executing busybox-1.24.1-r7.trigger
OK: 13 MiB in 16 packages
  • This shows an example of how to pull from the v3.2 branch of the Alpine package repo while using v3.3 Alpine Linux. Be aware that mixing branches/versions is not officially supported. – cowlinator Feb 14 at 22:10

Because I was using the testing repo. I ended up building my own copy. Steps:

Go to package details. Ex:


Click on the commit, click on the APKBUILD file links and "Log" on the menu to get the commit log of the APKBUILD file. Then choose a commit for your APKBUILD file and download it. Ex:


Install the build tools:

apk -U add alpine-sdk

You need to be not root user so create a packager user with password:

adduser -D packager && addgroup packager abuild
passwd packager

Then build it as packager in the same directory as the APKBUILD file:

su - packager
abuild-keygen -a -i
abuild -r

You might need to figure out errors and install dependencies. In my example, I needed to do this on my existing Docker image as root:

apk add python-dev

After a successful build as packager, install it as root:

apk add /home/packager/packages/<something...>/watchman-4.7.0-r0.apk --allow-untrusted

Not sure how to remove the --allow-untrusted part, but the steps worked for me.


The syntax for pinning alpine packages with apk is apk add packageName==x.y.z.

However, when pinning alpine packages in docker images, you have to be careful to use the specific version that matches your image, and avoid the edge branch.

You can view the alpine packages at https://pkgs.alpinelinux.org/packages . Unfortunately, this defaults to the edge branch, which contains packages that may be revoked.

From https://pkgs.alpinelinux.org/packages , type in the name of the package you want, change the branch from edge to match the alpine image version you are using, and set the Arch (architecture), and then hit search. (If you don't know the architecture, run the container and type uname -m.)

This will show you the only stable version(s) of the package that you can safely pin to. Pinning the package to a different version may cause your Dockerfile to stop working one day due to the package getting revoked from the alpine package repository.


FROM alpine:3.3
RUN apk update && apk upgrade
RUN apk add --no-cache \
  git==2.8.6-r0 \
  bash==4.3.42-r6 \

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.