Gitea Action 远程部署指南(实战四)

📝 前言

这是 DevOps 专题的第六篇,回顾一下前几篇的内容:

这一篇我们开始介绍如何使用 Gitea Actions(ssh-action)来完成远程部署,这是一种更为常见的部署方式。

🧭 背景介绍

Gitea Action 可用于自动化测试、打包构建,甚至是部署任务。

当代码合并到主分支时,可通过 Action 自动将代码部署到远程服务器,如生产环境、测试环境或内网机器,极大提升效率并降低人为失误。

📋 前提条件

在开始之前,请确保你已满足以下条件:

🚀 详细步骤

1️⃣ 下载离线 actions 和依赖

由于受到众所周知的网络环境影响,我们构建时使用的 action 并不能稳定下载,因此建议都手动下载,并上传到自己私有仓库中,这里在上一篇中也已经介绍过了。

另外ssh-action还依赖drone-ssh工具,也是需要我们下载并上传到私有的文件服务器上。

还有需要注意的是在推送官方action到自己的git仓库时,要把tag也一起推送,完整推送命令示例如下:

1
2
3
4
5
6
7
8
9
10
11
# 修改仓库地址为自己的git仓库
git remote set-url origin http://xxxxx.git

# 重命名分支(若原有分支为master可重命名为main)
git branch -m master main

# 推送代码
git push -u origin main

# 推送tags
git push --tags

2️⃣ 文件服务器配置

这里就简单的使用 nginx 快速搭建一个文件服务器即可,参考配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
server {
listen 80;
server_name lib.luhome.com;

location / {
# 文件存储路径
root /opt/lib;

# 启用自动索引,显示目录列表
autoindex on;

# 设置索引格式为详细列表
autoindex_format html;

# 显示文件大小(字节)
autoindex_exact_size off;

# 显示文件修改时间(本地时间)
autoindex_localtime on;

}
}

PS:这里我一般都是会在/etc/nginx/sites-available/创建.conf文件,然后通过软链接的方式进行启用:ln -s /etc/nginx/sites-available/xxx.conf /etc/nginx/sites-enabled/

创建文件服务目录并设置权限:

1
2
3
4
5
6
# 创建文件服务目录
mkdir -p /opt/lib/actions/appleboy-ssh-action/v1.8.1
# 设置权限
chown -R www-data:www-data /opt/lib
# 重启 Nginx 服务
sudo systemctl restart nginx

下载drone-ssh工具,并设置执行权限:

1
2
3
cd /opt/lib/actions/appleboy-ssh-action/v1.8.1/
wget https://github.com/appleboy/drone-ssh/releases/download/v1.8.1/drone-ssh-1.8.1-linux-amd64
chmod a+x drone-ssh-1.8.1-linux-amd64

3️⃣ 配置工作流

继续还是用上一篇文章的示例项目,修改.gitea/workflows/build.yaml文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
name: Build and Deploy Python Demo

on:
push:
branches: [ main ]
env:
# node
PATH: /opt/node/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
REGISTRY: harbor.luhome.com
IMAGE_NAME: lusyoe/python-workflow-demo
CONTAINER_NAME: python-workflow-demo
# 部署到远程的服务器地址
REMOTE_HOST: 192.168.10.1
# drone-ssh 工具离线下载
DRONE_SSH_RELEASE_URL: http://lib.luhome.com/actions/appleboy-ssh-action
DRONE_SSH_VERSION: 1.8.1

jobs:
build:
runs-on: host
outputs: # 声明作业的输出变量
datetime: ${{ steps.datetime.outputs.datetime }}
steps:
# 下载仓库源码
- name: Checkout repository
uses: http://git.luhome.com/actions/checkout@v4

# 登录镜像仓库,方便后续上传镜像
- name: Login to Docker Registry
uses: http://git.luhome.com/actions/docker-login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: admin
password: ${{ secrets.REGISTRY_PASSWD }}

# 获取时间戳,用于设置镜像 TAG 版本
- name: Get datetime
id: datetime
run: |
echo "datetime=$(date '+%Y-%m-%d-%H-%M-%S')" >> $GITHUB_OUTPUT

# 构建并上传镜像
- name: Build and push Docker image
uses: http://git.luhome.com/actions/docker-build-push-action@v5
with:
context: .
platforms: linux/amd64
file: Dockerfile
push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.datetime.outputs.datetime }}

deploy:
runs-on: host
needs: build
steps:
- name: Run remote commands via SSH
# 官方地址为:appleboy/ssh-action@v1
uses: http://git.luhome.com/actions/appleboy-ssh-action@v1
with:
host: ${{ env.REMOTE_HOST }} # 远程服务器 IP/Domain
username: root # SSH 用户名
key: ${{ secrets.PRIVATE_KEY }} # SSH 私钥(需提前添加到 Secrets)
script: |
DATETIME='${{ needs.build.outputs.datetime }}'
echo "DATETIME=${DATETIME}"
docker stop ${{ env.CONTAINER_NAME }} || true
docker rm ${{ env.CONTAINER_NAME }} || true
docker run -d --name ${{ env.CONTAINER_NAME }} -p 8000:8000 ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${DATETIME}

配置变更说明:

  • 环境变量: 这次我们新加了3个全局变量,分别为 REMOTE_HOSTDRONE_SSH_RELEASE_URLDRONE_SSH_VERSION,第1个就不用说是需要部署到远程的服务器地址,第2、3个是离线下载drone-ssh的环境变量,这个变量名称是不能改的,ssh-action 代码里面已写死。
  • deploy job: 这次我们在deploy job中新加了ssh-action的引用,方便我们更好的执行远程命令,当然你也可以直接使用 ssh 命令,只是没那么方便和优雅而已。
  • secrets: 我们在docker-login-actionssh-action中都引用到了secrets,这是为了安全起见,下面会介绍到如何创建secrets
  • script: 需要在远程执行的脚本命令,支持多行命令。

4️⃣ 创建 secrets

一般较为敏感的信息,如:密码、密钥、APIKEY等建议都使用secrets进行引用,避免信息泄露。

我们进入 Gitea 项目,点击设置 → Actions → 密钥 → Add secret 即可创建 secret,如下图所示:

值填写我们的SSH私钥,通常是在~/.ssh/id_xxx,注意是不带.pub后缀名的。

PS:这里需要提前将公钥添加到目标主机的~/.ssh/authorized_keys文件内。

镜像仓库密码也按同理进行创建即可,名称为:REGISTRY_PASSWD

✅ 总结

通过 Gitea Action 结合 SSH 和 Secrets,我们实现了一个小而美的自动化部署方案,完全自托管、无需依赖 GitHub/GitLab 等第三方平台。

另外 ssh-action 不只是支持密钥认证,同时也支持密码认证、多主机部署、代理连接等功能,详细可参看项目文档