Dockerfile создается локально, но не выполняется на этапе COPY в конвейере Azure Devops - PullRequest
0 голосов
/ 01 августа 2020

Я поместил в контейнер простую службу windows, работающую на. net framework 4.8. Приложение и контейнер как собираются, так и отлично работают локально с помощью этого файла докеров:

FROM ourcontainerregistry.azurecr.io/net-framework-base:latest
WORKDIR /app

RUN cmd MSBuild.exe /property:Configuration=Release
COPY TopShelfServiceInstaller/bin/Release/ .

ENTRYPOINT ["TopShelfServiceInstaller.exe"]

Когда я подключаюсь к контейнеру локально на рабочем столе docker, я вижу файлы в каталоге C: / app, которые Я ожидаю и могу подтвердить, что служба работает должным образом.

Однако, когда я пытаюсь запустить этот файл докеров в конвейере в Azure Devops с помощью агента сборки windows -latest, я продолжаю получать следующее ошибка на этапе КОПИРОВАНИЯ:

COPY failed: CreateFile \\?\C:\ProgramData\docker\tmp\docker-builder002424695\TopShelfServiceInstaller\bin\Release: The system cannot find the path specified.

Есть идеи, почему это может происходить и как это исправить?

РЕДАКТИРОВАТЬ: azure -pipelines.yml для сборки:

resources:
  repositories:
    - repository: net-framework-base
      type: git
      name: Container_DotNetFrameworkBase
  containers:
    - container: net-framework-base
      type: ACR
      azureSubscription: ---
      resourceGroup: ---
      registry: ---
      repository: net-framework-base

variables:
  - name: dockerRegistryServiceConnection
    value: ---
  - name: imageRepository
    value: "service"
  - name: containerRegistry
    value: ---
  - name: prod-container-registry
    value: ---
  - name: dockerfilePath
    value: "$(Build.SourcesDirectory)/Service/dockerfile"
  - name: tag
    value: "$(Build.BuildNumber)"
  - name: vmImageName
    value: "windows-latest"
trigger:
  batch: true
  branches:
    include:
      - feature/*
#pr:
stages:
  - stage: container
    displayName: New Docker Build
    dependsOn: []
    jobs:
      - job: container
        displayName: build container
        pool:
          vmImage: $(vmImageName)
        steps:
          - checkout: self
            fetchDepth: 1
          - checkout: net-framework-base
            fetchDepth: 1

          # this is the task that's failing
          - task: Docker@2
            displayName: build container
            inputs:
              containerRegistry: $(prod-container-registry)
              repository: $(imageRepository)
              command: "build"
              Dockerfile: $(dockerfilePath)
              tags: |
                $(tag)

Ответы [ 2 ]

1 голос
/ 01 августа 2020

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

То, что вы должны делать, это COPY исходный код в контейнер, а затем выполнить все шаги, необходимые для сборки приложения. Также рекомендуется использовать многоступенчатые сборки для этого: вы копируете исходный код в контейнер с SDK и своей цепочкой инструментов сборки, собираете его, а затем копируете полученный результат в упрощенный контейнер времени выполнения. который просто содержит среду выполнения без исходного кода.

0 голосов
/ 06 августа 2020

Я хотел добавить еще один ответ, чтобы лучше объяснить, в чем была моя проблема и как я ее решил. Моя проблема была не в неправильном понимании команды COPY, а в неправильном понимании того, что и где создавалось. Вот старый файл докеров с пояснениями, где я ошибся:

FROM ourcontainerregistry.azurecr.io/net-framework-base:latest
WORKDIR /app

# As Daniel said, the reason it was working for me locally is because I had already built the solution from visual studio.
# So this command wasn't actually building anything because nothing existed on this container yet.
RUN cmd MSBuild.exe /property:Configuration=Release

# However, this was copying the files I had already built in VS locally.
# When this ran on the build agent in Azure DevOps, it would fail because the solution had not been built on the build agent.
COPY TopShelfServiceInstaller/bin/Release/ .

ENTRYPOINT ["TopShelfServiceInstaller.exe"]

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

# First stage is building the app.  
# We do this with one container based on the .NET Framework 4.8 image that has the SDK installed on it.
FROM mcr.microsoft.com/dotnet/framework/sdk:4.8-windowsservercore-ltsc2019 AS build
WORKDIR C:/build

# Next we copy all files from the host into the build container.
COPY . .

# Then we run MSBuild to build the solution.
RUN MSBuild.exe /property:Configuration=Release

# Next and last stage is creating a container that will actually run the app.
FROM ourcontainerregistry.azurecr.io/net-framework-base:latest AS runtime
WORKDIR C:/app

# And here we're copying files from the build container into the runtime container.
COPY --from=build C:/build/TopShelfServiceInstaller/bin/Release .

ENTRYPOINT [ "C:/app/TopShelfServiceInstaller.exe" ]

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

...