Можно ли использовать артефакт, созданный моим конвейером Azure, для создания образа Docker?

У меня есть Azure pipeline, который выполняет dotnet restore, dotnet build и dotnet publish.

Первоначально мы опубликовали артефакт в Azure App Service.

Мы хотели бы перейти на Docker. Поэтому мы начали создавать Dockerfile и Docker@2 task в нашем конвейере, который строит изображение и отправляет его в наш Azure Container Registry.

В большинстве примеров, которые я нахожу, внутри Dockerfile вам нужно сделать dotnet restore, dotnet build и dotnet publish.

Но если я уже делаю это в своем Azure pipeline, не могу ли я просто скопировать и вставить свой артефакт из конвейера в образ Docker?

Аналогично этому вопросу: Передайте артефакт в задачу Docker в Azure DevOps А это: Сборка Docker с артефактами в Azure DevOps Pipeline

Я попытался сделать это следующим образом в конце моего конвейера:

- task: Docker@2
  inputs:
    containerRegistry: '$(containerRegistry)'
    repository: '$(imageRepository)'
    command: 'buildAndPush'
    Dockerfile: '**/Dockerfile'
    buildContext: '$(Build.ArtifactStagingDirectory)'
    tags: |
      $(Build.BuildId)

И мой Dockerfile, который лежит в основе моего проекта:

FROM mcr.microsoft.com/dotnet/aspnet:8.0
COPY . App/
WORKDIR /App
EXPOSE 80
EXPOSE 443
ENTRYPOINT ["dotnet", "MyApplication.dll"]

Образ правильно создан и опубликован на моем Azure Container Registry, но когда я пытаюсь запустить его на Docker Desktop, он сообщает мне, что SDK недоступен на машине. Вот ошибка:

Не удалось загрузить команду, возможно, потому что:

  • Вы намеревались выполнить приложение .NET: Приложение «MyApplication.dll» не существует.
  • Вы намеревались выполнить команду .NET SDK: Пакеты SDK для .NET не найдены.

Когда я нахожусь в локальной среде, под /bin/Debug... у меня есть MyApplication.dll. Поэтому вместо этого я попытался сгенерировать изображение из sdk:

FROM mcr.microsoft.com/dotnet/sdk:8.0

Но теперь ошибка еще более странная:

Не удалось выполнить, поскольку указанная команда или файл не найдены. Возможные причины этого включают в себя:

  • Вы неправильно написали встроенную команду dotnet.
  • Вы намеревались выполнить программу .NET, но dotnet-MyApplication.dll не существует.
  • Вы намеревались запустить глобальный инструмент, но в PATH не удалось найти исполняемый файл с префиксом dotnet и таким именем.

Я думаю, что мне следует придерживаться образа aspnet.

Тогда у меня два вопроса: я просто не скопировал (COPY . App/) в нужное место в Dockerfile, или в моем Dockerfile чего-то не хватает для импорта SDK?

Можно ли использовать артефакт, созданный моим конвейером Azure, для создания образа Docker?

Рекомендуемый способ — восстановление и сборка приложения внутри образа Docker. См. Учебник: Контейнеризация приложения .NET.

Rui Jarimba 17.07.2024 18:04

Наш конвейер уже настроен и работает хорошо. Меня немного беспокоит включение файла nuget.config с нашими учетными данными в изображение, чтобы его можно было восстановить с помощью нашего частного канала. Кроме того, мы платим за Azure Container Registry в зависимости от потребляемой им оперативной памяти и процессора, тогда как Azure Pipeline бесплатен, поэтому я хочу перенести на него большую часть процесса сборки. Хотя это может быть и не рекомендуется, есть ли способ заставить это работать так, как я пытаюсь достичь?

M. Ozn 17.07.2024 18:18

@Rui Jarimba Мне интересно, почему это рекомендуемый способ сделать это. Можете ли вы уточнить или предоставить документацию по этому поводу? Я изучаю Docker, и любые знания, которые я могу получить, очень приветствуются.

M. Ozn 17.07.2024 18:28

Что касается файла nuget.config в вашем образе Docker, см. Как добавить частный источник nuget в dotnet dockerfile? . Имейте в виду, что пример образа Docker по ссылке, которую я разместил, использует многоэтапную сборку: часть SDK запускает восстановление, сборку, запуск тестов и, наконец, публикацию приложения; и тогда среда выполнения использует только опубликованные файлы. AFAIK вы платите за хранилище и пропускную способность изображений при использовании ACR, а не ЦП и ОЗУ.

Rui Jarimba 17.07.2024 18:29
why this is the recommended way to do it - см. devops.stackexchange.com/questions/5461/…. Поиск в Google тоже поможет :-)
Rui Jarimba 17.07.2024 18:45
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
5
62
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Ниже приведен пример, который я пытаюсь использовать на своей стороне, и он может работать так, как ожидалось. Вы можете обратиться к нему, чтобы попытаться перенастроить конвейер и убедиться, что все необходимые файлы артефактов скопированы в контейнер.

  1. Докерфайл.
FROM mcr.microsoft.com/dotnet/aspnet:8.0
WORKDIR /app
EXPOSE 80
EXPOSE 443

COPY . .
RUN dotnet myApp.dll
ENTRYPOINT ["dotnet", "myApp.dll"]
  1. Конвейер YAML.
# azure-pipelines.yml

pool:
  vmImage: ubuntu-latest

steps:
- task: DotNetCoreCLI@2
  displayName: 'dotnet restore'
  inputs:
    command: restore
    projects: myApp.sln
    vstsFeed: 'myFeed'

- task: DotNetCoreCLI@2
  displayName: 'dotnet build'
  inputs:
    projects: myApp.sln
    arguments: '--no-restore -c Release'

- task: DotNetCoreCLI@2
  displayName: 'dotnet publish'
  inputs:
    command: publish
    publishWebProjects: false
    projects: myApp.sln
    arguments: '--no-build -c Release -o "$(Build.ArtifactStagingDirectory)"'
    zipAfterPublish: false
    modifyOutputPath: false

- task: CopyFiles@2
  displayName: 'Copy Dockerfile'
  inputs:
    SourceFolder: '$(Build.SourcesDirectory)'
    Contents: '**/Dockerfile'
    TargetFolder: '$(Build.ArtifactStagingDirectory)'

- task: Docker@2
  displayName: 'Build and Push image'
  inputs:
    containerRegistry: myDockerConnection
    repository: myApp
    Dockerfile: '**/Dockerfile'
    buildContext: '$(Build.ArtifactStagingDirectory)'
    tags: |
     $(Build.BuildId)
     latest

Мне удалось проверить свой образ Docker, используя: docker run --rm -it --entrypoint /bin/sh docker-image, оказывается, мне нужно добавить zipAfterPublish: false к моей команде publish, как вы это сделали. У меня есть похожий Dockerfile и похожий конвейер, и он работает хорошо. Спасибо!

M. Ozn 18.07.2024 09:54

@M.Ozn, Да, задача dotnet publish по умолчанию заархивирует файлы артефактов, и в этом случае вам нужно отключить ее, чтобы заархивировать файлы.

Bright Ran-MSFT 18.07.2024 10:04

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