.Net Core In Docker 在容器内编译并发布

Docker可以说是现在微服务,DevOps的基础,咱们.Net Core自然也得上Docker。.Net Core发布到Docker容器的教程网上也有不少,但是今天还是想来写一写。
你搜.Net core程序发布到Docker网上一般常见的有两种方案:

  • 1、在本地编译成Dll文件后通过SCP命令或者WinSCP等工具上传到服务器上,然后构建Docker镜像再运行容器。该方案跟传统的发布很像,麻烦的地方是每次都要打开相关工具往服务器上复制文件。

  • 2、在服务端直接通过Git获取最新源代码后编译成Dll然后构建Docker镜像再运行容器。该方案免去了往服务器复制文件这步操作,但是服务器环境需要安装.Net Core SDK 来编译源代码。
    自从用了Docker简直懒的不能自理,我既不想手工复制文件到服务器,也不想在服务器装.Net Core环境。显然只要Docker镜像包含.Net Core SDK环境就可以在Docker内帮我们编译代码然后运行,这样连我们的服务器都不用装啥.Net Core的环境拉。

在Docker内编译发布.Net Core程序并运行

新建一个Asp.net Core MVC项目

我们使用一个Asp.net Core MVC程序来演示如何发布到Docker并运行。
使用vs新建一个Asp.net core mvc项目

  public class HomeController : Controller{public IActionResult Index(){return Content($"Core for docker , {DateTime.Now} , verson 2");}}

修改HomeController下的index Action,直接输出一段文字

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>WebHost.CreateDefaultBuilder(args).UseKestrel(op =>{op.ListenAnyIP(5000);}).UseStartup<Startup>();

修改Program下的CreateWebHostBuilder方法,让Kestrel监听5000端口


本地运行一下试试

推送源码到代码仓库

把我们的代码推送到对应的Git仓库,方便我们从部署服务器上直接拉取最新的代码。

X:\workspace\CoreForDocker>git remote add origin https://gitee.com/kklldog/CoreForDocker.git
X:\workspace\CoreForDocker>git push -u origin master
Username for 'https://gitee.com': xxx@gmail.com
Password for 'https://xxx@gmail.com@gitee.com':
Counting objects: 88, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (83/83), done.
Writing objects: 100% (88/88), 527.07 KiB | 2.43 MiB/s, done.
Total 88 (delta 7), reused 0 (delta 0)
remote: Powered By Gitee.com
To https://gitee.com/kklldog/CoreForDocker.git* [new branch]      master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.

添加Dockerfile文件

在CoreForDocker下新增一个Dockerfile文件,注意没有任何扩展名。我们需要基于microsoft/dotnet:latest这个镜像构建一个新的镜像。并且在构建的过程中直接对源码进行编译并发布。

FROM microsoft/dotnet:latest
WORKDIR /app
COPY /. /app
RUN dotnet restore
RUN dotnet publish -o /out -c Release
EXPOSE 5000
ENTRYPOINT ["dotnet", "/out/CoreForDocker.dll"]

大概解释下Dockerfile的意思:
FROM microsoft/dotnet:latest:使用dotnet的最新镜像,这个镜像其实对应的应该就是2.2-sdk这个镜像,里面包含了dotnet-core 2.2 sdk
WORKDIR /app:指定工作目录为app
COPY /. /app:复制宿主机当前目录的内容到容器的app文件夹
RUN dotnet restore:还原nuget包
RUN dotnet publish -o /out -c Release:编译并发布程序集到容器的out目录
EXPOSE 5000:暴露5000端口
ENTRYPOINT ["dotnet", "/out/CoreForDocker.dll"]:容器启动的时候执行dotnet命令,参数为/out/CoreForDocker.dll

Dockerfile的文件属性设置为始终复制
新建好Dockerfile后git push到代码仓库。

在服务器上构建Docker镜像

这里以Ubuntu为例,ssh登录到服务器后使用git clone命令拉取源代码。

git clone https://gitee.com/kklldog/CoreForDocker.git

进入源码目录

cd CodeForDocker\CodeForDocker

使用docker build命令构建新的镜像,注意不要忘记最后一个'.'

docker build -t image_code4docker .

运行容器

如果以上步骤都没有报错,那么恭喜你镜像已经构建成功了,我们可以使用此镜像运行Docker容器了。

docker run -d --name code4docker -p 5000:5000 -v /ect/localtime:/ect/localtime image_core4docker

使用image_core4docker镜像运行一个名为core4docker的容器,绑定宿主机的5000到容器的5000口。其中需要注意的是-v参数映射宿主机的/ect/localtime文件夹到容器的/ect/localtime文件夹,因为经过实践发现容器中的时区有可能跟宿主机不一致,需要映射宿主机的/ect/localtime让容器的时区跟宿主机保持一致。


访问一下服务器的5000端口,发现能够正确返回数据表示我们的Asp.net Core程序在容器中运行成功了

以后当我们对源码进行修改,并提交后,我们只需在服务器上拉取最新的代码然后使用docker build,docker run命令来再次生成镜像并运行容器。但是手工输入docker build,docker run的命令好像也很麻烦,参数又那么多,太烦了。

使用shell脚本简化操作

为了偷懒不想敲那么长的命令,我们可以构建一个脚本,把命令一次性写好,以后只要运行一次脚本就可以了。
使用vim新建一个publish.sh的文件

vim publish.sh

键盘上按i进入编辑模式,输入以下内容

cd CoreForDocker/CoreForDocker
git pull
docker stop core4docker
docker rm core4docker
docker rmi image_core4docker
docker build -t image_core4docker .
docker run --name core4docker -d -p 5000:5000 -v /etc/localtime:/etc/localtime image_core4docker

以上命令,不光有新建镜像跟运行容器的命令,还有移除原来的容器跟镜像的命令
按ecs进入命令模式,退出保存

:wq

让我们模拟修改一下源代码,并提交到代码仓库

    public IActionResult Index(){return Content($"Core for docker , {DateTime.Now} , version 2");}

再次修改homecontroller的index action,输出内容上新增一个version
ssh登录到服务器,运行publish.sh文件

/bin/bash publish.sh


跑完之后我们再次访问下服务器的5000口,数据返回正确,表示服务器上跑的已经是最新的程序了

总结

通过以上演示我们基本了解如何通过git跟docker配合在Ubuntu服务器上不安装.Net Core SDK来发布.Net Core 程序到容器中运行,并且通过shell脚本的方式再次简化发布。但是尽管这样每次发布都需要ssh到服务器上然后运行脚本,特别是开发环境可能经常需要发布,还是觉得麻烦。有没有什么办法让我们push代码后服务器自动就开始部署最新的代码的到容器中运行了呢?
后面我会介绍下如何通过jenkins跟webhook来做CICD。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/309000.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

带你深入探究云原生时代的分布式操作系统 Kubernetes

过去几年&#xff0c;以 docker、kubernetes 为代表的容器技术已发展为一项通用技术&#xff0c;BAT、滴滴、京东、头条等大厂&#xff0c;都争相把容器和 k8s 项目作为技术重心&#xff0c;试图“放长线钓大鱼”。就说腾讯吧&#xff0c;目前基本所有业务都跑在云上&#xff0…

Java实现AVL平衡树

