7

使用Nginx在 Linux 上托管 ASP.NET Core 6.0应用:GitHub Actions自动部署 - 几秋

 1 year ago
source link: https://www.cnblogs.com/netry/p/aspnetcore6-linux-nginx-github-actions-systemd.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

使用Nginx在 Linux 上托管 ASP.NET Core 6.0应用:GitHub Actions自动部署

本文主要参考微软这篇文档而来 Host ASP.NET Core on Linux with Nginx,并使用Github Actions做CI&CD,部署到阿里云服务器,所有步骤均亲测可用。

  • Linux云服务器(本文使用的是阿里云Ubantu 22.04 64位)
  • SSH客户端(我使用的XShell, 官网 可以下载免费的家庭/学校版)
  • Github账号以及能流畅访问^

使用VS2022新建一个空的ASP.NET Core Web API项目,框架选择.Net 6.0。
因为需要使用Nginx,这里就简单配置中间件转发下 X-Forwarded-For X-Forwarded-Proto 两个header。

using Microsoft.AspNetCore.HttpOverrides;

...

app.UseForwardedHeaders(new ForwardedHeadersOptions
{
    ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});

app.UseAuthentication();

本地启动一下,看到swagger页面,没什么问题。代码提交Github,接下来开始配置服务器.

服务器配置

所有包均使用 apt 命令进行安装,如果安装过程提示 Unable to locate package 错误,请先执行如下命令后,再重新安装。

sudo apt update

安装ASP.Net Core运行时

由于我们是部署应用,只需在服务器上安装运行时即可,无需安装.net sdk

sudo apt install -y aspnetcore-runtime-6.0

查看是否安装成功:

dotnet --info

安装配置 Nginx

安装Nginx

sudo apt install nginx

编辑Nginx配置文件

vim /etc/nginx/sites-available/default

Esc进入命令模式,gg跳至首行,然后dG,清空当前配置,复制粘贴下面的配置。

server {
    listen        80;
    server_name   example.com *.example.com;
    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;
    }
}

退出并且保存 (Esc + :wq ,然后回车)
测试配置是否正确:

sudo nginx -t

没问题之后,让Nginx重新加载配置

sudo nginx -s reload

用户及权限

创建一个账号等下给Github Actions使用,总不能给它用root账号

sudo adduser github

创建一个文件夹,后面发布后的文件就上传到这里

sudo mkdir -p /home/project/example

给新账号添加该文件夹的读写权限

sudo chown -R github /home/project/example

到这里其实可以手动上传发布文件到服务器测试一下,但是为了省时间还是跳过,直接用Github Actions来发布。

Github Actions 配置

打开Github仓库,选择如下官方提供的.NET工作流进入编辑页面

image

使用如下配置:

name: ASP.NET Core 6.0 Example build and deploy
  
on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]

jobs:

  build:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v3
    - name: Setup .NET
      uses: actions/setup-dotnet@v2
      with:
        dotnet-version: 6.0.x
        
    - name: Restore dependencies
      run: dotnet restore
      
    - name: Build package
      run: dotnet publish ./src/example -c Release -r linux-x64 --self-contained false -o deploy
      
    - name: Upload package
      uses: garygrossgarten/[email protected]
      with:
        host: ${{ secrets.REMOTE_HOST }}
        username: ${{ secrets.REMOTE_USER }}
        password: ${{ secrets.REMOTE_PWD }}
        port: 22
        local: /home/runner/work/playground/example/deploy/
        remote: "/home/project/example/"

当main分支有提交或者PR时,发布就会触发;还有几个需要说明的地方,

  • 关于打包,这里指定了 --self-contained false,是为了减少发布的dll文件,更多publish命令,可以参考 .NET application publishing overview
  • 你可能已经注意到yml文件有很多secrets参数,这是在仓库如下处进行配置
    image
  • REMOTE_HOST是服务器地址,REMOTE_USER就是上面新创建的账号github,我这里使用的是 garygrossgarten/github-action-scp SSH上传文件到服务器,更多用法说明,直接参考文档。

提交yml文件,打开Actions,查看执行情况,可以看到已经完成了

image

检查下服务器是不是已经有发布文件了

cd /home/project/example
ls -l
image

手动运行一下,

dotnet example.dll

可以看到,外网已经可以访问了

image

如果不能访问,在阿里云控制台检查安全组规则,是否添加了80端口。

image

如果还是不能访问,检查一下服务器的防火墙,将80端口添加进去。

ufw status
ufw allow 80

systemd 守护进程

为了让服务在崩溃或者服务器重启之后,也能重新运行,这里使用systemd来管理我们的服务。
创建服务定义文件:

sudo nano /etc/systemd/system/dotnet-example.service

使用如下配置,Ctrl + X 退出保存。

[Service]
WorkingDirectory=/home/project/example
ExecStart=/usr/bin/dotnet /home/project/example/example.dll
Restart=always
# Restart service after 5 seconds if the dotnet service crashes:
RestartSec=5
KillSignal=SIGINT
SyslogIdentifier=dotnet-example
User=root
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false
[Install]
WantedBy=multi-user.target

服务启用、启动、查看状态:

sudo systemctl daemon-reload
sudo systemctl enable dotnet-example.service
sudo systemctl start dotnet-example.service
sudo systemctl status dotnet-example.service
image

最后更新Github Actions,将如下配置添加到末尾,这里使用的是同一个人的另一个项目来执行远程命令 garygrossgarten/github-action-ssh

    - name: Restart dotnet-example.service
      uses: garygrossgarten/[email protected]
      with:
        command: sudo systemctl restart dotnet-example.service; cd /home/project/example; ls -l
        host: ${{ secrets.REMOTE_HOST }}
        username: ${{ secrets.REMOTE_USER }}
        password: ${{ secrets.REMOTE_PWD }}

配置生效,发布成功:

image

本文完整介绍了如何使用Github Actions做CI&CD(感叹一下,免费的Github Actions太良心了,很方便个人项目或者私活,你完全可以只准备应用服务器),将ASP.NET Core 6.0 程序部署到阿里云Ubantu服务器,并使用Nginx作为web服务器,systemd做守护进程。虽然现在k8s已经很普及,并且很多公司都基本有专门DevOps团队维护CI&CD,程序员只需专注业务代码开发。但是了解并实操一遍整个过程还是很有益处的,特别是对新手。很多未知的坑,实践之前你永远不知道;就像以前也不知道写博客还挺累(整个搭建流 程前前后后完整重复了三遍,服务器都重置了好几回^)

任何问题或者建议,欢迎评论区留言讨论~


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK