简介

  之前采用shell脚本+dockerfile的方式构建项目,后来发现Docker在17.05版本之后有多阶段构建方式,该文主要记录了netcore采用dockerfile构建遇到的坑。

原先的方式

  这种方式理解起来比较简单就是把构建netcore的前期工作写个shell脚本来完成,dockerfile拿到已经编译好的文件运行。这种方式存在的一个问题就是部署过程比较复杂

单独的shell脚本

#!/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 # 退出

当时的dockerfile

FROM microsoft/dotnet:latest
WORKDIR /app
copy . ./
EXPOSE 80 443 # 构建镜像
ENTRYPOINT ["dotnet", "ExamManager.Web.dll"]

多阶段构建

  为解决以上部署的问题,Docker v17.05开始支持多阶段构建,使用多阶段构建只需要编写一个Dockerfile就可以解决上述问题.,下面是最终可执行的文件

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 ..)

问题

  详细错误如下:

COPY failed: Forbidden path outside the build context: ../src/Exam.Application/Exam.Application.csproj ()

该问题由于当时我的项目结构放在不同的文件夹当中,导致copy的时候,获取不到上下文。

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目录当中,去执行这样的话,上下文中就包括了整个项目。

# -f指定构建的文件
docker build -f ExamManager.Web/Dockerfile -t exam .

问题2

  在用netcore原生的命令的时候,在进行dotnet build的时候也总是报错。dockerfile文件:

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/"]

  一直在构建哪一步报错。

 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学习笔记图

netcore 自动生成Dockerfile的坑的更多相关文章

  1. 【MyBatis】MyBatis自动生成代码查询之爬坑记

    前言 项目使用SSM框架搭建Web后台服务,前台后使用restful api,后台使用MyBatisGenerator自动生成代码,在前台使用关键字进行查询时,遇到了一些很宝贵的坑,现记录如下.为展示 ...

  2. 在docker hub,用github的dockerfile自动生成docker镜像

    简介: 我已经深深的爱上了docker技术. 在日常使用中,经常看到docker hub 中有很多autobuild的镜像.基本使用是在github中上传dockerfile,过一会儿,docker ...

  3. h5 录音 自动生成proto Js语句 UglifyJS-- 对你的js做了什么 【原码笔记】-- protobuf.js 与 Long.js 【微信开发】-- 发送模板消息 能编程与会编程 vue2入坑随记(二) -- 自定义动态组件 微信上传图片

    得益于前辈的分享,做了一个h5录音的demo.效果图如下: 点击开始录音会先弹出确认框: 首次确认允许后,再次录音不需要再确认,但如果用户点击禁止,则无法录音: 点击发送 将录音内容发送到对话框中.点 ...

  4. 【.NetCore学习】ASP.NET Core EF Core2.0 DB First现有数据库自动生成实体Context

    主要参考微软官方文档 https://docs.microsoft.com/en-us/ef/core/get-started/aspnetcore/existing-db Microsoft .NE ...

  5. Mybatis-Plus默认主键策略导致自动生成19位长度主键id的坑

    原创/朱季谦 某天检查一位离职同事写的代码,发现其对应表虽然设置了AUTO_INCREMENT自增,但页面新增功能生成的数据主键id很诡异,长度达到了19位,且不是从1开始递增的-- 我检查了一下,发 ...

  6. 9.1.2 asp.net core 自动生成组合查询

    在做系统的时候,经常遇到前台录入一大堆的查询条件,然后点击查询提交后台,在Controller里面生成对应的查询SQL或者表达式,数据库执行再将结果返回客户端. 例如如下页面,输入三个条件,日志类型. ...

  7. 把时间还给洞察,且看PPT调研报告自动生成攻略

    文/JSong @2017.02.28 在数据分析里面有一句话是说,80%的时间要用于数据清洗和整理,而我觉得理想的状态应该是把更多的把时间花在数据背后的洞察当中.去年11月在简书占了个坑,说要自己写 ...

  8. CodeSmith 二、多模板按目录树批量自动生成代码

    通过调用指定目录下的所有模板,逐一按照数据表生成独立的代码文件.支持多模板调用.支持所有数据表生成或批量指定多个生成.支持自动的文件目录结构.支持代码文件格式化命名等. 背景:最近一个新项目一高兴选了 ...

  9. 自动生成业务库码表insert脚本

    背景:服务请求一体化项目升级到V4的服务请求类型时,所有配置库数据迁移到各省的业务库中,虽然数据出现大量冗余,但是这是唯一能解决V4 大量服务请求类型不在同一张表中的骚操作了,防止查询服务请求类型时G ...

随机推荐

  1. ElementUI分页Pagination自动到第一页

    当数据量过多时,使用分页请求数据. 设置分页的页数自动回到第一页. 例: <div class="pagination"> <el-pagination back ...

  2. C++第三次作业:友元类

    友元类 将数据与处理数据的函数封装在一起,构成类,即实现了数据的共享又实现了隐藏,无疑是面向程序设计的一大优点,但是封装并不总是完美的,一旦需要涉及到一个类的两个对象的数据处理问题该怎么办?无论是设计 ...

  3. GPU版TensorFlow怎么指定让CPU运行

    由于某些原因GPU版的TensorFlow运行起来会出现一些问题,比如内存溢出等情况.此时我们可以用CPU和系统内存来运行我们的程序. 代码如下: import osos.environ[" ...

  4. 洛谷P4860 Roy&October之取石子II 题解 博弈论

    题目链接:https://www.luogu.org/problem/P4860 和<P4018 Roy&October之取石子>一样的推导思路,去找循环节. 可以发现:只要不能被 ...

  5. hdu 3466 Proud Merchants(有排序的01背包)

    Proud Merchants Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) ...

  6. border写一个直角三角形

    文章地址 https://www.cnblogs.com/sandraryan/ border的四条边是平分的.你可以放大试试 .box1 { width:;; border: 100px solid ...

  7. golang http get请求方式

    client := &http.Client{} //生成要访问的url,token是api鉴权,每个api访问方式不同,根据api调用文档拼接URLurl := fmt.Sprintf(&q ...

  8. redis cluster和hash slot

    redis cluster介绍 从redis3.0.0开始,官方支持了redis cluster的集群模式,结束了redis没有集群的时代. redis cluster 支撑 N 个 redis ma ...

  9. UVa1601 - The Morning after Halloween [单向bfs]

    解题思路: 1.注意到2*2方格中必有一个#,那么最多只有192条通道,可以将所有非‘#’的位置提取出来用邻接表的方式建图,通过bfs搜索目标位置. 2.将三个ghost的位置(a,b,c)作为状态量 ...

  10. C# 从 short 转 byte 方法

    本文告诉大家多个方法转换 short 和 byte 有简单的也有快的 快速简单的方法 static short ToShort(short byte1, short byte2) { return ( ...