我设置了一个 GitHub Actions 工作流程,它使用 RSA 密钥对通过 SSH 连接到我的 Linux 生产机器(该设置看起来有点像本教程,除了我试图为此创建一个专用的 Linux 用户,在我看来很喜欢)这将是一个很好的做法)。
在我的 Linux 机器上,我做了:
github
github
用户成为群组的一部分 www-data
www-data
组的用户可以读取、写入和执行)在 GitHub 存储库方面,我设置了秘密
SSH_PRIVATE_KEY
、SSH_HOST
和 SSH_USER
(即 github
)。
GitHub Actions 工作流程文件(工作流程中有趣的步骤)如下所示:
- name: Install SSH key
uses: shimataro/ssh-key-action@v2
with:
key: ${{ secrets.SSH_PRIVATE_KEY }}
name: id_rsa
known_hosts: ${{ secrets.SSH_HOST }}
- name: Adding known hosts
run: ssh-keyscan -H ${{ secrets.SSH_HOST }} >> ~/.ssh/known_hosts
- name: Copy repository to server with rsync
run: rsync -avz ./ ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:/home/www/my_project/ --usermap=github:www-data
当我将项目文件夹与
github
用户及其密钥对从本地计算机项目文件夹同步到我的生产服务器上的 /home/www/my_project/
进行测试时,一切正常。
但是,当我推送存储库并执行 GitHub Actions 工作流程时,rsync 步骤在许多文件上失败,项目的许多文件上出现以下错误:
rsync: [generator] failed to set times on "/home/www/my_project/app/templates/en": Operation not permitted (1)
为什么?
要做的第一个测试是检查您的
secrets.SSH_HOST
是否确实可以从 GitHub Cloud runner 访问
run: curl -v telnet://${{ secrets.SSH_HOST }}:443
(假设此处是 HTTPS URL,但将 443 端口替换为与您的 URL 相关的端口)
由于连接似乎有效,请尝试使用 GitHub Action 而不是直接
run:
进行相同的 rsync。jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: rsync deployments
uses: burnett01/[email protected]
with:
switches: -avzr --delete
path: ./
remote_path: /home/www/my_project/
remote_host: ${{ secrets.SSH_HOST }}
remote_user: ${{ secrets.SSH_USER }}
remote_key: ${{ secrets.DEPLOY_KEY }}
首先检查
-avzt --delete
选项,以确保它们适合您的用例。
经过几次尝试对比rsync前后服务器被覆盖文件的权限,发现GitHub Actions从repo复制过来的文件已经没有了组写权限,所以无法写入结束了。
所以我们只需要在复制时为复制的文件设置所有者、组、文件权限和目录权限,使它们保持与rsync之前完全相同的权限。我们将组
D
的目录 (F
) 和文件 (www-data
) 权限设置为 rwx
,以便 www-data
组中的相同用户可以稍后覆盖。总而言之,rsync 步骤变为:
- name: Copy repository to server with rsync
run: rsync -avz --chown=github:www-data --chmod=Dg=rwx,Fg=rwx ./ ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:/home/www/my_project/
希望对其他人有帮助!
编辑2023/03/01: 我们可能还需要忽略
.git
目录以避免覆盖它,因为即使它被 gitignored ,它仍然存在于 GitHub 的机器上。所以 rsync 步骤变成:
- name: Copy repository to server with rsync
run: rsync -avz --exclude '.git' --chown=github:www-data --chmod=Dg=rwx,Fg=rwx ./ ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:/home/www/my_project/