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

Docker环境下Vike/React应用SSR路由失败排查求助

解决Vike/React SSR在Docker环境下API请求失败的问题

核心问题分析

本地SSR正常但Docker环境下失效,且客户端导航正常、刷新报错,本质是SSR阶段(容器内Node进程)无法连接后端API——客户端请求从浏览器发起(走宿主机/外部网络),而SSR请求是容器内Node进程发起的,二者网络环境存在差异,这是问题的核心。

具体排查与修复步骤

1. 确认Docker容器间的网络连通性

  • 若使用Docker Compose,默认会为所有服务创建共享网络,此时必须用后端容器名作为API地址,而非localhost/127.0.0.1(容器内的localhost指向自身,而非宿主机)。
  • 直接在Vike容器内测试连通性:
    # 进入Vike容器
    docker exec -it <vike-container-name> sh
    # 测试后端API是否可达
    curl http://<backend-container-name>:<backend-port>/api/blog
    
    如果返回连接拒绝,先检查后端服务是否正常启动,同时确认后端服务监听地址是0.0.0.0而非127.0.0.1(后者仅允许容器内部访问)。

2. 区分SSR与客户端的Axios baseURL

SSR运行在Node环境(容器内),客户端运行在浏览器,必须动态配置API地址:

// src/lib/api.js
import axios from 'axios';

// 根据运行环境切换baseURL
const api = axios.create({
  baseURL: typeof window === 'undefined' 
    ? 'http://backend:3000/api' // SSR用容器间地址(backend为后端容器名)
    : '/api' // 客户端用相对路径(由反向代理转发到后端)
});

export default api;

也可通过环境变量注入(更灵活):

  • 在Docker Compose中为Vike服务添加环境变量:
    services:
      vike-app:
        build: ./frontend
        environment:
          - SSR_API_BASE=http://backend:3000/api
    
  • 代码中读取环境变量:
    const baseURL = process.env.SSR_API_BASE || '/api';
    const api = axios.create({ baseURL });
    

3. 确保后端服务先于Vike启动

若Vike启动时后端尚未就绪,会触发连接拒绝。用Docker Compose的健康检查机制确保依赖服务就绪:

services:
  backend:
    build: ./backend
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"] # 后端需提供健康检查接口
      interval: 5s
      timeout: 5s
      retries: 3
  vike-app:
    build: ./frontend
    depends_on:
      backend:
        condition: service_healthy # 等待后端健康检查通过后再启动

4. 验证SSR数据预取的时机

确保API请求在Vike的onBeforeRender中触发(SSR阶段执行),而非组件的useEffect(仅客户端执行):

// pages/blog/+onBeforeRender.js
import api from '../../lib/api';

export async function onBeforeRender() {
  // SSR阶段预取博客数据
  const res = await api.get('/blog');
  return {
    pageContext: {
      pageProps: { posts: res.data }
    }
  };
}

若使用TanStack React Query,需在onBeforeRender中预取数据:

// pages/blog/+onBeforeRender.js
import { queryClient } from '../../lib/queryClient';

export async function onBeforeRender() {
  await queryClient.prefetchQuery({
    queryKey: ['blog-posts'],
    queryFn: () => api.get('/blog').then(res => res.data)
  });
  return { pageContext: { queryClient } };
}

5. 查看详细错误日志

在Docker中开启Vike/Node的详细日志,定位具体错误:

  • 修改Vike启动命令,添加日志参数:
    NODE_ENV=production DEBUG=vike* node server.js
    
  • 查看容器日志:
    docker logs <vike-container-name>
    
    重点关注Axios的错误栈,确认是连接拒绝、超时还是路径错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 11:04:51