Vercel 部署问题排查记录

Vercel 部署问题排查记录

📅 时间

2025-12-21

🎯 目标

将 Jekyll 博客项目部署到 Vercel


❌ 遇到的问题

问题 1:Git 推送被阻止 - GitHub Token 泄漏

错误信息:

error: GH013: Repository rule violations found for refs/heads/master.
- Push cannot contain secrets

GitHub Personal Access Token detected in:
- commit: cb4e8887e6bfa0e39035a2c96dc1756857d6bf15
  path: VERCEL_DEPLOYMENT.md:61
  path: VERCEL_DEPLOYMENT.md:124

原因:

  • VERCEL_DEPLOYMENT.md 文件中包含了真实的 GitHub Personal Access Token
  • GitHub 的安全扫描检测到并阻止了推送

解决方案:

  1. 创建备份分支:backup-before-cleanup
  2. 重置到远程分支:git reset --hard origin/master
  3. 从备份中恢复干净的文件(不含 Token)
  4. 重新提交并推送

关键命令:

git branch backup-before-cleanup
git reset --hard origin/master
git checkout backup-before-cleanup -- <files>
git commit -m "Add Vercel deployment configuration and documentation"
git push origin master

安全提示:

  • ✅ Token 从未真正泄漏到 GitHub(被安全扫描阻止)
  • ⚠️ 建议撤销该 Token 并创建新的

问题 2:Git 用户名不匹配

现象:

  • 本地 Git 配置用户名:rabbit8ge
  • 远程仓库所有者:pea1ce

解决方案:

git config --local user.name "pea1ce"
git config --local user.email "yipinghe87@163.com"

问题 3:Ruby 3.3 兼容性问题 - Bundler 1.16.0

错误信息:

/ruby33/lib/ruby/gems/3.3.0/gems/bundler-1.16.0/lib/bundler/shared_helpers.rb:266:in `search_up':
undefined method `untaint' for an instance of String (NoMethodError)

原因分析:

  1. Vercel 使用 Ruby 3.3
  2. untaint 方法在 Ruby 3.0+ 中已被移除
  3. Bundler 1.16.0 仍在使用这个方法

尝试的解决方案(未成功):

尝试 1:修改 buildCommand

// vercel.json
{
  "buildCommand": "gem install bundler && bundle update --bundler && bundle exec jekyll build"
}

失败原因: Vercel 仍然使用旧的 installCommand

尝试 2:删除 Gemfile.lock

git rm Gemfile.lock
git commit -m "Remove Gemfile.lock generated with Bundler 1.16.0"
git push

失败原因: Vercel 自动检测到 Jekyll 项目,使用默认的 gem install bundler(安装 1.16.0)


问题 4:Vercel 框架自动检测导致使用旧 Bundler

核心问题:

  • Vercel 检测到 Jekyll 项目后,使用内置的框架预设
  • 框架预设使用 gem install bundler(不指定版本)
  • 默认安装 Bundler 1.16.0
  • 即使删除了 Gemfile.lock,Vercel 仍会安装旧版本

最终解决方案:

修改 vercel.json,强制使用自定义构建流程:

{
  "framework": null,
  "installCommand": "gem install bundler:2.4.22",
  "buildCommand": "bundle install && bundle exec jekyll build",
  "outputDirectory": "_site",
  "rewrites": [
    { "source": "/api/(.*)", "destination": "/api/$1" }
  ],
  "headers": [
    {
      "source": "/api/(.*)",
      "headers": [
        { "key": "Cache-Control", "value": "no-store" }
      ]
    }
  ]
}

关键配置说明:

配置项 说明
framework null 禁用 Vercel 框架自动检测,强制使用自定义配置
installCommand gem install bundler:2.4.22 明确安装兼容 Ruby 3.3 的 Bundler 版本
buildCommand bundle install && bundle exec jekyll build 使用指定版本的 Bundler 构建 Jekyll
outputDirectory _site Jekyll 构建输出目录

