自动化部署编译部署【.net core】
github 自动化编译部署 .NET 程序,程序有两个服务,一个是api,一个是admin.
需要部署到两台机器上(测试和正式),所以采用两个Action来处理
项目目录结构
root
├── Config
│ ├── deploy
│ │ ├── nginx
│ │ │ ├── admin.conf
│ │ │ └── api.conf
│ │ ├── cert
│ │ │ ├── api.example.com.pem
│ │ │ ├── api.example.com.key
│ │ │ ├── admin.example.com.pem
│ │ │ └── admin.example.com.key
│ │ ├── supervisor
│ │ │ ├── admin.conf
│ │ │ └── api.conf
│ │ └── setting
│ │ ├── api.json
│ │ └── admin.json
│ └── deploy_test
│ ├── nginx
│ │ ├── testadmin.conf
│ │ └── testapi.conf
│ ├── cert
│ │ ├── testapi.example.com.pem
│ │ ├── testapi.example.com.key
│ │ ├── testadmin.example.com.pem
│ │ └── testadmin.example.com.key
│ ├── supervisor
│ │ ├── testadmin.conf
│ │ └── testapi.conf
│ └── setting
│ ├── testapi.json
│ └── testadmin.json
├── Admin
│ ├── appsettings.json
│ └── Admin.csproj
├── Api
│ ├── appsettings.json
│ └── Api.json
└── Website
├── static
└── index.html
不太好看的流程图
部署 Admin 服务的action
这里使用分支来做不同环境的部署,
deploy
从master
签出部署至正式机器,deploy_test
从dev
签出部署至测试机器,下面的action也只能从这两个分支中自动触发,其他的分支都可以手动触发流程,当然手动触发只支持部署至测试机器。
name: Deploy Admin
on:
push:
branches:
- deploy
- deploy_test
# paths:
# - "**.cs"
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: 7.0
- name: Restore dependencies
run: dotnet restore
- name: Publish
run: |
dotnet publish Admin/Web.Admin.csproj -c Release -o release/AdminServer
mkdir -p release/Config
- name: Copy Deploy Test File
if: github.ref != 'refs/heads/deploy'
run: |
cp -rf Config/deploy_test/* release/Config/
cp -f Config/deploy_test/setting/admin.json release/AdminServer/appsettings.json
- name: Copy Deploy File
if: github.ref == 'refs/heads/deploy' || github.ref == 'refs/heads/master'
run: |
cp -rf Config/deploy/* release/Config/
cp -f Config/deploy/setting/admin.json release/AdminServer/appsettings.json
- name: Tar AdminServer
run: tar -czvf AdminServer.tar.gz -C release .
- name: Deploy To TEST
uses: cross-the-world/ssh-scp-ssh-pipelines@v1.1.4
if: github.ref != 'refs/heads/deploy' && github.ref != 'refs/heads/master'
with:
host: ${{ secrets.DEPLOY_TEST_SSH_HOST}}
port: ${{ secrets.SSH_PORT }}
user: ${{ secrets.SSH_USER }}
key: ${{ secrets.SSH_KEY }}
first_ssh: |
rm -f /home/shop/AdminServer.tar.gz
mkdir -p /home/shop/logs/
scp: |
AdminServer.tar.gz => /home/shop/
last_ssh: |
cd /home/shop/
tar -xzvf AdminServer.tar.gz --overwrite
ln -sf /home/shop/Config/supervisor/admin_service.conf /etc/supervisor/conf.d/shop_admin.conf
ln -sf /home/shop/Config/nginx/shop.conf /etc/nginx/sites-enabled/admin_nginx.conf
supervisorctl reread
supervisorctl update
supervisorctl restart adminserver
- name: Deploy To PROD
uses: cross-the-world/ssh-scp-ssh-pipelines@v1.1.4
if: github.ref == 'refs/heads/deploy' || github.ref == 'refs/heads/master'
with:
host: ${{ secrets.DEPLOY_SSH_HOST}}
port: ${{ secrets.SSH_PORT }}
user: ${{ secrets.SSH_USER }}
key: ${{ secrets.SSH_KEY }}
first_ssh: |
rm -f /home/shop/AdminServer.tar.gz
mkdir -p /home/shop/logs/
scp: |
AdminServer.tar.gz => /home/shop/
last_ssh: |
cd /home/shop/
tar -xzvf AdminServer.tar.gz --overwrite
ln -sf /home/shop/Config/supervisor/admin_service.conf /etc/supervisor/conf.d/shop_admin.conf
ln -sf /home/shop/Config/nginx/shop.conf /etc/nginx/sites-enabled/admin_nginx.conf
supervisorctl reread
supervisorctl update
supervisorctl restart adminserver
nginx -s reload
部署 Api 服务的action
内容其实更 Admin 大同小异啦
name: Deploy Api
on:
push:
branches:
- deploy
- deploy_test
# paths:
# - "**.cs"
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: 7.0
- name: Restore dependencies
run: dotnet restore
- name: Publish
run: |
dotnet publish WebApi/WebApi.csproj -c Release -o release/ApiServer
mkdir -p release/Config
- name: Copy Deploy Test File
if: github.ref != 'refs/heads/deploy' && github.ref != 'refs/heads/master'
run: |
cp -rf Config/deploy_test/* release/Config/
cp -f Config/deploy_test/setting/api.json release/ApiServer/appsettings.json
- name: Copy Deploy File
if: github.ref == 'refs/heads/deploy' || github.ref == 'refs/heads/master'
run: |
cp -rf Config/deploy/* release/Config/
cp -f Config/deploy/setting/api.json release/ApiServer/appsettings.json
- name: Tar ApiServer
run: tar -czvf ApiServer.tar.gz -C release .
- name: Deploy To TEST
uses: cross-the-world/ssh-scp-ssh-pipelines@v1.1.4
if: github.ref != 'refs/heads/deploy' && github.ref != 'refs/heads/master'
with:
host: ${{ secrets.DEPLOY_TEST_SSH_HOST}}
port: ${{ secrets.SSH_PORT }}
user: ${{ secrets.SSH_USER }}
key: ${{ secrets.SSH_KEY }}
first_ssh: |
rm -f /home/shop/ApiServer.tar.gz
mkdir -p /home/shop/logs/
scp: |
ApiServer.tar.gz => /home/shop/
last_ssh: |
cd /home/shop/
tar -xzvf ApiServer.tar.gz --overwrite
ln -sf /home/shop/Config/supervisor/api_service.conf /etc/supervisor/conf.d/shop_api.conf
ln -sf /home/shop/Config/nginx/api.conf /etc/nginx/sites-enabled/api_nginx.conf
supervisorctl reread
supervisorctl update
supervisorctl restart apiserver
- name: Deploy To PROD
uses: cross-the-world/ssh-scp-ssh-pipelines@v1.1.4
if: github.ref == 'refs/heads/deploy' || github.ref == 'refs/heads/master'
with:
host: ${{ secrets.DEPLOY_SSH_HOST}}
port: ${{ secrets.SSH_PORT }}
user: ${{ secrets.SSH_USER }}
key: ${{ secrets.SSH_KEY }}
first_ssh: |
rm -f /home/shop/ApiServer.tar.gz
mkdir -p /home/shop/logs/
scp: |
ApiServer.tar.gz => /home/shop/
last_ssh: |
cd /home/shop/
tar -xzvf ApiServer.tar.gz --overwrite
ln -sf /home/shop/Config/supervisor/api_service.conf /etc/supervisor/conf.d/shop_api.conf
ln -sf /home/shop/Config/nginx/api.conf /etc/nginx/sites-enabled/api_nginx.conf
supervisorctl reread
supervisorctl update
supervisorctl restart apiserver
nginx -s reload
后期优化的地方
- 每次部署的时候 都需要重新编译代码,就算只改了配置文件,部署一次需要两分半, 考虑使用 paths-filter 优化。
- 后期一台机器撑不住的时候如何多台机器同时部署。
暂时考虑在正式机器部署完成之后,ssh 通过内网把文件传输到其他机器上面重启服务,但是又要考虑到部署不成功, 如何通知?并快速的回退上次部署?