这是为了赋予该用户某些高权限操作,且不会赋予太多权限,保证服务器安全

# 1. 创建用户(无密码,避免本地密码登录)
sudo adduser --disabled-password --gecos "" ghactions

# 2. 创建 .ssh 目录
sudo mkdir -p /home/ghactions/.ssh

# 3. 权限收紧
sudo chown -R ghactions:ghactions /home/ghactions/.ssh
sudo chmod 700 /home/ghactions/.ssh

然后为 github actions 创建私钥用于github action 远程登录

# 切换至用户
sudo su ghactions
# 生成公私钥
ssh-keygen -t ed25519 -C "github-actions" -f ~/.ssh/id_ed25519
# 查看公钥,复制到剪贴板:
cat ~/.ssh/id_ed25519.pub
# 切换回原用户
su <原用户名>
# 执行赋予权限
sudo bash -c 'echo "这里换成你的公钥内容" >> /home/ghactions/.ssh/authorized_keys'
sudo chown ghactions:ghactions /home/ghactions/.ssh/authorized_keys
sudo chmod 600 /home/ghactions/.ssh/authorized_keys

为 ghactions 赋予特定操作的权限

sudo visudo -f /etc/sudoers.d/ghactions-nginx

赋予重启 nginx 的无密码 sudo 权限

# 粘贴以下内容
ghactions ALL=(root) NOPASSWD: /usr/sbin/nginx -t, /usr/sbin/nginx -s reload, /bin/systemctl reload nginx

不过有可能你的 nginx 不是这个路径,请确认一下

which nginx
# 例子输出:/usr/sbin/nginx

接下来测试其权限

# 切换到这个用户
sudo -iu ghactions

# 测试能不能无密码 sudo
sudo nginx -t
sudo nginx -s reload
# 或者
sudo systemctl reload nginx

下一步是在 Github 仓库中配置我们设置的 Secrets,在如下位置逐个添加即可 CleanShot 2025-12-09 at 19.22.33@2x.png

这里附上对应的 workflow/deploy.yml

...
	runs:
      - name: Prepare SSH key
        env:
          SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
        run: |
          mkdir -p ~/.ssh
          echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_ed25519
          chmod 600 ~/.ssh/id_ed25519

          eval $(ssh-agent -s)
          ssh-add ~/.ssh/id_ed25519

      - name: Upload build to server
        env:
          SSH_HOST: ${{ secrets.SSH_HOST }}
          SSH_USER: ${{ secrets.SSH_USER }}
          SSH_PORT: ${{ secrets.SSH_PORT }}
          TARGET_DIR: ${{ secrets.DEPLOY_TARGET_DIR }}
        run: |
          SSH_PORT=${SSH_PORT:-22}

          ssh-keyscan -p "$SSH_PORT" "$SSH_HOST" >> ~/.ssh/known_hosts

          rsync -avz --delete -e "ssh -p $SSH_PORT" dist/ "$SSH_USER@$SSH_HOST:$TARGET_DIR/"

      - name: Reload nginx
        env:
          SSH_HOST: ${{ secrets.SSH_HOST }}
          SSH_USER: ${{ secrets.SSH_USER }}
          SSH_PORT: ${{ secrets.SSH_PORT }}
        run: |
          SSH_PORT=${SSH_PORT:-22}
          ssh -p "$SSH_PORT" "$SSH_USER@$SSH_HOST" "sudo systemctl reload nginx"