Dockerfile如下:
FROM mcr.microsoft.com/dotnet/core/aspnet:2.1-stretch-slim AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/core/sdk:2.1-stretch AS build
WORKDIR /src
//这一行copy是没有问题的,由于执行docker build的目录就是在项目根目录下
COPY ["Api.Admin.csproj", "Api.Admin/"]
//下面的4个类库项目,是api.admin项目依赖的项目(因为没有依赖nuget包,直接从本地项目引用)
COPY ["../lib-common/Api.Common/Api.Common.csproj", "../lib-common/Api.Common/"]
COPY ["../lib-common/Api.Common1/Api.Common1.csproj", "../lib-common/Api.Common1/"]
COPY ["../lib-common/Api.Common2/Api.Common2.csproj", "../lib-common/Api.Common2/"]
COPY ["../lib-common/Api.Common3/Api.Common3.csproj", "../lib-common3/Api.Common3/"]
RUN dotnet restore "Api.Admin/Api.Admin.csproj"
COPY . .
WORKDIR "/src/Api.Admin"
RUN dotnet build "Api.Admin.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "Api.Admin.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Api.Admin.dll"]
cmd定位到api.admin项目目录下,执行docker build 命令,会提示定位到
COPY ["../lib-common/Api.Common/Api.Common.csproj", "../lib-common/Api.Common/"]
这一行错误,COPY failed: Forbidden path outside the build context:
想到的其他办法有2个:
1、项目依赖改成nuget包方式引用
2、在Dockerfile中,去掉编译的命令,只保留考本和容器启动的命令,在本地发布好之后,再执行docker build.
直接copy 所有的项目吧简单粗暴
FROM mcr.microsoft.com/dotnet/core/aspnet:3.0-buster-slim AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/core/sdk:3.0 AS build
COPY ./ /src
WORKDIR "/src/WebNotebook.Vue"
FROM build AS publish
RUN dotnet publish "WebNotebook.Vue.csproj" -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "WebNotebook.Vue.dll"]
看了你的示例项目下的Dockerfile,并没有依赖的项目引用呢?
|
|
RUN dotnet restore "WebNotebook/WebNotebook.csproj" |
@Code_Song: 不需要,直接publish的时候会自动添加的,不要看我第一个项目,看我上面给你的代码
你这个报错是,copy的时候相应引用项目没有copy过去导致的,docker的路径是比较绕的
简单粗暴的解决方案就是,全部都copy过去,然后publish,一定能找到引用的
@布洛克菲勒: 按你说的试了一下,看截图错误
我的依赖的项目引用,不是在构建的项目目录下的。它们在别的目录下
<ItemGroup>
<ProjectReference Include="..\..\shh-lib-common\Shh.Identity\Shh.Identity.csproj" />
<ProjectReference Include="..\..\shh-lib-common\Shh.OSS\Shh.OSS.csproj" />
<ProjectReference Include="..\..\shh-lib-common\Shh.Service\Shh.Service.csproj" />
</ItemGroup>
这个是构建项目的工程文件,依赖项目是在别的解决方案下
@Code_Song: 不好意思,少写了一行 wordir
COPY ./ /src
的下面
WORKDIR "/src/WebNotebook.Vue"
另外build 命令建议在 sln 下执行
dooker build -f xxx/Dockerfile -t sh. spi. admin:v1
-f 后面是文件路径
@布洛克菲勒: 大佬,加了,好像没有作用
@布洛克菲勒:
我试了,但是还是提示依赖的项目文件不存在
Skipping project "/shh-lib-common/Shh.Identity/Shh.Identity.csproj" because it was not found.
Skipping project "/shh-lib-common/Shh.OSS/Shh.OSS.csproj" because it was not found.
Skipping project "/shh-lib-common/Shh.Service/Shh.Service.csproj" because it was not found.
Skipping project "/shh-lib-common/Shh.Identity/Shh.Identity.csproj" because it was not found.
Skipping project "/shh-lib-common/Shh.OSS/Shh.OSS.csproj" because it was not found.
Skipping project "/shh-lib-common/Shh.Service/Shh.Service.csproj" because it was not found.
@布洛克菲勒: 和sdk版本没有关系吧,我的是2.1的
@Code_Song:
1.确保你Dockerfile 在 project 下面
2.在sln 目录下 使用 dooker build -f xxx/Dockerfile -t sh. spi. admin:v1
指定Dockerfile 路径build
ps: 你的项目如果能用vs publish,那么路径正常就能build
建议 WORKDIR "/src/WebNotebook.Vue"
下面加上 RUN ls -la
可以查看docker 里面目录结构
@布洛克菲勒: 大佬,我的构建环境是windows下的。和环境有关系么,我用的是docker desktop。
好奇怪,shell下的publish是可以的,真是/tuxue
@Code_Song:
你 Dockerfile 呢?
@布洛克菲勒:
FROM mcr.microsoft.com/dotnet/core/aspnet:2.1-stretch-slim AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/core/sdk:2.1-stretch AS build
COPY ./ /src
WORKDIR /src/Shh.Api.Admin
RUN ls -la
FROM build AS publish
RUN dotnet publish "Shh.Api.Admin.csproj" -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "Shh.Api.Admin.dll"]
@Code_Song: 我说的不是这个,我说的是 Dockerfile 为啥不在项目里面
@布洛克菲勒: 我看了目录下是有的呢,但是为什么在构建的时候,输出没有看到
@Code_Song: 包括到项目里面了吗?解决方案里面能看到吗?
@布洛克菲勒: 能看到的,emmm
@Code_Song: 你参考下我的 项目
https://github.com/zhaozhengyan/Nexter.FinTech
我的这个项目是和你的结构类似的
@布洛克菲勒: 好的,我参考一下看看
刚才没有输出Dockerfile的原因我找到了,是因为解决方案目录下,有个dockerfile.ignore文件的原因,删除掉之后,再构建,就输出了,单还是有提示依赖的项目文件找不到的错误。
@布洛克菲勒: 大佬,看了一下你的工程目录结构,然后和我的区别是,你的所有类库项目都是在一个解决方案下,而我的类库项目和构建项目是分离的,除此没有其他的区别。
所以我的构建项目,没法在一个解决方案的目录下,把依赖项目拷贝过来。因为路径是独立于当前的解决方案目录的。(其他的原因找不到了,所以才会提示找不到依赖项目的文件)
@布洛克菲勒:看这里,shh-api-admin,是dockerfile构建的解决方案,但是依赖的项目在下面(蓝色圈)的解决方案下。
@Code_Song: 我明白了,你这个路径不对,Copy ./ Copy 的是 ssh-api-admin 的所有文件
你这里需要 改成 COPY . .
@布洛克菲勒:
改成这样吗(COPY .. /src)
貌似不行,COPY failed: Forbidden path outside the build context: .. ()
@Code_Song: COPY 上面加一行 RUN ls -la,
另外你的build 命令是怎么写的?
@布洛克菲勒:
这会儿输出的容器下的目录都不对了,怎么变成系统的目录了。
docker build -f Shh.Api.Admin/Dockerfile -t shh.api.admin:v1 .
COPY failed: Forbidden path outside the build context: .. () 是不能访问 OpenSource 下的文件
你的build 的命令应该在OpenSource 目录下执行,相应的你的 file路径应该改一下
WORKDIR /src/Shh.Api.Admin 的路径应该一并修改
@布洛克菲勒: thanks,现在这个问题已经解决了,另外还有我的其他项目引用的nuget包问题,因为有离线的包引用。
从命令行输出来看,docker build执行的时候,是把源码都发送到docker的上下文环境中,然后再执行构建过程。
看来,我的项目结构和包引用方式,还需要改进一下,才能方便docker部署
@Code_Song:
当你copy 到 docker里面的时候,docker 里面就和你的 windows 完全隔离了,nuget 找的自然是官方的了,想离线使用nuget,我司的解决方案是 搭建一台私有 nuget 服务器
@Code_Song: 另外, 你这个情况,是因为引入的项目不在上下文里面所以 Copy的时候 没有Copy 进Docker
RUN ls -al
就是看你的Docker的目录结构的,其实你的操作不太规范
正确的做法是 只要不是当前sln的引用都应该采用nuget包的形式 build
我司用的就是 私有化服务器+私有化nuget服务器+私有化镜像管理Harbor 做DevOps的
这里有篇博文是关于Docker 上下文的,可以参考一下
https://www.cnblogs.com/sparkdev/p/9573248.html
@布洛克菲勒: 感谢大佬指点。
将 Dockerfile 放到上级目录
放到上一级目录测试了一下,依然是报这样的错误。
@Code_Song: 放到上级目录后,COPY
路径中 ../
改为 ./
@dudu:
Step 7/23 : COPY ["./shh-lib-common/Shh.Identity/Shh.Identity.csproj", "./shh-lib-common/Shh.Identity/"]
COPY failed: stat /var/lib/docker/tmp/docker-builder304651255/shh-lib-common/Shh.Identity/Shh.Identity.csproj: no such file or directory
这个路径不是本地的项目路径?