Почему Alpine apk сообщает о «невыполнимых ограничениях» при установке старой версии Node.js?

Почему Alpine apk сообщает о «невыполнимых ограничениях» при установке старой версии Node.js?

Я пытаюсь установить старую версию Node.js (4.4.4) на Alpine. Вот мои команды:

apk update
apk add nodejs-lts=4.4.4-r0

При запуске я получаю сообщение об ошибке (запускаю как root, поскольку использую образ Docker Alpine:3.4):

/ # 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 есть вики-страница:Создание альпийского пакета.

Обратите внимание, что имя пакета «nodejs-lts» устарело.

provide="nodejs-lts=$pkgver" # для обратной совместимости

replaces="nodejs-current nodejs-lts" # nodejs-lts для обратной совместимости

решение2

К сожалению,Управление пакетами Alpine-Linuxудаляет старые пакеты, когда доступны новые версии. Это затрудняет использование Alpine Linux с docker, поскольку вам нужен воспроизводимый образ с точными версиями.

Видеть этостатьядля полного списка. Предлагаются два решения: создать собственное зеркало и разместить конкретную версию пакетов, к которым вы хотите сохранить доступ (вероятно, не стоит усилий) или использовать другой базовый образ, например Ubuntu, чья система управления пакетами не удаляет старые версии пакетов (как интуитивно ожидается от любой современной системы управления пакетами).

И, я полагаю, вы могли бы просто обновить свой docker-файл, чтобы использовать последнюю доступную версию этих пакетов. Однако, это будет лишь вопросом времени, прежде чем вы снова столкнетесь с той же ситуацией. Это просто не масштабируется, если вы создаете для производственной системы.

решение3

Вы можете использовать определенную версию из предыдущего выпуска Alpine, используя следующий пример, alia-lib-devкоторый установлен на 1.1.7-r0 в Alpine Edge, но здесь принудительно установлен на 1.1.6-r0 из 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

решение4

Я нашел обходной путь, который, по моему мнению, является золотой серединой.

Я по-прежнему могу задать семантическое версионирование, просто не задаю номер релиза.

т.е. я хочу rsync-3.2.3, но мне все равно, это rsync-3.2.3-r1или rsync-3.2.3-r4.

Я был бы очень обеспокоен, если бы между ними были какие-либо критические изменения, и хотел бы, чтобы мой контейнер Docker собирался независимо от того, существовал ли бы новый идентификатор релиза, а я бы об этом не знал.

В контейнере docker ниже я устанавливаю семантическую версию как , ARGа затем запускаю поиск инструмента через , apk searchа затем , grepчтобы найти семантическую версию с идентификатором релиза. Я использую это значение для последующей установки пакета.

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

Связанный контент