ASP.NET Core amp; Docker 实战经验分享

一.前言

最近一直在研究和实践ASP.NET Core、Docker、持续集成。在ASP.NET Core 和 Dcoker结合下遇到了一些坑,在此记录和分享,希望对大家有一些帮助。

二.中间镜像

我前面写过一个 《ASP.NET Core & Docker 零基础持续集成 》的教程。里面我们通过持续集成工具Jenkins构建Docker镜像并运行容器,采用的是Docker Compose来进行编排构建运行的(Visual Studio 2017添加Docker支持是采用的Docker Compose)。细心的朋友可能会发现,每次构建完毕以后通过docker images命令查询,可以发现多了许多没有名称()的镜像。这些都是构建过程中的中间镜像,我们可以在构建完成以后 进行统一删除。

删除所有无名称镜像:

docker rmi $(docker images -f "dangling=true" -q)

此命令应当加在构建的最后一步,示例:

echo ---------------Remove-Orphans------------------
docker-compose -f src/docker-compose.yml -f src/docker-compose.override.yml  -p alipaydemo down --rmi local --remove-orphansecho ---------------Publishing...------------------
docker-compose -f "src/docker-compose.yml" -f "src/docker-compose.override.yml"  -p alipaydemo up -d --buildecho ---------------Clear-Images...------------------
docker rmi $(docker images -f "dangling=true" -q)

执行之后会看到以下效果:

这是非常有必要的,因为如果每次构建都残留一些中间镜像,会额外消耗我们的磁盘空间的。

后来的我们

主演:井柏然 / 周冬雨 / 田壮壮

猫眼电影演出 广告
购买

三.固定容器外部端口

这里主要讲的是在自动化构建的过程中,通过docker compose来运行容器的外部端口,而不是直接通过docker run命令来指定。

我们通过Visual Studio 2017添加Docker支持(Docker Compose),通过Docker Compose编排构建运行容器,我们会发现每次构建以后,运行的容器的外部端口都不是固定的,比如32774、32775、32776等等。这对于我们设置了Nginx反向代理和API Gateway等配置的肯定是十分不方便的,我们每次构建完毕以后还要去改这些配置,不是扯淡吗。所以我们需要固定我们容器运行的外部端口,我们可以通过改变docker compose的yml文件来固定容器的外部端口。

Visual Studio 2017 添加的Docker支持所生成的文件有如下结构:

我是用的版本为VS2017 15.6.5。如果是更早的版本添加Docker支持可能会多出一个docker-compose.ci.build.yml文件,其实这一步没必要,目前的最新的VS2017已经移除了该文件。

我们固定容器外部端口需要修改的是docker-compose.override.yml文件,我们需要修改的是ports。默认为:

ports:- "80"

这个80端口只是容器的内部端口,我们进行如下修改来知道容器运行时映射到服务器的端口也就是外部端口:

ports:- "32775:80"

通过上面的设置,我们将容器的外部端口指定为32775,这样我们在构建完成以后,容器运行以后的外部端口都将会为32775,无需再次修改Nginx反向代理等配置。

四.设置镜像版本

我们的应用程序具有不同的版本号,我们不同版本的应用程序构建出来的镜像应该也是具有不同的版本的,我们可以通过设置镜像的Tag来表示不同的版本:

我们同样可以在docker compose的yml里面进行设置,这次修改的是docker-compose.yml文件,我们直接在镜像的名称后面设置Tag,语法为:

image: <镜像名称>:<Tag>

比如我设置一个名为alipaydemo的镜像Tag为V1:

image: alipaydemo:v1

完整的配置分享:

version: '3'services:alipay.demo.pcpayment:    image: alipaydemopcpayment:v1    container_name: alipaydemocontainer    build:      context: .      dockerfile: Alipay.Demo.PCPayment/Dockerfile

五.设置容器名称

