Jenkins CD部署Next.js时getServerSideProps出现401错误,需配置Nginx?
我给基于NextJS、apollo-graphql、prisma的全栈网站搭建了CI/CD流程,服务器上安装了Jenkins、Nginx和pm2用于启停服务。用root用户启动服务器时,前端获取数据一切正常;但换成jenkins用户运行Jenkins节点执行任务后,虽然任务能正常从GitHub拉取代码、安装依赖、构建并通过pm2启动网站,但无服务端数据请求的页面可正常访问,使用getServerSideProps进行服务端数据获取的页面却显示500错误,服务器日志报错如下:
2|mywebsite | ApolloError: Unexpected token < in JSON at position 0 2|mywebsite | at new ApolloError (/home/jenkins/workspace/mywebsite/node_modules/@apollo/client/errors/errors.cjs:34:28) 2|mywebsite | at /home/jenkins/workspace/mywebsite/node_modules/@apollo/client/core/core.cjs:1658:19 2|mywebsite | at both (/home/jenkins/workspace/mywebsite/node_modules/@apollo/client/utilities/utilities.cjs:985:53) 2|mywebsite | at /home/jenkins/workspace/mywebsite/node_modules/@apollo/client/utilities/utilities.cjs:978:72 2|mywebsite | at new Promise (<anonymous>) 2|mywebsite | at Object.then (/home/jenkins/workspace/mywebsite/node_modules/@apollo/client/utilities/utilities.cjs:978:24) 2|mywebsite | at Object.error (/home/jenkins/workspace/mywebsite/node_modules/@apollo/client/utilities/utilities.cjs:986:49) 2|mywebsite | at notifySubscription (/home/jenkins/workspace/mywebsite/node_modules/zen-observable/lib/Observable.js:140:18) 2|mywebsite | at onNotify (/home/jenkins/workspace/mywebsite/node_modules/zen-observable/lib/Observable.js:179:3) 2|mywebsite | at SubscriptionObserver.error (/home/jenkins/workspace/mywebsite/node_modules/zen-observable/lib/Observable.js:240:7) { 2|mywebsite | graphQLErrors: [], 2|mywebsite | clientErrors: [], 2|mywebsite | networkError: SyntaxError [ServerParseError]: Unexpected token < in JSON at position 0 2|mywebsite | at JSON.parse (<anonymous>) 2|mywebsite | at /home/jenkins/workspace/mywebsite/node_modules/@apollo/client/link/http/http.cjs:18:25 2|mywebsite | at runMicrotasks (<anonymous>) 2|mywebsite | at processTicksAndRejections (node:internal/process/task_queues:96:5) { 2|mywebsite | response: Response { 2|mywebsite | size: 0, 2|mywebsite | timeout: 0, 2|mywebsite | [Symbol(Body internals)]: [Object], 2|mywebsite | [Symbol(Response internals)]: [Object] 2|mywebsite | }, 2|mywebsite | statusCode: 401, 2|mywebsite | bodyText: '<html>\n' + 2|mywebsite | '<head><title>401 Authorization Required</title></head>\n' + 2|mywebsite | '<body>\n' + 2|mywebsite | '<center><h1>401 Authorization Required</h1></center>\n' + 2|mywebsite | '<hr><center>nginx/1.18.0</center>\n' + 2|mywebsite | '</body>\n' + 2|mywebsite | '</html>\n' 2|mywebsite | }, 2|mywebsite | extraInfo: undefined 2|mywebsite | }
从日志里的statusCode: 401和Nginx返回的401授权HTML页面可以明确:服务端在getServerSideProps中请求GraphQL接口时被Nginx拦截,返回了HTML格式的授权错误页,而Apollo客户端期望接收JSON格式数据,因此解析时出现Unexpected token < in JSON at position 0的错误。需要针对Nginx或服务端请求配置调整:
优先调整服务端请求地址:如果NextJS服务端是向自身的GraphQL接口请求,直接用
localhost或内网IP+端口访问,绕过Nginx的外部授权验证。比如把Apollo客户端在服务端的请求地址从域名改为http://localhost:3000/api/graphql(根据你的实际接口路径和服务端口调整)。修改Nginx配置放行内部请求:如果必须通过Nginx转发请求,在Nginx的站点配置中,给GraphQL接口路径添加内部IP白名单,跳过授权验证:
location /api/graphql { # 保留原有的反向代理等配置 proxy_pass http://localhost:3000; # 放行本地服务端请求 allow 127.0.0.1; allow ::1; deny all; # 如果原本配置了Basic Auth,添加以下规则允许内部请求跳过验证 satisfy any; auth_basic "Restricted"; auth_basic_user_file /path/to/your/.htpasswd; }
- 检查jenkins用户权限:确认jenkins用户能读取项目的环境变量(比如GraphQL接口地址、凭证等),确保服务端请求时能获取到正确的配置参数。
内容的提问来源于stack exchange,提问作者kamal951

