Docker & ASP.NET Core (2):定製Docker映象

solenovex發表於2018-11-21

上一篇文章:把程式碼連線到容器 

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:

可以看到該容器執行後就馬上退出了,檢視一下日誌看看原因:

 

錯誤資訊是:

其實這個錯誤資訊感覺並不明確。

 

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

相關文章