1. 程式人生 > >ASP.NET Core 2.0 : 九.從Windows發布到CentOS的跨平臺部署

ASP.NET Core 2.0 : 九.從Windows發布到CentOS的跨平臺部署

emc org 常用 .org and 好用 system 可能 import

本文聊一下如何在Windows上用VS開發並發布, 然後將其部署到CentOS上。對於我們一些常在Windows上逛的來說,CentOS用起來還真有些麻煩。MSDN官方有篇文章大概講了一下(鏈接),按照MSDN上面的例子用vs創建個hellomvc項目,還是踩了好多坑,將整個過程和遇到的坑說一下,希望對有需要的朋友有所幫助。(ASP.NET Core系列目錄)

  本文主要內容:

  1.工具準備

  2.CentOS 上安裝.NET Core環境

  3.Windows上用VS發布項目

  4.項目運行測試

  5.安裝並配置Apache

  6.創建service管理應用

  7.其他註意事項

  8.獨立部署(SCD)

  示意圖:

  技術分享圖片

  最近在阿裏雲上弄了個ECS玩,既然.NET Core跨平臺了,也就選了個CentOS的系統,然後踩坑開始。

一、工具準備

  Putty:阿裏雲提供了一個網頁方式遠程操作CentOS的命令行工具,沒找到怎麽粘貼,挺不好用的。這個是一個命令行的小軟件,也省去了每次都要登錄阿裏雲控制臺的步驟。鏈接

  FileZila:sftp工具,用於將windows上生成的發布包弄到CentOS上去。鏈接

二、CentOS 上安裝.NET Core環境

  安裝.NET Core的環境有兩種方式,SDK和Runtime,區別類似java的JDK和JRE。

  官方提供的下載頁面用Build Apps 和Run Apps描述這兩個, 我們不需要在CentOS上編碼, 所以安裝Runtime就夠了。

  在頁面的all downloads中找到CentOS對應的Runtime版本頁面(鏈接)進行安裝,這裏要註意一下:

  坑一:版本問題,看了一下自己的VS中項目的Microsoft.AspNetCore.All版本是2.0.6, 也就去找了Runtime的2.0.6版本, 否則容易出現某些組件在VS上的引用版本和CentOS上的環境中的版本不一致的錯誤。

  通過Putty鏈接到CentOS服務器,按照該頁面上的步驟執行如下命令:

技術分享圖片
1 sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc
2 sudo sh -c ‘echo -e "[packages-microsoft-com-prod]\nname=packages-microsoft-com-prod \nbaseurl= https://packages.microsoft.com/yumrepos/microsoft-rhel7.3-prod\nenabled=1\ngpgcheck=1\ngpgkey=https://packages.microsoft.com/keys/microsoft.asc" > /etc/yum.repos.d/dotnetdev.repo‘
3 
4 sudo yum update
5 sudo yum install libunwind libicu
技術分享圖片

  最後還有下面關鍵一步我執行後部署仍會有提示某包找不到的問題,

sudo yum install dotnet-runtime-2.0.6

  在github上看到這樣一段話:

Linux
On supported Linux systems, register the Microsoft Product feed as described above and install dotnet-hosting-2.0.6 using your package manager. This will also install the .NET Core Runtime and other required packages.

  後來測試了一下不安裝dotnet-runtime-2.0.6而是安裝dotnet-hosting-2.0.6成功。

sudo yum install dotnet-hosting-2.0.6

三、Windows上用VS發布項目

  右鍵項目選擇發布,默認情況下是FDD(依賴框架部署),發布生成的內容不包含依賴的框架內容,將依賴上文安裝的runtime。

  在CentOS上創建個文件夾, 通過FileZila將發布的文件上傳到該文件夾。

  參考創建目錄命令: mkdir -p /var/aspnetcore/hellomvc

四、項目運行測試

  執行命令運行上傳後的項目:

