以前采用shell脚本+dockerfile的方式构建项目,后来发现Docker在17.05版本以后有多阶段构建方式,该文主要记录了netcore采用dockerfile构建遇到的坑。git
这种方式理解起来比较简单就是把构建netcore的前期工做写个shell脚原本完成,dockerfile拿到已经编译好的文件运行。这种方式存在的一个问题就是部署过程比较复杂
docker
#!/bin/bash # 转到exam代码 cd /root/code/examManager/exammanager/ExamManager.Web # 获取最新代码 sudo git pull # 编译 sudo dotnet build # 复制文件到发布文件夹 sudo cp -r /root/code/examManager/exammanager/ExamManager.Web/ExamManager.Web/bin/Debug/netcoreapp3.1/. /root/release/exam-dev # 镜像删除 sudo docker rm -f exam sudo docker rmi exam # 进入代码 cd /root/release/exam-dev # 启动docker docker-compose -p exam up -d # 退出
FROM microsoft/dotnet:latest WORKDIR /app copy . ./ EXPOSE 80 443 # 构建镜像 ENTRYPOINT ["dotnet", "ExamManager.Web.dll"]
为解决以上部署的问题,Docker v17.05开始支持多阶段构建,使用多阶段构建只须要编写一个Dockerfile就能够解决上述问题.,下面是最终可执行的文件
shell
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base WORKDIR /app EXPOSE 80 443 ENV LANG C.UTF-8 LABEL maintainer="test.qq.com" FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build WORKDIR /src copy . . RUN dotnet restore "ExamManager.Web/Exam.Web.csproj" WORKDIR "/src/ExamManager.Web" RUN dotnet build "Exam.Web.csproj" -c Release -o /app/build FROM build AS publish RUN dotnet publish "Exam.Web.csproj" -c Release -o /app/publish from base AS final WORKDIR /app COPY --from=publish /app . ENTRYPOINT ["dotnet", "Exam.Web.dll"]
上述代码中为netcore自动生成的Dockerfile文件,只不过把原来的copy csproj文件,改为了copy全部文件(copy ..)
bash
详细错误以下:
app
COPY failed: Forbidden path outside the build context: ../src/Exam.Application/Exam.Application.csproj ()
该问题因为当时个人项目结构放在不一样的文件夹当中,致使copy的时候,获取不到上下文。
ide
Web页面和相关Dockerfile文件都在ExamManager.Web当中,其他项目文件全在src目录下,必定要注意:
这个缘由是Copy指令是从构建上下文目录中去复制文件的。
这个缘由是Copy指令是从构建上下文目录中去复制文件的。
这个缘由是Copy指令是从构建上下文目录中去复制文件的。
这句话的意思也就是说,由于我是在ExamManager.Web目录下执行的构建命令,因为docker 客户端会把上下文中的全部文件发送给 docker daemon。因此构建的时候是没法获取src这个路径。
学习
COPY ["../src/Exam.Application/Exam.Application.csproj","src/Exam.Application/"]
构建动做在上层也就是sln目录当中,去执行这样的话,上下文中就包括了整个项目。
ui
# -f指定构建的文件 docker build -f ExamManager.Web/Dockerfile -t exam .
在用netcore原生的命令的时候,在进行dotnet build的时候也老是报错。dockerfile文件:rest
COPY ["ExamManager.Web/Exam.Web.csproj","exam-dev/"] COPY ["src/Exam.Application/Exam.Application.csproj","src/Exam.Application/"] COPY ["src/Exam.Domain/Exam.Domain.csproj","src/Exam.Domain/"]
一直在构建哪一步报错。code
CSC : error CS5001: Program does not contain a static 'Main' method suitable for an entry point [/src/exam-dev/Exam.Web.csproj]
缘由暂时未知。
在这过程当中还碰到一些奇怪的错误,后来发现是本身在改dockerfile的时候,慌了神,仔细查看是因为没有加空格的缘由.
MSBUILD : error MSB1008: Only one project can be specified.
另附一张总结的docker学习笔记图