Переменная ARG в Dockerfile не расширяется

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

У меня в Dockerfile есть строки, которые предназначены для сборки приложения dotnet, и, как вы можете видеть, у меня есть ARG, где я определяю конфигурацию сборки, а затем передаю ее компилятору в следующей строке:

ARG BUILD_CONFIGURATION=Release
RUN dotnet build "MyProject/MyProject.csproj" -c ${BUILD_CONFIGURATION} -o /bin

Однако проблема в том, что при сборке образа Docker аргумент ${BUILD_CONFIGURATION} не расширяется, а вместо этого передается буквально, поэтому фактически вызываемая команда сборки буквально:

dotnet build "MyProject/MyProject.csproj" -c ${BUILD_CONFIGURATION} -o /bin

Очевидно, компилятору это не нравится, и он выдает мне ошибку:

MSB3052: параметр компилятора недействителен. '/define:${BUILD_CONFIGURATION}' будет игнорироваться.

Почему это не работает? Что мне не хватает?

ПРИМЕЧАНИЕ. Я также пробовал $BUILD_CONFIGURATION без фигурных скобок, а также пробовал использовать ENV вместо ARG, но результат тот же.

Обновлено: дополнительная информация, если необходимо.

  • Я использую Docker Desktop в Windows 11.
  • Я запускаю процесс сборки из терминала Windows с помощью команды docker build .
  • Это полный файл докеров, если это поможет:

Докерфайл

#Copy source code into container
WORKDIR /src
COPY . .    
#Build application
ARG BUILD_CONFIGURATION=Release
RUN dotnet build "MyProject/MyProject.csproj" -c ${BUILD_CONFIGURATION} -o /bin

Изменили ли вы значение SHELL в файле Dockerfile (или в базовом образе)? И если да, то как эта оболочка расширяет переменные среды?

BMitch 12.04.2024 17:44

@BMitch: Я ничего не делал с оболочкой, и я совсем новичок в докере, сейчас я просто пытаюсь скомпилировать один проект. Я использую последнюю версию Docker Desktop для Windows 11, если это поможет. И я не передаю ARG через оболочку, поэтому я предполагаю, что он расширится до значения по умолчанию «Release», как я установил его в первой строке, которую вы можете видеть выше. Я отредактировал вопрос с полным файлом докеров на случай, если это поможет.

Master_T 12.04.2024 18:11

Пожалуйста, смотрите минимальный воспроизводимый пример для получения подробной информации о предоставлении примера, который мы можем воспроизвести. Ваш «полный файл Dockerfile» не является полным файлом Dockerfile, его нельзя использовать другим лицам, пытающимся воссоздать вашу проблему.

BMitch 12.04.2024 19:55
Развертывание модели машинного обучения с помощью Flask - Angular в Kubernetes
Развертывание модели машинного обучения с помощью Flask - Angular в Kubernetes
Kubernetes - это портативная, расширяемая платформа с открытым исходным кодом для управления контейнерными рабочими нагрузками и сервисами, которая...
Как создать PHP Image с нуля
Как создать PHP Image с нуля
Сегодня мы создадим PHP Image from Scratch для того, чтобы легко развернуть базовые PHP-приложения. Пожалуйста, имейте в виду, что это разработка для...
2
3
123
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я попробовал ваш пример, используя базовый образ Linux Alpine, но у меня в консоли он печатает переменную во время работы docker build .

Вот Dockerfile:

FROM alpine
#Copy source code into container
WORKDIR /src
COPY . .    
#Build application
ARG BUILD_CONFIGURATION=Release
RUN dotnet build "MyProject/MyProject.csproj" -c ${BUILD_CONFIGURATION} -o /bin

Вот вывод:

....
 => [2/4] WORKDIR /src                                                                                     0.1s
 => [3/4] COPY . .                                                                                         0.3s
 => ERROR [4/4] RUN dotnet build "MyProject/MyProject.csproj" -c Release -o /bin                           0.3s
------                                                                                                          
 > [4/4] RUN dotnet build "MyProject/MyProject.csproj" -c Release -o /bin:
0.323 /bin/sh: dotnet: not found
...

Хотя он выводит ошибку, но, по крайней мере, он печатает Release как часть журнала, что доказывает, что он работает для базового образа Linux...

Редактировать

Поскольку вы используете базовый образ Windows, переменные среды оцениваются с использованием символа %%, а не $. Итак, вы можете изменить команду запуска, чтобы она работала:

dotnet build "MyProject/MyProject.csproj" -c %BUILD_CONFIGURATION% -o /bin

Это действительно образ Windows (он мне нужен, поскольку мое приложение использует некоторые API-интерфейсы Win). Как я уже сказал, я новичок в докере... если я правильно понимаю, вы говорите, что команды в Dockerfile ведут себя по-разному в зависимости от используемого вами образа? Кажется, это противоречит цели Docker, но, возможно, это просто мое невежество....

Master_T 15.04.2024 09:16

@Master_T В Windows есть «командная строка», а в Linux/Mac — «Терминал», и оба они ведут себя по-разному. В Windows переменные среды оцениваются с использованием символа %%, а не $. Я бы посоветовал попробовать, используя: dotnet build "MyProject/MyProject.csproj" -c %BUILD_CONFIGURATION% -o /bin и посмотреть, сработает ли это

Kartoos 15.04.2024 10:39

Также, если это не сработает, можете ли вы поделиться названием базового образа? Я могу попытаться воссоздать вашу проблему

Kartoos 15.04.2024 10:41

вот и все! Использование % вместо $ сработало. Если вы хотите написать это в ответе или отредактировать свой ответ, чтобы отразить это, я приму его.

Master_T 15.04.2024 13:21

@Master_T отлично!! Я отредактировал ответ, включив эту информацию

Kartoos 16.04.2024 10:50

Другие вопросы по теме