如何用GitHub Actions从VPS下载PostgreSQL备份并保存为工件?
我正在使用appleboy/ssh-action连接VPS,为Docker中的PostgreSQL数据库生成SQL备份文件。现在想把这个文件下载到GitHub Actions环境,再用actions/upload-artifact上传为工件,但不知道怎么实现文件下载。另外,如果这种方式不是最优解,正确的备份生成与工件上传流程应该是怎样的?
当前已有的GitHub Actions步骤:
jobs: backup-db: runs-on: ubuntu-latest steps: - name: Dump database uses: appleboy/ssh-action@v1.0.3 env: POSTGRES_MAIN_DB_DOCKER_CONTAINER_NAME: ${{ env.POSTGRES_MAIN_DB_DOCKER_CONTAINER_NAME }} POSTGRES_MAIN_USER: ${{ env.POSTGRES_MAIN_USER }} POSTGRES_MAIN_DB_NAME: ${{ env.POSTGRES_MAIN_DB_NAME }} with: host: ${{ secrets.VPS_HOST }} port: ${{ secrets.VPS_PORT }} username: ${{ secrets.VPS_USERNAME }} key: ${{ secrets.VPS_KEY }} envs: POSTGRES_MAIN_DB_DOCKER_CONTAINER_NAME,POSTGRES_MAIN_USER,POSTGRES_MAIN_DB_NAME script: | docker exec ${POSTGRES_MAIN_DB_DOCKER_CONTAINER_NAME} pg_dump -U ${POSTGRES_MAIN_USER} ${POSTGRES_MAIN_DB_NAME} > postgres_backup/backup_$(date +'%Y-%m-%d_%H-%M-%S').sql
计划在下载文件后执行的步骤:
- name: Archive database dump uses: actions/upload-artifact@v3 with: name: latest-dump.sql.bz2 path: latest-dump.sql.bz2 if-no-files-found: error retention-days: 14
方案一:从VPS下载备份文件到Actions环境
可以使用和ssh-action同作者的appleboy/scp-action实现文件下载,步骤如下:
修改备份脚本,记录备份文件名
在ssh-action的script中,先定义固定格式的备份文件名,并存入GitHub环境变量,方便后续步骤引用:script: | BACKUP_FILE="postgres_backup/backup_$(date +'%Y-%m-%d_%H-%M-%S').sql" docker exec ${POSTGRES_MAIN_DB_DOCKER_CONTAINER_NAME} pg_dump -U ${POSTGRES_MAIN_USER} ${POSTGRES_MAIN_DB_NAME} > ${BACKUP_FILE} echo "BACKUP_FILE=${BACKUP_FILE}" >> $GITHUB_ENV添加SCP下载步骤
通过scp-action把VPS上的备份文件下载到Actions Runner的当前目录:- name: Download backup from VPS uses: appleboy/scp-action@v0.1.4 with: host: ${{ secrets.VPS_HOST }} port: ${{ secrets.VPS_PORT }} username: ${{ secrets.VPS_USERNAME }} key: ${{ secrets.VPS_KEY }} source: ${{ env.BACKUP_FILE }} target: ./可选:压缩备份文件
如果需要压缩节省存储空间,执行压缩命令:- name: Compress backup file run: bzip2 ${{ env.BACKUP_FILE }}执行工件上传
修改上传步骤的path参数,匹配实际的备份文件名:- name: Archive database dump uses: actions/upload-artifact@v3 with: name: latest-dump.sql.bz2 path: ${{ env.BACKUP_FILE }}.bz2 if-no-files-found: error retention-days: 14
方案二:直接输出备份内容到Actions环境(更优)
不需要在VPS生成文件再下载,直接把pg_dump的输出通过SSH传输到Actions Runner本地,省去中间文件存储和下载环节:
修改SSH步骤,直接输出备份内容
去掉VPS上的文件写入操作,让pg_dump的输出直接通过stdout返回给Actions:- name: Dump database to stdout uses: appleboy/ssh-action@v1.0.3 env: POSTGRES_MAIN_DB_DOCKER_CONTAINER_NAME: ${{ env.POSTGRES_MAIN_DB_DOCKER_CONTAINER_NAME }} POSTGRES_MAIN_USER: ${{ env.POSTGRES_MAIN_USER }} POSTGRES_MAIN_DB_NAME: ${{ env.POSTGRES_MAIN_DB_NAME }} id: pg_dump with: host: ${{ secrets.VPS_HOST }} port: ${{ secrets.VPS_PORT }} username: ${{ secrets.VPS_USERNAME }} key: ${{ secrets.VPS_KEY }} envs: POSTGRES_MAIN_DB_DOCKER_CONTAINER_NAME,POSTGRES_MAIN_USER,POSTGRES_MAIN_DB_NAME script: | docker exec ${POSTGRES_MAIN_DB_DOCKER_CONTAINER_NAME} pg_dump -U ${POSTGRES_MAIN_USER} ${POSTGRES_MAIN_DB_NAME}将输出写入本地文件(可选压缩)
把SSH步骤的stdout输出写入本地文件,直接压缩可以一步完成:- name: Save and compress dump run: echo "${{ steps.pg_dump.outputs.stdout }}" | bzip2 > latest-dump.sql.bz2执行工件上传
直接使用你原本计划的上传步骤即可,因为文件已经在Actions Runner本地。
注意:如果备份文件体积过大,直接用stdout传输可能触发GitHub Actions的输出大小限制,这种情况下优先选择方案一的SCP下载方式。
内容的提问来源于stack exchange,提问作者Nelson Sousa

