Размещение обновления с ответом здесь на тот случай, если у кого-то еще возникнет подобная проблема. Я не нашел других решений для этого, поэтому я должен был сделать свое собственное. Ниже мой Dockerfile. Прямо сейчас размер изображения составляет 1 ГБ, поэтому мне, безусловно, потребуется go и оптимизировать его, но я объясню, что я сделал:
#1 Install .NET Core SDK Build Environment
FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build-env
WORKDIR /app
#2 Build YummyApp
COPY . ./
RUN dotnet publish YummyAppAPI -c Release -o out
#3 Install Ubuntu Base Image
FROM ubuntu:latest
MAINTAINER yummylumpkins <yummy@lumpkins.com>
WORKDIR /app
ENV ASPNETCORE_URLS=http://+:80
EXPOSE 80
#4 Install package dependencies & .NET Core SDK
RUN apt-get update \
&& apt-get install apt-transport-https \
&& apt-get update \
&& apt-get install -y curl bash dos2unix wget dpkg \
&& wget -q https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb \
&& dpkg -i packages-microsoft-prod.deb \
&& apt-get install -y software-properties-common \
&& apt-get update \
&& add-apt-repository universe \
&& apt-get update \
&& apt-get install apt-transport-https \
&& apt-get update \
&& apt-get install -y dotnet-sdk-3.1 \
&& apt-get update \
&& rm packages-microsoft-prod.deb
#5 Copy project files from earlier SDK build
COPY --from=build-env /app/out .
#6 Install Azure CLI for AppAuthorization
RUN curl -sL https://aka.ms/InstallAzureCLIDeb | bash
#7 Login to Azure Services and run application
COPY entrypoint.sh ./
RUN dos2unix entrypoint.sh && chmod +x entrypoint.sh
CMD ["/app/entrypoint.sh"]
Шаг 1. Установка. NET Среда сборки Core SDK: Мы начнем с использования. NET Core SDK в качестве базового образа для сборки моего приложения. Следует отметить, что у меня есть большое приложение с одним решением и несколькими файлами проекта. Проект API зависит от других проектов.
Шаг 2. Построение YummyApp: Мы копируем всю структуру проекта из нашего локального каталога в наш рабочий каталог внутри изображения docker (/ приложение). На всякий случай, если кому-то интересно, мой проект - базовое c API-приложение. Это выглядит так:
[YummyApp]
|-YummyAppDataAccess
|YummyAppDataAccess.csproj
|-YummyAppInfrastructure
|YummyAppInfrastructure.csproj
|-YummyAppAPI
|-YummyAppAPI.csproj
|-YummyAppServices
|-YummyAppServices.csproj
|-YummyApp.sln
После того, как мы скопируем все, мы создаем / publi sh Конфигурацию выпуска приложения.
Шаг 3 - Установите базовый образ Ubuntu : Мы запускаем новый слой, используя Ubuntu. Сначала я попытался go с Alpine Linux, но оказалось, что на него установить Azure CLI практически невозможно без каких-либо по-настоящему хакерских обходных путей, поэтому я пошел с Ubuntu для простоты установки.
Шаг 4. Установка зависимостей пакетов &. NET Core SDK: Внутри слоя Ubuntu мы устанавливаем наш рабочий каталог и устанавливаем / обновляем множество библиотек, включая наш. NET Core SDK. Следует отметить, что мне нужно было установить dos2unix
для файла сценария оболочки, который я должен был запустить позже. , .Я объясню позже.
Примечание. Первоначально я пытался установить. NET Core Runtime только из-за его более легкого размера и уменьшения этого образа примерно до 700 МБ (с 1 ГБ), но по какой-то причине, когда я попытался запустить мое приложение в конце файла (Шаг 7) Я получил сообщение об ошибке, в котором не было обнаружено времени выполнения. Поэтому я вернулся к SDK.
Шаг 5. Копирование файлов проекта из более ранней сборки SDK: Чтобы сэкономить место, я скопировал файлы встроенного проекта из первого «образа сборки» в этот слой Ubuntu для экономии места (около 1 ГБ).
Шаг 6 - Установите Azure CLI: Чтобы авторизовать мое приложение для получения токена из Azure Services, обычно я использую Microsoft.Azure.Services.AppAuthentication
. Этот пакет предоставляет метод под названием AzureServiceTokenProvider()
, который (через мою IDE) разрешает моему приложению подключаться к Azure Services для получения токена, который затем используется для доступа к Azure Key Vault. Вся эта проблема началась, потому что мое приложение не может сделать это из контейнера docker, потому что Azure не распознает запрос, поступающий от самого контейнера.
Итак, в Чтобы обойти это, нам нужно войти через az login
в Azure CLI внутри контейнера, прежде чем мы запустим приложение.
Шаг 7 - Войдите в Azure Services и Запустите приложение: Теперь пришло время. У меня были две разные проблемы, чтобы решить здесь. Я должен был выяснить, как выполнить az login
и dotnet YummyAppAPI.dll
, когда этот контейнер будет запущен. Но Dockerfiles позволяют выполнять только один ENTRYPOINT
или CMD
во время выполнения, поэтому я нашел обходной путь. Создав файл сценария оболочки (точка входа. sh), я смог поместить обе команды в этот файл и затем выполнить этот один файл.
После настройки я получил ошибку с entrypoint.sh
, которая читала что-то вроде этого: entrypoint.sh: executable file not found in $PATH
. Я обнаружил, что мне пришлось изменить права доступа к этому файлу с помощью chmod
, потому что в противном случае мой контейнер docker не смог получить к нему доступ. Это сделало файл видимым, но файл все еще не мог быть выполнен. Я получаю еще одну ошибку: Standard_init_linux.go:211: exec user process caused “no such file or directory”
После еще одного копания оказывается, что эта проблема возникает, когда вы пытаетесь использовать файл. sh, созданный в Windows на основе Linux система. Поэтому мне пришлось установить dos2unix
, чтобы преобразовать этот файл во что-то Linux совместимое. Я также должен был убедиться, что файл был отформатирован правильно. Для любого любопытного, вот как выглядит мой entrypoint.sh
:
#!/bin/sh
set -e
az login -u yummy@lumpkins.com -p ItsAlwaysYummy
dotnet /app/YummyAppAPI.dll
exec "$@"
Примечание: Логин и пароль жестко запрограммированы. , Я знаю, что это плохая практика (на самом деле, это ужасно), однако, это только для моей локальной машины и никогда не увидит производство. Следующим шагом будет введение переменных среды с принципом входа в систему. Поскольку это развертывание в конечном итоге произойдет в конвейере Devops * 1095, я могу внедрить эти переменные ENV прямо в конвейер devam YAML, чтобы все это происходило без ввода учетных данных; они будут доставлены прямо из хранилища ключей, где они хранятся.
Наконец, размер этого контейнера огромен (1 ГБ), и его необходимо оптимизировать, если он будет регулярно обновляться / собираться. Я буду продолжать работать над этим, но я открыт для предложений о том, как лучше сделать это, двигаясь вперед.
Еще раз спасибо всем.