古いバージョンの Node.js をインストールするときに、Alpine apk が「満たされない制約」を報告するのはなぜですか?

古いバージョンの Node.js をインストールするときに、Alpine apk が「満たされない制約」を報告するのはなぜですか?

Alpine に古いバージョンの Node.js (4.4.4) をインストールしようとしています。コマンドは次のとおりです。

apk update
apk add nodejs-lts=4.4.4-r0

実行すると、エラーが発生します (Alpine:3.4 Docker イメージを使用しているため、root として実行しています)。

/ # 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]

特定の古いバージョンのパッケージを にインストールするにはどうすればよいですかapk?

答え1

そうです。残念ながら、4.4.4 は利用できません。

独自のパッケージミラーとパッケージビルドを制御している場合を除き、パッケージバージョンを明示的に指定することは避け、使用中の Alpine リリースに対してパッケージシステムが処理できるようにする必要があります。

Alpine 3.4 の場合、4.6.0 のみが利用可能です。Alpine 3.4 x86_64 パッケージをオンラインで検索 (nodejs-lts)

ご希望の場合は、選択した特定のバージョンをビルドするために変更するパッケージのソースがここにあります。

パッケージソースを確認する

Alpine には wiki ページがあります:Alpine パッケージの作成

「nodejs-lts」パッケージ名は非推奨であることに注意してください。

下位互換性のため、provides="nodejs-lts=$pkgver" #

replaces="nodejs-current nodejs-lts" # 下位互換性のための nodejs-lts

答え2

残念ながら、Alpine-Linux パッケージ管理新しいバージョンが利用可能になると、古いパッケージが削除されます。正確なバージョンの再現可能なイメージが必要なため、Alpine Linux を docker で使用するのは困難です。

これを見て記事全体の概要については、次の 2 つの解決策が提案されています。独自のミラーを作成し、アクセスし続けたいパッケージの特定のバージョンをホストする (おそらく労力に見合わない)、またはパッケージ管理システムが古いバージョンのパッケージを削除しない Ubuntu などの別のベース イメージを使用する (現代のパッケージ管理システムでは直感的に期待されるとおり)。

また、これらのパッケージの最新バージョンを使用するように、docker ファイルを更新することもできます。ただし、同じ状況に再び遭遇するのは時間の問題です。実稼働システム用に構築する場合は、スケーラブルではありません。

答え3

次のようにして、以前の Alpine リリースの特定のバージョンを使用できます。例では、alia-lib-devAlpine Edge では 1.1.7-r0 に設定されていますが、ここでは Alpine 3.8 から 1.1.6-r0 に強制されています。

apk add --no-cache --update-cache --repository http://nl.alpinelinux.org/alpine/v3.8/main alsa-lib-dev=1.1.6-r0

答え4

ちょうど良い回避策を見つけました。

セマンティック バージョン管理は引き続き設定できますが、リリース番号は設定しません。

つまり、私は が欲しいのですが、か かrsync-3.2.3は気にしません。rsync-3.2.3-r1rsync-3.2.3-r4

これらの間に重大な変更があった場合、私は非常に心配し、新しいリリース ID が存在するかどうかに関係なく、Docker コンテナをビルドしたいと思うでしょう。

以下の Docker コンテナでは、セマンティック バージョンを に設定しARG、 を介してツールの検索を実行してapk searchgrepリリース ID を持つセマンティック バージョンを検索します。この値を使用してパッケージをインストールします。

FROM docker.io/alpine:3.13.2

LABEL author="Alexis Lucattini" \
      description="Run rsync 3.2.3" \
      maintainer="[email protected]"

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}" ]

関連情報