我们在通过docker compose运行的容器将会被指定一个默认的容器名称,如果是第四节的配置,那么容器的默认名称为alipaydemopcpayment.alipay.demo.pcpayment.build_1,具有非常一长串,此时我们可以自己来指定这个容器的名称,同样我们需要修改docker-compose.yml文件,设置容器名称的命令格式为:

container_name: <容器名称>

完整的配置分享:

version: '3'services:alipay.demo.pcpayment:   
 image:
alipaydemopcpayment:v1  
container_name:
alipaydemocontainer  
build:
     context: .    
dockerfile:
Alipay.Demo.PCPayment/Dockerfile

通过上面的配置我们将容器名称设置为了alipaydemocontainer

六.设置容器重启策略

某一天我对服务器进行了重启,重启以后发现通过Docker运行的服务无法访问了,然后查看原因,发现Docker服务没有开机自启,启动了Docker以后发现容器又没有自动启动。

1.设置Docker开机自启

我们可以直接通过chkconfig命令来设置Docker开启自启:

chkconfig docker

执行成功如下:

2.设置容器随Docker启动

我们要让容器随Docker启动,就必须设置容器的重启策略为always,我们通过docker compose来运行容器时可以在yml里面指定。打开docker-compose.override.yml文件,添加配置:

restart: always

完整的配置示例:

version: '3'services:alipay.demo.pcpayment:    restart: always    environment:- ASPNETCORE_ENVIRONMENT=Production    ports:- "32775:80"

七.Docker的重启策略

1.设置容器重启策略

这里讲的设置容器重启策略主要是通过命令来进行交互,并非第六节讲的通过docker compose来设置重启策略,是对第六节的一个扩展阅读。

我们可以在使用docker run命令时通过--restart参数来设置重启策略:

docker run -d --restart=always alipaydemodocker run -d --restart=on-failure:10 alipaydemo

第一条命令代表容器退出时总是重启容器,第二条代表在容器非正常退出时重启容器,最多重启10次。

对于已经运行的容器可以通过docker update命令来指定:

docker update --restart=always alipaydemo 

2.Docker容器的重启策略

Docker容器的重启策略是面向生产环境的一个启动策略,在开发过程中可以忽略该策略。
Docker容器的重启都是由Docker守护进程完成的,因此与守护进程息息相关。
Docker容器的重启策略如下:

  • no,默认策略,在容器退出时不重启容器

  • on-failure,在容器非正常退出时(退出状态非0),才会重启容器

  • on-failure:3,在容器非正常退出时重启容器,最多重启3次

  • always,在容器退出时总是重启容器

  • unless-stopped,在容器退出时总是重启容器,但是不考虑在Docker守护进程启动时就已经停止了的容器

3.Docker容器的退出状态码

docker run的退出状态码如下:

  • 0,表示正常退出

  • 非0,表示异常退出(退出状态码采用chroot标准)

  • 125,Docker守护进程本身的错误

  • 126,容器启动后,要执行的默认命令无法调用

  • 127,容器启动后,要执行的默认命令不存在

  • 其他命令状态码,容器启动后正常执行命令,退出命令时该命令的返回状态码作为容器的退出状态码

参考资料:https://blog.csdn.net/taiyangdao/article/details/73076019

八.设置自动交互

我们在编写Dockerfile时,可以通过RUN命令来运行一些命令,由此我们可以通过运行apt-get等命令,将一些必要的组件安装到我们的镜像之中,比如lsof等。我们有如下配置:

RUN apt-get install lsof

但是我们在安装一个组件时,非常有可能遇到交互操作,比如“Dou you want to xxx?[y/n]”等,遇到这种将会中断我们的Docker镜像构建过程,那么如何解决呢?我们可以给命令指定--assume-yes来实现自动交互:

RUN apt-get install lsof --assume-yes

持续集成自动化构建过程中,如若不设置自动交互将会被中断:

使用apt-get install命令以前,最好使用apt-get update更新一下,避免出现问题。

