.Net Core In Docker 在容器内编译并发布
Docker可以說是現(xiàn)在微服務(wù),DevOps的基礎(chǔ),咱們.Net Core自然也得上Docker。.Net Core發(fā)布到Docker容器的教程網(wǎng)上也有不少,但是今天還是想來寫一寫。
你搜.Net core程序發(fā)布到Docker網(wǎng)上一般常見的有兩種方案:
1、在本地編譯成Dll文件后通過SCP命令或者WinSCP等工具上傳到服務(wù)器上,然后構(gòu)建Docker鏡像再運(yùn)行容器。該方案跟傳統(tǒng)的發(fā)布很像,麻煩的地方是每次都要打開相關(guān)工具往服務(wù)器上復(fù)制文件。
2、在服務(wù)端直接通過Git獲取最新源代碼后編譯成Dll然后構(gòu)建Docker鏡像再運(yùn)行容器。該方案免去了往服務(wù)器復(fù)制文件這步操作,但是服務(wù)器環(huán)境需要安裝.Net Core SDK 來編譯源代碼。
自從用了Docker簡(jiǎn)直懶的不能自理,我既不想手工復(fù)制文件到服務(wù)器,也不想在服務(wù)器裝.Net Core環(huán)境。顯然只要Docker鏡像包含.Net Core SDK環(huán)境就可以在Docker內(nèi)幫我們編譯代碼然后運(yùn)行,這樣連我們的服務(wù)器都不用裝啥.Net Core的環(huán)境拉。
在Docker內(nèi)編譯發(fā)布.Net Core程序并運(yùn)行
新建一個(gè)Asp.net Core MVC項(xiàng)目
我們使用一個(gè)Asp.net Core MVC程序來演示如何發(fā)布到Docker并運(yùn)行。
使用vs新建一個(gè)Asp.net core mvc項(xiàng)目
修改HomeController下的index Action,直接輸出一段文字
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>WebHost.CreateDefaultBuilder(args).UseKestrel(op =>{op.ListenAnyIP(5000);}).UseStartup<Startup>();修改Program下的CreateWebHostBuilder方法,讓Kestrel監(jiān)聽5000端口
本地運(yùn)行一下試試
推送源碼到代碼倉(cāng)庫(kù)
把我們的代碼推送到對(duì)應(yīng)的Git倉(cāng)庫(kù),方便我們從部署服務(wù)器上直接拉取最新的代碼。
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下新增一個(gè)Dockerfile文件,注意沒有任何擴(kuò)展名。我們需要基于microsoft/dotnet:latest這個(gè)鏡像構(gòu)建一個(gè)新的鏡像。并且在構(gòu)建的過程中直接對(duì)源碼進(jìn)行編譯并發(fā)布。
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的最新鏡像,這個(gè)鏡像其實(shí)對(duì)應(yīng)的應(yīng)該就是2.2-sdk這個(gè)鏡像,里面包含了dotnet-core 2.2 sdk
WORKDIR /app:指定工作目錄為app
COPY /. /app:復(fù)制宿主機(jī)當(dāng)前目錄的內(nèi)容到容器的app文件夾
RUN dotnet restore:還原nuget包
RUN dotnet publish -o /out -c Release:編譯并發(fā)布程序集到容器的out目錄
EXPOSE 5000:暴露5000端口
ENTRYPOINT ["dotnet", "/out/CoreForDocker.dll"]:容器啟動(dòng)的時(shí)候執(zhí)行dotnet命令,參數(shù)為/out/CoreForDocker.dll
Dockerfile的文件屬性設(shè)置為始終復(fù)制
新建好Dockerfile后git push到代碼倉(cāng)庫(kù)。
在服務(wù)器上構(gòu)建Docker鏡像
這里以Ubuntu為例,ssh登錄到服務(wù)器后使用git clone命令拉取源代碼。
git clone https://gitee.com/kklldog/CoreForDocker.git進(jìn)入源碼目錄
cd CodeForDocker\CodeForDocker使用docker build命令構(gòu)建新的鏡像,注意不要忘記最后一個(gè)'.'
docker build -t image_code4docker .運(yùn)行容器
如果以上步驟都沒有報(bào)錯(cuò),那么恭喜你鏡像已經(jīng)構(gòu)建成功了,我們可以使用此鏡像運(yùn)行Docker容器了。
docker run -d --name code4docker -p 5000:5000 -v /ect/localtime:/ect/localtime image_core4docker使用image_core4docker鏡像運(yùn)行一個(gè)名為core4docker的容器,綁定宿主機(jī)的5000到容器的5000口。其中需要注意的是-v參數(shù)映射宿主機(jī)的/ect/localtime文件夾到容器的/ect/localtime文件夾,因?yàn)榻?jīng)過實(shí)踐發(fā)現(xiàn)容器中的時(shí)區(qū)有可能跟宿主機(jī)不一致,需要映射宿主機(jī)的/ect/localtime讓容器的時(shí)區(qū)跟宿主機(jī)保持一致。
訪問一下服務(wù)器的5000端口,發(fā)現(xiàn)能夠正確返回?cái)?shù)據(jù)表示我們的Asp.net Core程序在容器中運(yùn)行成功了
以后當(dāng)我們對(duì)源碼進(jìn)行修改,并提交后,我們只需在服務(wù)器上拉取最新的代碼然后使用docker build,docker run命令來再次生成鏡像并運(yùn)行容器。但是手工輸入docker build,docker run的命令好像也很麻煩,參數(shù)又那么多,太煩了。
使用shell腳本簡(jiǎn)化操作
為了偷懶不想敲那么長(zhǎng)的命令,我們可以構(gòu)建一個(gè)腳本,把命令一次性寫好,以后只要運(yùn)行一次腳本就可以了。
使用vim新建一個(gè)publish.sh的文件
鍵盤上按i進(jìn)入編輯模式,輸入以下內(nè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以上命令,不光有新建鏡像跟運(yùn)行容器的命令,還有移除原來的容器跟鏡像的命令
按ecs進(jìn)入命令模式,退出保存
讓我們模擬修改一下源代碼,并提交到代碼倉(cāng)庫(kù)
public IActionResult Index(){return Content($"Core for docker , {DateTime.Now} , version 2");}再次修改homecontroller的index action,輸出內(nèi)容上新增一個(gè)version
ssh登錄到服務(wù)器,運(yùn)行publish.sh文件
跑完之后我們?cè)俅卧L問下服務(wù)器的5000口,數(shù)據(jù)返回正確,表示服務(wù)器上跑的已經(jīng)是最新的程序了
總結(jié)
通過以上演示我們基本了解如何通過git跟docker配合在Ubuntu服務(wù)器上不安裝.Net Core SDK來發(fā)布.Net Core 程序到容器中運(yùn)行,并且通過shell腳本的方式再次簡(jiǎn)化發(fā)布。但是盡管這樣每次發(fā)布都需要ssh到服務(wù)器上然后運(yùn)行腳本,特別是開發(fā)環(huán)境可能經(jīng)常需要發(fā)布,還是覺得麻煩。有沒有什么辦法讓我們push代碼后服務(wù)器自動(dòng)就開始部署最新的代碼的到容器中運(yùn)行了呢?
后面我會(huì)介紹下如何通過jenkins跟webhook來做CICD。
總結(jié)
以上是生活随笔為你收集整理的.Net Core In Docker 在容器内编译并发布的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C#由转换二进制所引起的思考,了解下?
- 下一篇: asp.net core程序在k8s中基