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

Docker容器间Next.js调用GraphQL服务时Apollo useQuery请求失败

问题解决:Next.js客户端无法访问Docker化的GraphQL服务(ERR_NAME_NOT_RESOLVED)

问题根源

核心矛盾在于服务器端与客户端的网络环境不统一:

  • NextAuth、getServerSideProps运行在Next.js容器内部,属于Docker共享网络,能通过容器名node正常访问GraphQL服务。
  • 但useQuery在用户浏览器中执行(客户端环境),浏览器不在Docker网络范围内,无法解析node这个Docker内部主机名,因此抛出ERR_NAME_NOT_RESOLVED错误。

解决方案

通过区分服务端/客户端的Apollo配置 + Nginx反向代理解决,步骤如下:

1. 修改ApolloClient配置,适配双环境

在Next.js中,通过typeof window === 'undefined'判断运行环境,服务器端用Docker内部地址访问GraphQL,客户端用相对路径交由Nginx转发:

function createLink(session?: Session | null) {
  // 判断是否为服务器端环境
  const isServer = typeof window === 'undefined';
  // 服务器端用Docker内部服务地址,客户端用相对路径
  const authUrl = isServer 
    ? "http://node_app:4000/graphql" 
    : "/graphql";

  const httpLink = new HttpLink({
    uri: authUrl,
  });

  const authLink = new ApolloLink((operation, forward) => {
    operation.setContext(({ headers = {} }) => ({
      headers: {
        ...headers,
        ...(session?.accessToken
          ? { Authorization: `Bearer ${session?.accessToken}` }
          : {}),
      },
    }));
    return forward(operation);
  });

  return ApolloLink.from([authLink, httpLink]);
}

const createApolloClient = (session?: Session | null) => {
  return new ApolloClient({
    link: createLink(session),
    cache: new InMemoryCache(),
  });
};

2. 修正Nginx配置,正确转发请求

之前的Nginx配置用localhost:4000是错误的——Nginx容器内部的localhost指向自身,而非宿主机器。需改用Docker服务名node_app访问GraphQL服务,同时配置Next.js请求转发:

server {
  listen 80;

  # 转发所有Next.js页面请求到next_app容器
  location / {
    proxy_pass http://next_app:3000;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
  }

  # 转发GraphQL请求到node_app容器
  location /graphql {
    proxy_pass http://node_app:4000/graphql;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    # 确保Authorization等请求头被正确传递
    proxy_pass_request_headers on;
  }
}

3. Docker Compose配置优化(可选)

可以关闭next_app的3000端口对外暴露,所有请求统一通过Nginx转发:

next_app:
  build: ./next
  container_name: next
  # 移除对外的3000端口映射
  # ports:
  #   - 3000:3000
  networks:
    - postgres-db-network
  volumes:
    - ./next:/app
    - /app/node_modules
    - /app/.next
  depends_on:
    - node_app
  environment:
    - NODE_ENV=development

方案原理

  • 服务器端:Next.js容器处于Docker网络内,通过node_app:4000直接访问GraphQL服务,原有认证逻辑保持正常运行。
  • 客户端:浏览器通过相对路径/graphql发送请求,Nginx将请求转发到GraphQL服务,既避免了跨域问题,也解决了Docker主机名无法解析的问题,同时Authorization令牌会被正确传递。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 05:05:58