✅ 最终提交历史

b819319 Force Vercel to use Bundler 2.4.22 to fix Ruby 3.3 compatibility
0a2020d Remove Gemfile.lock generated with Bundler 1.16.0
66d3eee Fix Ruby 3.3 compatibility: Update Bundler to latest version
21377a4 Add Vercel deployment configuration and documentation
d870587 Add interactive footprint management system with Vercel deployment

📚 技术要点总结

1. Vercel 框架检测机制

  • Vercel 会自动检测项目类型(Jekyll、Next.js 等)
  • 自动检测可能使用过时的构建配置
  • 使用 "framework": null 可以禁用自动检测

2. Ruby/Bundler 版本兼容性

  • Ruby 2.7: 最后支持 untaint 的版本
  • Ruby 3.0+: untaint 方法被移除
  • Bundler 1.x: 不兼容 Ruby 3.0+
  • Bundler 2.x: 完全支持 Ruby 3.0+

3. Gemfile.lock 的作用

  • 锁定依赖版本,确保一致性
  • 包含 BUNDLED WITH 字段,指定 Bundler 版本
  • 旧的 lockfile 会导致 Vercel 使用旧版 Bundler

4. Git 安全最佳实践

  • ✅ 永远不要将 Token、密码等敏感信息提交到仓库
  • ✅ 使用环境变量存储敏感配置
  • ✅ GitHub 的推送保护可以阻止 Token 泄漏
  • ✅ 定期审查提交历史中的敏感信息

🔍 排查技巧

如何定位 Vercel 构建问题:

  1. 查看完整构建日志
    • 在 Vercel Dashboard 中查看 Build Logs
    • 注意 “Running install command” 和 “Running build command”
  2. 检查使用的命令
    • 确认 Vercel 是否使用了你的自定义命令
    • 还是使用了框架预设的命令
  3. 检查版本信息
    Ruby version: 3.3.0
    Bundler version: 1.16.0 or 2.4.22
    
  4. 常见错误模式
    • undefined method 'untaint' → Bundler 版本太老
    • Gemfile.lock ... with 1.x.x → 需要删除或更新 lockfile
    • Command "..." exited with 1 → 检查构建命令是否正确

📝 相关文档


🎓 经验教训

  1. 总是使用 framework: null
    • 对于老项目或自定义构建流程
    • 避免 Vercel 自动检测导致的版本问题
  2. 明确指定依赖版本
    • 不要依赖默认版本
    • 使用 gem install bundler:2.4.22 而不是 gem install bundler
  3. 删除过时的 lockfile
    • 旧的 Gemfile.lock 可能导致兼容性问题
    • 让新环境重新生成 lockfile
  4. 安全第一
    • 使用环境变量存储 Token
    • 利用 GitHub 的安全扫描功能
    • 定期轮换 Token

🚀 成功部署后的配置

部署成功后,在 Vercel Dashboard 中配置环境变量:

变量名 说明 示例
GITHUB_TOKEN GitHub Personal Access Token ghp_xxxxxxxxxxxx
API_AUTH_TOKEN 管理员密码 your-password
GITHUB_OWNER GitHub 用户名 pea1ce
GITHUB_REPO 仓库名 pea1ce.github.io

文档创建时间: 2025-12-21 最后更新: 2025-12-21 状态: ✅ 问题已解决


附录:完整的 vercel.json 配置

{
  "framework": null,
  "installCommand": "gem install bundler:2.4.22",
  "buildCommand": "bundle install && bundle exec jekyll build",
  "outputDirectory": "_site",
  "rewrites": [
    { "source": "/api/(.*)", "destination": "/api/$1" }
  ],
  "headers": [
    {
      "source": "/api/(.*)",
      "headers": [
        { "key": "Cache-Control", "value": "no-store" }
      ]
    }
  ]
}

祝部署成功! 🎉