代码如下: package AVLTree;import java.util.ArrayList; import java.util.LinkedList; import java.util.Queue; import java.util.Scanner;public class AVLTree {private class TreeNode{private int data;TreeNode left;TreeNode right;private int height;public TreeNo…

辅助类BinaryTreeNodeIndex(用index索引代替指针)

辅助类BinaryTreeNodeIndex (用index索引代替指针&#xff09; template<typename T> class BinaryTreeNodeIndex { public:T key;int left;int right;int parent; public:BinaryTreeNodeIndex(){}BinaryTreeNodeIndex(const T key,int parent -1,int left -1,int ri…

C# 9.0 新特性之 Lambda 弃元参数

阅读本文大概需要不到 1 分钟。弃元&#xff08;Discards&#xff09; 是在 C# 7.0 的时候开始支持的&#xff0c;它是一种人为丢弃不使用的临时虚拟变量。语法上它是用来赋值的&#xff0c;但它却不被分配存储空间&#xff0c;即没有值&#xff0c;所以不能从中读取值。弃元用…

辅助类BinaryTreeNode(二叉树节点)

辅助类BinaryTreeNode (二叉树节点) template<typename T> class BinaryTreeNode { public:T key;BinaryTreeNode<T>* parent;BinaryTreeNode<T>* left;BinaryTreeNode<T>* right; public:BinaryTreeNode(){}BinaryTreeNode(T key,BinaryTreeNode<…

Java实现Huffman哈夫曼树

代码如下: package HuffmanTree;import java.util.ArrayList; import java.util.LinkedList; import java.util.Queue; import java.util.Scanner;public class HuffmanTree {private class TreeNode{private int val;private TreeNode left;private TreeNode right;public Tr…

应用交付老兵眼中的Envoy, 云原生时代下的思考

Envoy 是云原生时代的明星&#xff0c;其本质是反向代理负载均衡类软件&#xff0c;领域上归于应用交付&#xff0c;那么作为应用交付领域的老兵如何看待 Envoy&#xff0c;Envoy 又引发了哪些关于传统应用交付领域的思考&#xff1f;关于作者林静&#xff0c;F5 软件方向解决方…

给定一个n节点二叉树,写出一个O(n)时间的非递归的过程,将该树每个结点的关键字输出(算法导论第三版第十章10.4-5)

给定一个n节点二叉树&#xff0c;写出一个O(n)时间的非递归的过程&#xff0c;将该树每个结点的关键字输出。要求除该树本树的存储空间外只能使用固定量的额外存储空间&#xff0c;且过程中不得修改该树&#xff0c;即使是暂时的修改也不允许。 &#xff08;算法导论第三版第十…

Java实现Huffman哈夫曼树(数组实现)

代码如下: package HuffmanTreeArrays;import java.util.ArrayList; import java.util.Scanner;public class HuffmanTree {private class TreeNode{private int val;private int left;private int right;private int parent;public TreeNode(){val 0;left -1;right -1;par…

asp.net core程序在k8s中基于rabbitmq队列消息数的HPA实践!

背景最近一段时间&#xff0c;陆陆续续的把手里头项目都迁移到了k8s中&#xff0c;期间遇到很多的坑&#xff0c;并且也学到了许多k8s的知识&#xff08;从0-1&#xff09;&#xff0c;大家都知道k8s中的一大特性是自动扩容&#xff0c;对此结合自己的业务发现很是有“用武之地…

非递归遍历二叉树(算法导论第三版第十章10.4-5)

非递归遍历二叉树&#xff08;算法导论第三版第十章10.4-5&#xff09; template<typename T> void TraverseBinaryTreeNonRecursive(BinaryTreeNode<T>* root) {BinaryTreeNode<T>* prev nullptr;BinaryTreeNode<T>* current root;while (current!…

图的遍历(C语言,邻接表存储的图 - DFS,邻接矩阵存储的图 - BFS)

邻接表存储的图 - DFS /* 邻接表存储的图 - DFS */void Visit( Vertex V ) {printf("正在访问顶点%d\n", V); }/* Visited[]为全局变量&#xff0c;已经初始化为false */ void DFS( LGraph Graph, Vertex V, void (*Visit)(Vertex) ) { /* 以V为出发点对邻接表存储…

如何优雅做系统错误提示?

这里是Z哥的个人公众号每周五11&#xff1a;45 按时送达当然了&#xff0c;也会时不时加个餐&#xff5e;我的第「149」篇原创敬上大家好&#xff0c;我是Z哥。不管是日常的工作中还是生活中&#xff0c;我们每天会用到很多软件系统。不知道你有没有过这样的感受&#xff0c;当…

搭建一套ASP.NET Core+Nacos+Spring Cloud Gateway项目

前言伴随着随着微服务概念的不断盛行&#xff0c;与之对应的各种解决方案也层出不穷。这毕竟是一个信息大爆发的时代&#xff0c;各种编程语言大行其道&#xff0c;各有各的优势。但是有一点未曾改变&#xff0c;那就是他们服务的方式&#xff0c;工作的时候各司其职&#xff0…

dijkstra算法和floyd算法(C语言)

dijkstra算法: /* 邻接表存储 - 无权图的单源最短路算法 *//* dist[]和path[]全部初始化为-1 */ void Unweighted ( LGraph Graph, int dist[], int path[], Vertex S ) {Queue Q;Vertex V;PtrToAdjVNode W;Q CreateQueue( Graph->Nv ); /* 创建空队列, MaxSize为外部定义…

辅助类BinaryTreeNodeLeftChildRightSibling(左孩子右兄弟,二叉树结点)

辅助类BinaryTreeNodeLeftChildRightSibling(左孩子右兄弟&#xff0c;二叉树结点&#xff09; template<typename T> class BinaryTreeNodeLeftChildRightSibling { public:T key;BinaryTreeNodeLeftChildRightSibling<T>* parent;BinaryTreeNodeLeftChildRightS…

如何在ASP.NET Core中集成ElasticSearch

本文来自&#xff1a;https://www.blexin.com/en-US/Article/Blog/How-to-integrate-ElasticSearch-in-ASPNET-Core-70图片我敢打赌&#xff0c;您肯定会被要求向Web应用程序中添加高级搜索功能&#xff0c;而且通常是全文的类似Google的搜索。在技术电子商务的开发过程中&…

prim算法和kruskal算法(C语言)

prim算法: /* 邻接矩阵存储 - Prim最小生成树算法 */Vertex FindMinDist( MGraph Graph, WeightType dist[] ) { /* 返回未被收录顶点中dist最小者 */Vertex MinV, V;WeightType MinDist INFINITY;for (V0; V<Graph->Nv; V) {if ( dist[V]!0 && dist[V]<Min…

利用链表实现可合并堆(算法导论第三版思考题10-2)

利用链表实现可合并堆&#xff08;算法导论第三版思考题10-2&#xff09; a 链表已排序 创建一个空堆&#xff1a; Θ(1) 插入&#xff1a;Θ(n)&#xff0c;插入后依然保持排序 最小值&#xff1a;Θ(1)&#xff0c;第一位便是 取最小值&#xff1a;Θ(1) 合并&#xff1a;Θ…

了解下C#由转换二进制所引起的思考

【导读】最近遇到很有意思转换二进制的问题&#xff0c;有部分童鞋俨然已了解&#xff0c;可能也有一部分童鞋没碰到过也就不知情&#xff0c;这里我们来深入学习下转换二进制所带来的问题。在写此篇文章时&#xff0c;非常开心&#xff0c;收到再一次连任MVP的邮件&#xff0c…