九.ASP.NET Core 生成图片问题

大家应该知道目前.NET Core(2.0)还是没有System.Drawing程序集,如果我们要使用Image等对象来完成生成图片验证码、图片二维码等操作只有通过第三方编写的组件,ZKWeb.System.Drawing便是其中一个,我们使用它以后,我们在windows上运行良好,无需其他额外的操作。但是我们一到Linux运行或者使用Docker(dotnet镜像使用的是ubantu环境)运行时,会发现程序无法正常生成图片,会出现异常,这是因为我们的zk在Linux/Docker下运行需要安装一个名为 libgdiplus 的组件,我们在构建Docker镜像的时候可以通过RUN命令使用apt-get命令进行安装:

RUN apt-get updateRUN apt-get install libgdiplus --assume-yesRUN cd /usr/lib
RUN ln -s libgdiplus.so gdiplus.dll

apt-get update是非常有必要的

完整的Dockerfile配置提供给大家参考:

FROM microsoft/aspnetcore:2.0 AS base
WORKDIR /app
EXPOSE 80FROM microsoft/aspnetcore-build:2.0 AS build
WORKDIR /src
COPY Alipay.Demo.PCPayment.sln ./
COPY Alipay.Demo.PCPayment/Alipay.Demo.PCPayment.csproj Alipay.Demo.PCPayment/
RUN dotnet restore -nowarn:msb3202,nu1503
COPY . .
WORKDIR /src/Alipay.Demo.PCPayment
RUN dotnet build -c Release -o /appFROM build AS publish
RUN dotnet publish -c Release -o /appFROM base AS finalWORKDIR /app
COPY --from=publish /app .RUN apt-get updateRUN apt-get install libgdiplus --assume-yesRUN cd /usr/lib
RUN ln -s libgdiplus.so gdiplus.dll
ENTRYPOINT ["dotnet", "Alipay.Demo.PCPayment.dll"]

十.写在最后

本文乃是我在实践ASP.NET Core & Docker & 持续集成过程中遇到的问题和解决之道,完完全全的实战经验、总结,希望能帮助到大家。关于实践ASP.NET Core & Docker 构建持续集成大家可以看我的这一系列文章:《ASP.NET Core & Docker 零基础持续集成》。本文所说的实战是我在实践我的开源项目:

https://github.com/dotnetcore/Alipay.AopSdk.Core

此项目及其演示项目通过持续集成自动化发布到Nuget和通过Docker运行。这个项目是一个支持.NET Core的支付宝的服务端SDK项目,不仅仅提供支付能力,还提供支付宝生活号、服务窗、行业合作等开发。觉得好的希望能给一个Star支持(手动滑稽)。

最后分享给大家一个高效写博客的方法,本文亦是用此来进行编写和发布:http://www.cnblogs.com/stulzq/p/9043632.html

原文地址:https://www.cnblogs.com/stulzq/p/9059108.html


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com

Reward

长按二维码向我转账

pic_reward_qrcode.2x3534de.png

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

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

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

相关文章

codeforces E. Picking Strings 构造

题目链接 Picking String 题意 给出字符串S和T&#xff0c;1e5个询问&#xff0c;每次询问S的一段区间是否能转变成T的一段区间。 转变方式&#xff1a; A>BCA>BCB>ACB>ACC>ABC>ABAAAAAA可以消除 题解 我们从以上四个条件出发推导出更加精华的条件 B>…

P4169-[Violet]天使玩偶/SJY摆棋子【CDQ分治】

正题 题目链接:https://www.luogu.com.cn/problem/P4169 题目大意 nnn个点&#xff0c;然后每次操作 加一个新的点询问一个点更近的点 解题思路 定义tit_iti​表示第几个操作&#xff0c;开始就有的点tit_iti​为000 假设最近的点在左上角&#xff0c;那么有要求ti<tj,xi…

