使用GitHub Actions自托管Runner部署Next.js:非NEXT_PUBLIC秘钥失效
问题原因
Next.js中,带NEXT_PUBLIC_前缀的变量会在构建时被注入到客户端代码中,而非前缀变量仅在服务器端运行时生效。你的工作流里,这些非前缀变量只存在于GitHub Actions的构建步骤环境中,当用pm2 restart重启应用时,pm2管理的Node.js进程无法获取到这些变量——因为GitHub Actions的环境变量不会自动传递到服务器的持久运行环境里。
另外,你工作流里的Switch to the Project Directory步骤是无效的:每个run步骤都是独立的shell会话,cd命令只在当前步骤生效,后续的pm2 restart还是会在默认目录执行,可能导致pm2找不到正确的应用配置。
解决方案
方案1:生成.env.production文件(推荐)
Next.js会自动读取项目根目录的.env.production文件作为生产环境变量。在工作流中添加步骤,将所有密钥写入该文件,确保应用运行时能加载到变量:
修改工作流的步骤,在npm ci之后、npm run build之前添加写入环境变量的步骤:
- run: npm ci - name: Create production env file run: | echo "NEXT_PUBLIC_BASE_URL=${{secrets.NEXT_PUBLIC_BASE_URL}}" >> .env.production echo "NEXT_PUBLIC_COMMENT_URL=${{secrets.NEXT_PUBLIC_COMMENT_URL}}" >> .env.production echo "NEXT_PUBLIC_COMMENT_LIST_URL=${{secrets.NEXT_PUBLIC_COMMENT_LIST_URL}}" >> .env.production echo "NEXT_PUBLIC_WEBINAR_REGISTER_URL=${{secrets.NEXT_PUBLIC_WEBINAR_REGISTER_URL}}" >> .env.production echo "GOOGLE_CLIENT_ID=${{secrets.GOOGLE_CLIENT_ID}}" >> .env.production echo "GOOGLE_CLIENT_SECRET=${{secrets.GOOGLE_CLIENT_SECRET}}" >> .env.production echo "NEXTAUTH_URL=${{secrets.NEXTAUTH_URL}}" >> .env.production echo "SECRET=${{secrets.SECRET}}" >> .env.production - run: npm run build --if-present
同时确保项目的.gitignore文件中包含.env.production,避免敏感信息被提交到仓库:
.env.production
方案2:修正pm2重启步骤的工作目录
删除无效的Switch to the Project Directory步骤,改用working-directory参数指定pm2操作的目录:
- name: Restart app with pm2 working-directory: /home/xxxxx/actions-runner/_work/yyyy/yyyy run: pm2 restart 1
额外注意事项
- 如果你使用的是Next.js的静态导出(
next export),非NEXT_PUBLIC_变量完全无法被客户端或静态产物读取,这种情况下需要确认你的应用是否依赖服务器端渲染或API路由来使用这些变量。 - 确保自托管Runner的用户权限足够写入项目目录的
.env.production文件,避免因权限问题导致文件创建失败。
内容的提问来源于stack exchange,提问作者DevolamiTech
相关产品推荐
相关产品推荐

