You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在GitHub Actions中自动执行git pull且不覆盖服务器专属配置文件?

GitHub Actions部署到Digital Ocean Droplet时,保留敏感配置文件不被Git覆盖的最佳实践

问题描述

我正在使用GitHub Actions将应用部署至Digital Ocean Droplet云服务器,当前遇到的核心问题是包含数据库凭证的config.json文件冲突:

  • 仓库中的config.json是占位符值,用于代码同步;
  • 服务器上的config.json存储真实敏感凭证,不希望被git pull操作覆盖。

我的GitHub Actions工作流核心代码如下:

name: Deploy to Droplet

on:
  push:
    branches:
      - main  # 推送至main分支时触发部署

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
    - name: Checkout code
      uses: actions/checkout@v3

    - name: Install sshpass
      run: sudo apt-get install sshpass

    - name: Deploy to Droplet
      run: |
        sshpass -p "${{ secrets.SSH_PASSWORD }}" ssh -o StrictHostKeyChecking=no root@208.189.185.180 << 'EOF'
          cd /root/automation
          git pull origin main
          # 重启应用或执行其他必要步骤
          # Example: systemctl restart your-app
        EOF

执行该工作流时,git pull会因仓库与服务器的config.json内容不一致产生冲突,手动解决不现实。我尝试过两种方案但都有弊端:

  • 将config.json加入.gitignore:导致仓库无法通过Git更新该文件的结构;
  • 使用git stash保存本地更改:恢复stash时仍可能引发冲突。

请问这类场景下的最佳实践是什么?有没有既能合并仓库更新,又能自动保留服务器专属配置的方法?


解决方案

针对这类敏感配置文件的部署冲突问题,有三种成熟的最佳实践,可根据你的场景选择:

1. 使用Git的assume-unchanged标记忽略本地修改

这是最简单的方案,适合配置文件结构不频繁变更的场景:

  • 原理:告诉Git忽略指定文件的本地修改,git pull时不会尝试覆盖该文件;
  • 操作步骤:
    1. 在Droplet服务器上执行一次:
      cd /root/automation
      git update-index --assume-unchanged config.json
      
    2. 修改GitHub Actions的部署脚本,处理配置结构变更的极端情况:
      - name: Deploy to Droplet
        run: |
          sshpass -p "${{ secrets.SSH_PASSWORD }}" ssh -o StrictHostKeyChecking=no root@208.189.185.180 << 'EOF'
            cd /root/automation
            # 临时取消标记,避免结构变更时的拉取冲突(忽略命令执行失败)
            git update-index --no-assume-unchanged config.json || true
            # 拉取代码,若配置文件冲突,优先保留仓库的结构版本
            git pull origin main --strategy-option theirs
            # 重新标记忽略本地修改
            git update-index --assume-unchanged config.json
            # 重启应用
            systemctl restart your-app
          EOF
      
  • 注意:如果仓库中config.json的结构(比如新增配置项)有变更,服务器上的文件会被仓库版本覆盖,之后需要手动补充敏感凭证,或者结合脚本自动合并。

2. 分离配置模板与本地配置

适合需要保留本地自定义配置,且文件结构可能频繁变更的场景:

  • 原理:仓库中存储配置模板(占位符),服务器上保留真实配置文件,部署时仅同步模板,不覆盖真实配置;
  • 操作步骤:
    1. 在仓库中将config.json重命名为config.json.template,提交并推送至Git;
    2. 在Droplet服务器上,将config.json加入本地.gitignore(或用assume-unchanged标记),避免Git追踪;
    3. 修改部署脚本,拉取代码后用模板更新本地配置(仅新增未存在的配置项):
      - name: Deploy to Droplet
        run: |
          sshpass -p "${{ secrets.SSH_PASSWORD }}" ssh -o StrictHostKeyChecking=no root@208.189.185.180 << 'EOF'
            cd /root/automation
            git pull origin main
            # 使用jq工具合并模板与本地配置(需先在服务器安装jq:apt install jq)
            jq -s '.[0] * .[1]' config.json.template config.json > temp.json && mv temp.json config.json
            # 重启应用
            systemctl restart your-app
          EOF
      
  • 优势:既同步了配置结构的更新,又保留了本地的敏感凭证,无需手动干预。

3. 通过GitHub Secrets动态生成配置文件

适合完全用密钥管理工具托管敏感信息,不希望服务器本地存储配置文件的场景:

  • 原理:将敏感配置存储在GitHub Secrets中,部署时在服务器上动态生成config.json;
  • 操作步骤:
    1. 在GitHub仓库的「Settings → Secrets and variables → Actions」中添加敏感字段(如DB_USER、DB_PASSWORD);
    2. 仓库中可以删除config.json,或保留一个不含敏感信息的模板;
    3. 修改部署脚本,动态生成配置文件:
      - name: Deploy to Droplet
        run: |
          sshpass -p "${{ secrets.SSH_PASSWORD }}" ssh -o StrictHostKeyChecking=no root@208.189.185.180 << EOF
            cd /root/automation
            git pull origin main
            # 生成包含敏感信息的config.json
            cat > config.json << 'EOL'
            {
              "db": {
                "user": "${{ secrets.DB_USER }}",
                "password": "${{ secrets.DB_PASSWORD }}"
              },
              "api_url": "https://your-production-api.com",
              "debug": false
            }
            EOL
            # 重启应用
            systemctl restart your-app
          EOF
      
  • 优势:敏感信息完全托管在GitHub Secrets中,服务器上不会残留明文凭证,安全性更高。

内容的提问来源于stack exchange,提问作者krishna vamsi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 07:28:10