10

I'm trying to install an older version of Node.js (4.4.4) on Alpine. Here are my commands:

apk update
apk add nodejs-lts=4.4.4-r0

When I execute, I get an error (running as root because I'm using the Alpine:3.4 Docker image):

/ # apk update
fetch http://dl-cdn.alpinelinux.org/alpine/v3.4/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.4/community/x86_64/APKINDEX.tar.gz
v3.4.6-64-gd029d25 [http://dl-cdn.alpinelinux.org/alpine/v3.4/main]
v3.4.6-33-g38ef2d2 [http://dl-cdn.alpinelinux.org/alpine/v3.4/community]
OK: 5977 distinct packages available
/ # apk add nodejs-lts=4.4.4-r0
ERROR: unsatisfiable constraints:
  nodejs-lts-4.6.0-r0:
    breaks: world[nodejs-lts=4.4.4-r0]

How do I install a specific, older version of a package in apk?

5 Answers 5

10

That is correct. Unfortunately, 4.4.4 is not available.

You should avoid being explicit on package versions unless controlling your own package mirror and package builds, rather allow the package system to handle it for the Alpine release in use.

For Alpine 3.4, only 4.6.0 is available. Search Alpine 3.4 x86_64 Packages Online for nodejs-lts

If you are so inclined, here's the source for the package to change in order to build a specific version of choice.

Review the package source

Alpine has a wiki page: Creating an Alpine package.

Note that 'nodejs-lts' package name is deprecated.

provides="nodejs-lts=$pkgver" # for backward compatibility

replaces="nodejs-current nodejs-lts" # nodejs-lts for backward compatibility

3
  • Got it. Thanks for the explanation. This would be a good candidate for a FAQ. Feb 5, 2017 at 16:10
  • 6
    So it is not possible fixate the version? To make container image kind of immutable/
    – WHITECOLOR
    Apr 9, 2017 at 22:55
  • "You should avoid being explicit on package versions".. What about issues caused by specific versions?..
    – dustytrash
    May 17, 2020 at 9:52
9

Unfortunately, Alpine-Linux Package Management drops older packages when there are newer versions available. This makes it hard to use Alpine Linux with docker since you want a reproducible image with exact versions.

See this article for the entire rundown. The two solutions that are offered: Create you own mirror and host the specific version of the packages you wish to keep having access to (probably not worth the effort) or use a different base image such as Ubuntu who's package management system doesn't drop older versions of packages (as intuitively expected from any modern day package management system).

And, I suppose you could just update your docker file to use the latest available version of those packages. However, it'll only be a matter of time before you run into this same situation again. It's just not scalable if you are building for a production system.

2

You can use a specific version from previous alpine release using the following, with example of alia-lib-dev which is set to 1.1.7-r0 in alpine edge but here forced to be 1.1.6-r0 from alpine 3.8:

apk add --no-cache --update-cache --repository http://nl.alpinelinux.org/alpine/v3.8/main alsa-lib-dev=1.1.6-r0
1
  • This may work sometimes, but unfortunately the repository is only categorized by 2 version numbers (v x.y). git 2.22.0 used to work in alpine 3.10.1, but with alpine 3.10.3, it got dropped for git 2.22.2. This means that I am unable to use nl.alpinelinux.org/alpine/v3.10/main to get git 2.22.0.
    – cowlinator
    Jan 16, 2020 at 23:18
1

Just uncomment the entry containing community in /etc/apk/repositories. Then run apk update and apk add <PKG>.

0

I found a workaround that I think is a happy medium.

I can still set the semantic versioning, I just don't set the release number.

i.e I want rsync-3.2.3, but I don't care if its rsync-3.2.3-r1 or rsync-3.2.3-r4.

I would be very concerned if there were any breaking changes between these and would want my docker container to build regardless if a new release id existed and I was none the wiser.

In the docker container below, I set the semantic version as an ARG and then run a search of a tool through apk search and then a grep to find the semantic version with the release id. I use this value to then install the package.

FROM docker.io/alpine:3.13.2

LABEL author="Alexis Lucattini" \
      description="Run rsync 3.2.3" \
      maintainer="alexis.lucattini@umccr.org"

ARG TOOL_NAME="rsync"
ARG TOOL_VERSION="3.2.3"
ARG FUZZY="true"
ARG ALPINE_MAIN_REPOSITORY="http://dl-cdn.alpinelinux.org/alpine/v3.13/main"

# User args
ARG USER="alpine_user"
ARG UID=1000
ARG GID=1000
ARG GROUP="alpine_group"

RUN apk update --quiet && \
    if [[ "${FUZZY-}" == "true" ]]; then \
      TOOL_VERSION="$(apk search --no-cache --repository "${ALPINE_MAIN_REPOSITORY}" \
                        "${TOOL_NAME}" | \
                      grep "^${TOOL_NAME}-${TOOL_VERSION}" | \
                      sed "s%^${TOOL_NAME}-%%")"; \
    fi; \
    apk add --no-cache --repository "${ALPINE_MAIN_REPOSITORY}" \
      "${TOOL_NAME}=${TOOL_VERSION}"

RUN addgroup \
    --system \
    --gid "${GID}" \
    "${GROUP}" && \
    adduser \
    --system \
    --disabled-password \
    --ingroup "${GROUP}" \
    --uid "${UID}" \
    "$USER"

USER "$USER"

CMD [ "${TOOL_NAME}" ]

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.