0%

[C#] 在 Linux 架設 ASP.NET Core 應用程式

前言

ASP.Net Core 是微軟生態系未來的趨勢,主要優勢是可以跨平台開發,使用一組程式碼便能在各平台上運作。這篇文章的情境是:在 Windows 上開發 ASP.Net Core 應用程式,且發布至 CentOS 上運行,並使用 Nginx 作為 Reverse Proxy。

環境

  • 實體機 (Host) 作業系統:Windows 10
  • 虛擬機 (Guest) 作業系統:CentOS 7.9
  • 虛擬機軟體:VMware Workstation Player 16.2.0
  • ASP.NET Core 3.1

添加 sudoer 權限

安裝好作業系統後,先將要用來平常作業用的使用者帳號加入 sudoers file,使其可用 sudo 指令。

安裝 ASP.Net Core 執行環境

dotnet 套件有兩種套件分別為 SDK 與 Runtime,若要在 CentOS 中 開發 .NET Core,需要安裝的是 SDK;若只是要 運行 編譯好的 .NET Core 應用,則是安裝 Runtime。筆者是在 Windows 中編譯好再拿到 CentOS 上運行,因此只需要安裝 Runtime

1
2
[wrxue@localhost ~]$ sudo rpm -Uvh https://packages.microsoft.com/config/centos/7/packages-microsoft-prod.rpm
[wrxue@localhost ~]$ sudo yum install -y aspnetcore-runtime-3.1 # 依照自己的目標版本更改,2.1、3.1、5.0 等等

安裝 Nginx

安裝 Nginx 並啟用服務

1
2
3
4
[wrxue@localhost ~]$ sudo yum install -y epel-release
[wrxue@localhost ~]$ sudo yum install -y nginx
[wrxue@localhost ~]$ sudo systemctl start nginx
[wrxue@localhost ~]$ sudo systemctl enable nginx

設定防火牆

http 服務與 5000 Port 加入防火牆 (firewalld) 規則,允許外部連入 (Inbound)

1
2
3
[wrxue@localhost ~]$ sudo firewall-cmd --permanent --zone=public --add-port=5000/tcp # ASP.NET Core 應用程式預設的 Port
[wrxue@localhost ~]$ sudo firewall-cmd --permanent --zone=public --add-service=http
[wrxue@localhost ~]$ sudo firewall-cmd --reload

關閉 SELinux

架設伺服器時先暫時關閉 SELinux 會較容易確認問題所在,待一切設定就緒之後,再開啟 SELinux 並研究如何添加規則即可

1
2
3
4
[wrxue@localhost ~]$ sudo sed -i 's/SELINUX=enforcing/SELINUX=disabled/1' /etc/selinux/config
[wrxue@localhost ~]$ sudo reboot # 重開機

[wrxue@localhost ~]$ sudo sestatus # 查看 SELinux 的狀態,需為 disabled

Publish ASP.NET Core APP

在 ASP.NET Core 應用程式的目錄下,執行下方指令,並等待一段時間直到 Publish 成功

1
dotnet publish -c Release

移動 Publish 資料夾

筆者是使用 VMware 上的 CentOS,因此需要先掛載共用資料夾,才能將 Windows 的檔案傳到 Server 上,讀者可以依實際情況來判定是否可以忽略這一步

1
2
[wrxue@localhost ~]$ mkdir shares
[wrxue@localhost ~]$ sudo /usr/bin/vmhgfs-fuse .host:/Shared ~/shares -o subtype=vmhgfs-fuse,allow_other

再將 Publish 出來的資料夾 整個 搬到 /var/www/ 目錄下,並使用 dotnet 指令啟動 ASP.NET Core 應用程式

1
2
3
4
[wrxue@localhost ~]$ sudo mkdir -p /var/www/appName
[wrxue@localhost ~]$ sudo cp -R ./shares/publish/* /var/www/appName/
[wrxue@localhost ~]$ cd /var/www/appName/
[wrxue@localhost appName]$ dotnet appName.dll
  • appName:為應用程式名稱,請依實際情況做變更。

到目前為止,已經可以在伺服器 本身 的瀏覽器瀏覽 http://localhost:5000 囉。

設定 Nginx 為反向代理

讓原本的終端機 (Terminal) 繼續運行 ASP.NET Core 的應用程式,另外開啟 一個 Terminal 來操作以下動作,新增檔案 /etc/nginx/conf.d/appName.conf 且內容如下,完成後重啟 Nginx

1
2
3
4
5
6
7
8
9
10
11
12
13
server {
listen 80;
location / {
proxy_pass http://127.0.0.1:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
1
[wrxue@localhost ~]$ sudo systemctl restart nginx # 重啟 nginx

到目前為止,已經可以在 外部主機 的瀏覽器透過 http://{server_ip} 瀏覽 ASP.NET Core 應用程式囉。

允許外部直接連線 5000 Port

目前外部主機無法直接以 5000 Port 與 ASP.NET Core 應用程式連線,參考 [C#] 發布 ASP.NET Core 應用程式,可以看到 kestrel 只監聽 http://localhost:5000,所以只能接受 localhost 來的 request,而反向代理可以做到這件事則是因為透過 proxy_pass http://127.0.0.1:5000; 組態指令,將外來的 request 轉傳遞給本地端 (即 localhost) 5000 Port 的網頁應用程式,因此對 ASP.NET Core 應用程式來說,連線流量是來自於 localhost 而不是外部。

若想要讓本機以外的都能直接透過 5000 Port 與應用程式連線,就需要修改 Program.cs 的程式碼如下

1
2
3
4
5
6
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseUrls("http://*:5000").UseStartup<Startup>(); // 使用 UseUrls
});
很高興能在這裡幫助到您,歡迎登入 Liker 為我鼓掌 5 次,或者成為我的讚賞公民,鼓勵我繼續創造優質文章。
以最優質的內容回應您的鼓勵