【Floyed】【匈牙利算法】导弹(jzoj 1610)

题目大意&#xff1a; 有n个城市&#xff0c;有一部分是A国的&#xff0c;有一部分是B国的&#xff08;小于A国的&#xff09;&#xff0c;A国每个城市都有一枚导弹&#xff08;只有一枚&#xff09;&#xff0c;炸毁别的城市的时间是到这个城市的距离&#xff0c;请问A国最快…

codeforces G - Almost Increasing Array 动态规划、动态开点线段树

题意 给出一个序列&#xff0c;允许删除一个元素&#xff0c;并将任意元素的值修改为任意整数&#xff0c;问最少修改多少个元素使得序列变成严格单调递增的序列&#xff1f; 题解 这道题目很具有启发性&#xff1a; 不考虑删除元素&#xff0c;原数列各个数值减去他们下标得…

Oracle .NET Core Beta驱动已出,自己动手写EF Core Oracle

使用.net core也有一段时间了&#xff0c;一直都没有Oracle官方的正式版驱动程序&#xff0c;更别说EF版本了。之前基于Oracle官方的.net core预览版本写了个Dapper的数据库操作实现&#xff0c;但是总感觉不太完美&#xff0c;有消息称Oracle官方的EF版本可能要到第三季度出了…

nssl1452-排行榜【数论】

正题 题目大意 给出nnn&#xff0c;求一个长度为2n2n2n的由1∼n1\sim n1∼n各两个组成的一个序列使得有一个数的前缀数量不小于任何数字。 解题思路 首先这个数字肯定是第一个数字&#xff0c;这里假设为111&#xff0c;那么要求任意位置111的前缀数量都不小于别的数。 也就…

【离散化】【差分】幻灯片(jzoj 1609)

幻灯片 题目大意&#xff1a; 有n个幻灯片映在一起&#xff0c;每个幻灯片的的左上角是a1,a2,右上角是a3,a4,颜色是a5当多个幻灯片在同一个位置时&#xff0c;颜色就是他们的和&#xff0c;求有所少种颜色 样例输入 3 2 2 3 3 2 2 0 4 4 1 1 1 3 5 3 样例输出 4 数据…

.net core在网关中统一配置Swagger

最近在做微服务的时候&#xff0c;由于我们是采用前后端分离来开发的&#xff0c;提供给前端的直接是Swagger&#xff0c;如果Swagger分布在各个API中&#xff0c;前端查看Swagger的时候非常不便&#xff0c;因此&#xff0c;我们试着将Swagger集中放到网关中。这里我用两个API…

P4074-[WC2013]糖果公园【树上带修莫队】

正题 题目链接:https://www.luogu.com.cn/problem/P4074 题目大意 nnn个点的一颗数&#xff0c;第iii个点有一颗cic_ici​种类的糖。 第iii次获得jjj种类的糖可以产生价值wi∗vjw_i*v_jwi​∗vj​。 每次操作 修改一个点的糖果种类询问一个路径的价值和 解题思路 用欧拉序…

闲来无事刷水题、简单博弈论专题、sg函数、洛谷

记 今天闲来无事&#xff0c;不想刷codeforces了&#xff0c;到洛谷提高组训练营找几道水题刷着玩玩&#xff08;虽然自己早已过了打OI的年纪&#xff09;&#xff5e; 简单博弈论专题 P1199 三国游戏 这么考虑&#xff0c;由于电脑总是不能让我搭配出当前能搭配出的最大的…

医院(jzoj 1611)

医院 题目大意&#xff1a; 有n个城市&#xff0c;有m条线路使他们相连&#xff08;有向&#xff09;&#xff0c; 在一些城市中建立医院&#xff0c;相连的城市只能有一间医院&#xff0c;每个医院可以派医生去别的城市&#xff0c;当医生走的线路>3时&#xff0c;他们会…

2019.01.24【NOIP普及组】模拟赛C组

