Dockerfile 在本地构建但在 Azure Devops 管道中的 COPY 步骤失败
Dockerfile builds locally but fails on COPY step in Azure Devops pipeline
我已经在 .net Framework 4.8 上容器化了一个简单的 windows 服务 运行ning。使用此 docker 文件:
可以在本地构建应用程序和容器 运行
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 目录中看到了我期望的文件,并且可以确认服务正在按预期运行。
但是,当我尝试使用 windows-最新构建代理在 Azure Devops 的管道中 运行 这个 docker 文件时,我在 COPY 上不断收到以下错误步骤:
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)
我认为 COPY
命令的功能与您想象的不同。 COPY
将文件 从 主机文件系统 复制到 容器中。它在本地工作的原因是因为你在本地构建了代码,所以它正在将你在本地构建的版本复制到容器中。
您应该做的是COPY
将源代码装入容器,然后运行构建应用程序所需的任何步骤。为此使用 multi-stage builds 也是一个好习惯:将源代码复制到带有 SDK 和构建工具链的容器中,构建它,然后将生成的输出复制到仅包含运行时的精简运行时容器中没有源代码的环境。
我想添加另一个答案以更好地解释我的问题是什么以及我是如何解决它的。我的问题不是对 COPY 命令的误解,而是对在哪里构建什么的误解。这是旧的 dockerfile,解释了我哪里出错了:
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"]
这是我使用 multi-stage 构建的新 dockerfile,其中包含有关发生的时间和原因的评论:
# 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" ]
以这种方式构建的要点在于,无论您是在本地工作还是在自动构建管道中工作,它都允许您使用单个命令克隆存储库并构建容器,再次作为 Daniel已经提到了。
我已经在 .net Framework 4.8 上容器化了一个简单的 windows 服务 运行ning。使用此 docker 文件:
可以在本地构建应用程序和容器 运行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 目录中看到了我期望的文件,并且可以确认服务正在按预期运行。
但是,当我尝试使用 windows-最新构建代理在 Azure Devops 的管道中 运行 这个 docker 文件时,我在 COPY 上不断收到以下错误步骤:
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)
我认为 COPY
命令的功能与您想象的不同。 COPY
将文件 从 主机文件系统 复制到 容器中。它在本地工作的原因是因为你在本地构建了代码,所以它正在将你在本地构建的版本复制到容器中。
您应该做的是COPY
将源代码装入容器,然后运行构建应用程序所需的任何步骤。为此使用 multi-stage builds 也是一个好习惯:将源代码复制到带有 SDK 和构建工具链的容器中,构建它,然后将生成的输出复制到仅包含运行时的精简运行时容器中没有源代码的环境。
我想添加另一个答案以更好地解释我的问题是什么以及我是如何解决它的。我的问题不是对 COPY 命令的误解,而是对在哪里构建什么的误解。这是旧的 dockerfile,解释了我哪里出错了:
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"]
这是我使用 multi-stage 构建的新 dockerfile,其中包含有关发生的时间和原因的评论:
# 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" ]
以这种方式构建的要点在于,无论您是在本地工作还是在自动构建管道中工作,它都允许您使用单个命令克隆存储库并构建容器,再次作为 Daniel已经提到了。