Docker化Next.js+FastAPI应用:统一请求URL方案
问题解决:Next.js+FastAPI Docker化应用统一API请求URL
问题根源
- 浏览器环境的客户端组件用
http://server:8000会失败:浏览器运行在宿主机,无法解析Docker内部的服务名称server,导致DNS解析错误ERR_NAME_NOT_RESOLVED。 - Next.js服务端组件用
http://localhost:8000会失败:服务端组件运行在client容器内,容器的localhost指向自身而非宿主机,因此无法连接到FastAPI服务,触发TypeError: fetch failed。
解决方案一:Next.js Rewrites 反向代理(推荐)
通过Next.js的路由重写,让客户端和服务端组件统一使用相对路径请求,由Next.js在服务端转发请求到FastAPI。
- 配置Next.js重写规则
在client项目根目录创建next.config.js:
/** @type {import('next').NextConfig} */ const nextConfig = { async rewrites() { return [ { source: '/api/:path*', destination: 'http://server:8000/:path*', }, ] }, } module.exports = nextConfig
- 统一使用相对路径请求
客户端和服务端组件都用/api/xxx发起请求:
// 客户端组件(浏览器运行) const res = await fetch('/api/weather') // 服务端组件(client容器内运行) const res = await fetch('/api/weather')
- 清理无用环境变量
删除docker-compose.yml中client服务的NEXT_PUBLIC_PYTHON_API环境变量。
解决方案二:区分环境变量(兼容现有代码)
通过不同环境变量分别给客户端和服务端组件提供API地址,代码中自动适配。
- 更新Docker Compose配置
修改client服务的环境变量:
client: container_name: client build: context: ./client dockerfile: ./Dockerfile volumes: - ./client:/app ports: - 3000:3000 environment: - NEXT_PUBLIC_API_URL=http://localhost:8000 # 供浏览器端组件使用 - API_URL=http://server:8000 # 供服务端组件使用(仅容器内可见)
- 编写通用请求函数
在代码中通过环境判断自动选择API地址:
async function fetchApi(path) { // 浏览器环境用NEXT_PUBLIC变量,服务端环境用内部变量 const baseUrl = typeof window !== 'undefined' ? process.env.NEXT_PUBLIC_API_URL : process.env.API_URL const res = await fetch(`${baseUrl}${path}`) return res.json() } // 客户端/服务端组件统一调用 const data = await fetchApi('/weather')
关键注意事项
- Docker Compose默认会为所有服务创建同一网络,
client和server容器可通过服务名互相访问,因此服务端组件用http://server:8000是合法的。 - 浏览器无法直接访问Docker内部服务名,必须使用宿主机的
localhost或IP地址。
内容的提问来源于stack exchange,提问作者joovil
相关产品推荐
相关产品推荐