总结 这一次的分数&#xff1a;1002562.562.5250 第一题老实打完&#xff0c;100分&#xff0c;第二题蒙点25分&#xff0c;第三题只打了Floyed&#xff0c;还有一部分&#xff08;匈牙利算法&#xff09;没打&#xff0c;第四题蒙点特判&#xff0c;62.5,&#xff08;说实在我…

nssl1453-Fibonacci数列【矩阵乘法,线段树】

正题 题目大意 给出nnn和si(i∈[0..n−1])s_i(i\in[0..n-1])si​(i∈[0..n−1])&#xff0c;对于大部分情况有sxsx%ns_xs_{x\%n}sx​sx%n​。 有递推式FiFi−1si−1Fi−2si−2F_iF_{i-1}s_{i-1}F_{i-2}s_{i-2}Fi​Fi−1​si−1​Fi−2​si−2​ 有mmm个情况的sx!sx%ns_x!s_{…

Apache SkyWalking 为.NET Core带来开箱即用的分布式追踪和应用性能监控

在大型网站系统设计中&#xff0c;随着分布式架构&#xff0c;特别是微服务架构的流行&#xff0c;我们将系统解耦成更小的单元&#xff0c;通过不断的添加新的、小的模块或者重用已经有的模块来构建复杂的系统。随着模块的不断增多&#xff0c;一次请求可能会涉及到十几个甚至…

洛谷 P1967货车运输 并查集+贪心 不需要用LCA!

题目链接 题目链接 题解 要求所有的路径中最小边长的最大值&#xff01; 我们贪心的加边&#xff0c;依照边从大往小的方式往里添加&#xff0c;然后合并并查集。 每次当查询分布在两个待合并的并查集的时候&#xff0c;当前的边长就是这次查询的答案。 我们对每个并查集…

【图论】【最短路】【SPFA】香甜的黄油 Sweet Butter (luogu 1828)

香甜的黄油 Sweet Butter luogu 1828 题目大意&#xff1a; 有n头奶牛&#xff0c;他们在不同的牧场中&#xff0c;他们之间有一些路&#xff0c;现在要让他们去一个地方吃黄油&#xff0c;使他们的总距离最小 题目描述 农夫John发现做出全威斯康辛州最甜的黄油的方法&…

P1081 开车旅行 倍增 洛谷

题目连接 题意 题目已经说的hin明确了。 题解 我们要求出从每个点出发&#xff0c;小A要走的城市和小B要走的城市。 我们把ii以后的所有点的海拔加入到set" role="presentation" style="position: relative;">setset&#xff0c;然后拿H[i]H[…

nssl1454-最短路【并查集,贪心】

正题 题目大意 nnn个点&#xff0c;每个点可以走到[ai,n][a_i,n][ai​,n]&#xff0c;每个点可以从[bi,n][b_i,n][bi​,n]到达。 求disi,j∗(ij)dis_{i,j}*(ij)disi,j​∗(ij)的异或和 解题思路 首先我们可以知道肯定是先往后跳再往前走最优&#xff0c;因为如果先往前再往后…

.NET Core 跨平台执行命令、脚本

一.前言我们可能会遇到需要在程序中执行一些系统命令&#xff0c;来获取一些信息&#xff1b;或者调用shell脚本。.NET Core 目前已经可以跨平台执行&#xff0c;那么它如何跨平台执行命令呢&#xff0c;请看下面的讲解。二.ProcessStartInfo、Process 类介绍我们主要用到的两个…

nssl1458-HR 的疑惑【枚举】

正题 题目大意 给出nnn&#xff0c;求[1..n][1..n][1..n]中有多少个数可以被ab(b>1)a^b(b>1)ab(b>1)表示 解题思路 首先如果bbb等于222&#xff0c;那么可以被表示的数就是n\sqrt nn​个 bbb不是质数时&#xff0c;显然所以的数都可以被一个bbb是质数的情况表示。 …