Docker & ASP.NET Core (2):定制Docker鏡像


上一篇文章:把代碼連接到容器 

Dockerfile

在Docker的世界里,我們可以通過一個叫Dockerfile的文件來創建Docker鏡像,隨后可以運行容器。

Dockerfile就是一個文本文件,里面寫着一些指令。通過Docker Client,並使用docker build這個命令,docker build命令會讀取該文件里面的指令,生成一層文件系統,然后就生產出了一個docker的鏡像。

Dockerfile的文件名就是Dockerfile,當然了也可以叫別的名,但是通常就叫Dockerfile。

Dockerfile里面包含着各種指令,這些指令會創建一個中間層鏡像,這個中間層鏡像可以被緩存,這樣的話以后構建的時候速度就很快了。

 

Dockerfile的主要指令:

  • FROM。通常情況下,你要創建的鏡像是基於另外一個鏡像的,這就需要使用FROM,當然也可以完全從頭創建。
  • MAINTAINER。該鏡像的維護人。
  • RUN。這里可以定義一些需要運行的命令。例如npm install,dotnet restore等等。
  • COPY。開發的時候,可以把源碼放在Volumes里。而在生產環境下,經常需要把源碼復制到容器里面,使用COPY就可以做到這點。
  • ENTRYPOINT。它可以定義容器的入口,把容器配置成像exe一樣的運行文件。通常是一些例如dotnet 命令,node命令等等。
  • CMD。設置容器運行的默認命令和參數。當容器運行的時候,這個可以在命令行被覆蓋。
  • WORKDIR。設定容器運行的工作目錄。
  • EXPOSE。暴露端口。
  • ENV。設定環境變量。
  • VOLUME。定義Volume,並控制如何在宿主中進行存儲。

 

下面是官網的一個Dockerfile的例子:

 

FROM python:27.-slim,說明該鏡像要基於python:2.7-slim這個鏡像構建。這將會是一層。

COPY . /app,是指在構建鏡像的時候,從當前目錄把源碼復制到/app目錄下。這又是一層。

RUN xxx,是指在WORKDIR(/app)下執行pip install xxx這行命令。

EXPOSE 80,是指把容器的80端口暴露給外界。

ENV,定義了環境變量。

CMD ["python", "app.py"],里定義了容器運行的默認命令和參數。

 

創建一個ASP.NET Core Dockerfile

在Docker hub里找到aspnetcore:

里面第一個microsoft/aspnetcore 只有運行時,所以只能dotnet run,適用於生產環境。

第二個microsoft/aspnetcore-build里有完整的dotnet sdk,可以執行dotnet restore, dotnet build, dotnet run等等。

 

使用VSCode打開我上篇文章建立的ASP.NET Core項目(或者新建一個也可以):

 

然后我們這樣來創建Dockerfile,首先點擊Extensions,搜索docker:

可以找到一個Docker擴展,是由微軟開發的。安裝它即可。

 

安裝完后,點擊Docker按個圖標:

就可以看到本機上的Docker鏡像,容器,注冊信息等等。

 

然后按Ctrl+Shift+P,然后輸入docker:

可以看到有很多可用的命令。

選擇Add Docker Files to Workspace,然后選擇ASP.NET Core:

 

然后選擇操作系統,這里我選Linux:

 

然后填寫內部的端口,我這個項目是5001:

 

然后按回車,就會生成Dockerfile,同時還有一個.dockerignore文件:

(在編輯Dockerfile文件的時候還有智能提示的)。

看一下這個文件:

FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base,就是把前面的鏡像起了一個別名,叫做base。

WORKDIR /app,工作目錄是 /app。

端口5001。

下面幾句類似,然后:

COPY ["VolumeSample.csproj", "./"],就是把VolumeSample.csproj復制到當前工作的目錄。

RUN dotnet restore "./VolumeSample.csproj",執行dotnet restore。

COPY . .,然后把所有的源碼也復制到當前的工作目錄。

WORKDIR "/src/.",切換工作目錄到/src。

RUN dotnet build "VolumeSample.csproj" -c Release -o /app,再執行dotnet build命令,並把結果放在/app目錄下。

 

后邊幾句也是類似:

COPY --from=publish /app .,是指從publish目錄復制,具體是從publish/app目錄復制,到當前的工作目錄。

ENTRYPOINT ["dotnet", "VolumeSample.dll"],就是運行該鏡像會執行的命令dotnet VolumeSample.dll。
 
(一個項目里可以有多個Dockerfile,例如區分開發和生產環境,但是文件名最好使用dockerfile后綴,因為這樣在VSCode里有智能提示)。
 

創建鏡像

其實上面使用VSCode生成的Dockerfile並不是我需要的,我需要的Dockerfile還是按照官方文檔來吧:

https://github.com/aspnet/aspnet-docker/blob/master/README.aspnetcore-build.md

最后是這樣的:

也是多個Stage的。

 

然后執行這個命令來構建鏡像:

docker build -t solenovex/aspnetcore .

使用docker build,-t表示tag,然后是用戶名和要起的鏡像名,鏡像名后邊可以跟着具體的tag,例如solenovex/aspnetcore:1.0,如果不加的話就是latest。最后一個.表示當前這個含有Dockerfile目錄是我要進行構建的內容。

 

執行的時候會遇到.net sdk版本不匹配的問題,也就是microsoft/aspnetcore-build這個鏡像的.net sdk版本有點低。

 

所以,我只好改為使用microsoft/dotnet:2.1-sdk這個鏡像了:

 

再次執行:docker build -t solenovex/aspnetcore .

這個構建的過程還是挺快的,過程大概如下:

成功了。

 

然后從VSCode的docker擴展里就可以看到我剛剛創建的鏡像:

 

然后在Powershell里面創建/運行一個容器:

 

執行docker ps -a:

可以看到該容器運行后就馬上退出了,查看一下日志看看原因:

 

錯誤信息是:

其實這個錯誤信息感覺並不明確。

 

具體怎么解決這個錯誤,且聽下回分解。。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM