Замена ARG в команде RUN не работает для Dockerfile

В моем Dockerfile у меня есть следующее:

ARG a-version
RUN wget -q -O /tmp/alle.tar.gz http://someserver/server/$a-version/a-server-$a-version.tar.gz && \
    mkdir /opt/apps/$a-version

Однако при построении этого с:

--build-arg http_proxy=http://myproxy","--build-arg a-version=a","--build-arg b-version=b"

Step 10/15: RUN wget... отображается с $a-version в пути вместо замещенного значения, и сборка завершается неудачно.

Я следовал инструкциям, показанным здесь, но, должно быть, упустил что-то еще.

Мои вопросы: что может быть причиной этой проблемы и как я могу ее решить?

Ответ 1

Не используйте - в именах переменных.

Конструкция Docker всегда будет показывать вам строку, записанную в файле Docker, несмотря на значение переменной.

Поэтому используйте это имя переменной a_version:

ARG a_version

См. Этот пример:

Dockerfile:

FROM alpine

ARG a_version
RUN echo $a_version

Телосложение:

$ docker build . --build-arg a_version=1234
Sending build context to Docker daemon 2.048 kB
Step 1/3 : FROM alpine
 ---> a41a7446062d
Step 2/3 : ARG a_version
 ---> Running in c55e98cab494
 ---> 53dedab7de75
Removing intermediate container c55e98cab494
Step 3/3 : RUN echo $a_version                <<< note this <<
 ---> Running in 56b8aeddf77b
1234                                          <<<< and this <<
 ---> 89badadc1ccf
Removing intermediate container 56b8aeddf77b
Successfully built 89badadc1ccf

Ответ 2

Еще одна вещь, о которой следует быть осторожным, заключается в том, что после каждого оператора FROM все ARG собираются и больше не доступны. Будьте осторожны с многоэтапными сборками.

Ответ 3

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

ARG CONFIGURATION=Debug
RUN dotnet publish "Tmp.AtsCandidates.AtsImportApi.csproj" -c "$CONFIGURATION" -o /app/publish

Ответ 4

У меня была та же проблема с использованием Docker для Windows.

Вместо этого (который работает в контейнерах Linux)

FROM alpine
ARG TARGETPLATFORM
RUN echo "I'm building for $TARGETPLATFORM"

Вы должны сделать это

FROM mcr.microsoft.com/windows/servercore
ARG TARGETPLATFORM
RUN echo "I'm building for %TARGETPLATFORM%"

Просто измените разрешение переменной в соответствии с ОС.

Ответ 5

Единственным способом, которым я смог заменить ARG в контейнере Windows, было префикс $env:, как упоминалось здесь.

Пример моего Dockerfile приведен ниже. Обратите внимание, что ARG PAT определяется после FROM, поэтому он находится в области его использования в команде RUN nuget sources add (, как предложил Хунтао). Единственным успешным способом, с помощью которого я нашел личный токен доступа, было использование $env:PAT

FROM mcr.microsoft.com/dotnet/framework/sdk:4.7.2 AS build
WORKDIR /app

ARG PAT

# copy csproj and restore as distinct layers
COPY *.sln .
COPY WebApi/*.csproj ./WebApi/
COPY WebApi/*.config ./WebApi/
RUN nuget sources add -name AppDev -source https://mysource.pkgs.visualstudio.com/_packaging/AppDev/nuget/v2 -username usern -password $env:PAT
RUN nuget restore

# copy everything else and build app
COPY WebApi/. ./WebApi/
WORKDIR /app/WebApi
RUN msbuild /p:Configuration=Release


FROM mcr.microsoft.com/dotnet/framework/aspnet:4.7.2 AS runtime
WORKDIR /inetpub/wwwroot
COPY --from=build /app/WebApi/. ./

Фактическая команда Docker выглядит следующим образом:

docker build --build-arg PAT=mypatgoeshere -t webapi .