dotnet /var/aspnetcore/hellomvc/hellomvc.dll

  我們都知道,默認情況下,項目采用的事5000端口,我運行項目時遇到了端口沖突,可能是被占用了吧,VS中修改一下Program.cs, 將端口改為常用的8080

        public static IWebHost BuildWebHost(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
            .UseUrls("http://*:8080")
                .UseStartup<Startup>()
                .Build();

  重新發布並上傳,執行上面的命令成功,提示Kestrel開始監聽8080端口。

  瀏覽器訪問一下http://ip:8080

  技術分享圖片

  結果如上圖很怪異,坑二出現,按F12查看一下提示找不到xxx.css xxx.js等,通過FileZila確認對應的css和js文件都已成功上傳在指定位置。

  第一感覺是沒有執行UseStaticFiles(), 確認了一下已執行。接著又懷疑是目錄大小寫問題,一 一排除, 均正常。

  後來先cd到發布目錄,再次執行,終於成功。

cd /var/aspnetcore/hellomvc

  結果如我們熟悉的下圖:

  技術分享圖片

五、安裝並配置Apache

  安裝Apache,並配置反向代理, 將80端口請求轉給上面的8080端口由Kestrel處理。

  安裝並啟動Apache

sudo yum -y install httpd mod_ssl
sudo systemctl start httpd

  訪問一下http://ip ,頁面是Apache的默認頁面,安裝成功。

技術分享圖片

  配置代理,創建並打開文件hellomvc.conf:

nano /etc/httpd/conf.d/hellomvc.conf

  nano是一個文本編輯工具,如果提示 nano: command not found 可能nano沒有安裝
  執行 yum install nano 命令安裝即可。

  hellomvc.conf文件內寫入如下內容:

技術分享圖片
<VirtualHost *:80>
    ProxyPreserveHost On
    ProxyPass / http://127.0.0.1:8080/
    ProxyPassReverse / http://127.0.0.1:8080/
    ServerName www.example.com
    ServerAlias *.example.com
    ErrorLog ${APACHE_LOG_DIR}hellomvc-error.log
    CustomLog ${APACHE_LOG_DIR}hellomvc-access.log common
</VirtualHost>
技術分享圖片

  重啟Apache服務並將該服務設置為自動啟動:

sudo systemctl restart httpd
sudo systemctl enable httpd

  再次通過 dotnet /var/aspnetcore/hellomvc/hellomvc.dll 將項目運行起來後,訪問 http://ip 或者 http://ip:8080 均訪問正常。

  到現在可能有人比較疑惑, 既然之前的項目已經可以正常訪問了,為什麽還要用Apache?在項目中直接指定監聽80端口不就已經OK? 因為這樣做該服務直接占用了80端口, 但有些情況下,我們需要將來自不同域名的訪問指定到不同的端口處理,例如可以將a.com的請求指定到8080,將b.com的請求指定到8081. 當然, 如果沒有這樣的需求,直接用Kestrel做服務而不用反向代理。

  另外每次通過命令 dotnet xxx.dll 的方式來啟動也不是個很好的體驗,我們可以創建個service來管理它, 這也有點向windows的service。

六.創建service管理應用

  再次用nano創建文件:

sudo nano /etc/systemd/system/kestrel-hellomvc.service

  文件內容如下:

技術分享圖片
[Unit]
Description=Example .NET Web API App running on CentOS 7

[Service]
WorkingDirectory=/var/aspnetcore/hellomvc
ExecStart=/usr/local/bin/dotnet /var/aspnetcore/hellomvc/hellomvc.dll
Restart=always
# Restart service after 10 seconds if dotnet service crashes
RestartSec=10
SyslogIdentifier=dotnet-example
User=apache
Environment=ASPNETCORE_ENVIRONMENT=Production 

[Install]
WantedBy=multi-user.target
技術分享圖片

  保存並啟動服務:

systemctl enable kestrel-hellomvc.service
systemctl start kestrel-hellomvc.service

  查看是否成功:

systemctl status kestrel-hellomvc.service

  在此處我遇到了問題,提示出錯,..........(code=exited, status=203/EXEC).............. kestrel-hellomvc.service failed。坑三出現,又是各種搜索,後來發現msdn中提供的上面的kestrel-hellomvc.service文件內容中的 ExecStart=/usr/local/bin/dotnet 在我的CentOS系統中不存在,通過 which dotnet 查看我的系統中是在 /usr/bin/dotnet ,修改kestrel-hellomvc.service重新執行 systemctl start kestrel-hellomvc.service 提示成功。註意修改該文件後會提示先執行 systemctl daemon-reload 重新加載。

  至此,主要工作均已完成。

七.其他註意事項

  A.kestrel-hellomvc.service中的User=apache

    在安裝Apache之前,通過 dotnet /var/aspnetcore/hellomvc/hellomvc.dll 已經可以將項目運行起來了, 那時候就想先創建Service,因為覺得這與Apache無關, 結果service總是啟動失敗,後來才註意到了這個User=apache,這裏要求這個User存在並且擁有相應的權限。由於對CentOS不熟悉,這點也繞了好久。

  B.啟用ForwardedHeaders中間件

    由於采用了反向代理,需要啟用ForwardedHeaders中間件轉發,在Startup的Configure中添加如下代碼,註意UseForwardedHeaders要用在UseAuthentication之前。(MSDN上的詳細說明)

技術分享圖片
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
    ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});

app.UseAuthentication();
技術分享圖片

八.獨立部署(SCD)

  下面說一下獨立部署(包含依賴項)的發布方式。

  在VS中右擊項目文件,註意是 .csproj 而不是 .sln ,選擇編輯xxx.csproj,打開該文件:

技術分享圖片
<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp2.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.6" />
  </ItemGroup>

  <ItemGroup>
    <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.3" />
  </ItemGroup>

</Project>
技術分享圖片

  在PropertyGroup中添加RuntimeIdentifiers標簽

  <PropertyGroup>
    <TargetFramework>netcoreapp2.0</TargetFramework>
    <RuntimeIdentifiers>win10-x64;centos.7-x64</RuntimeIdentifiers>
  </PropertyGroup>

win10-x64;centos.7-x64 叫做.NET Core RID, 是一些固定的內容, 具體可選項見.NET Core RID的目錄。

  當我們再次發布的時候,在發布設置的目標運行時中就出現了這兩個選項,我們可以根據需要部署的系統選擇對應的RID後進行發布。

https://www.cnblogs.com/FlyLolo/p/ASPNETCore2_9.html

ASP.NET Core 2.0 : 九.從Windows發布到CentOS的跨平臺部署