Next.js容器中getServerSideProps报ECONNREFUSED连接错误求助
环境配置详情
前端docker-compose.yaml
services: bsb_front: image: bsb_front container_name: bsb_front build: context: . target: dev restart: always command: yarn dev environment: - NODE_ENV=development - BASE_URL=http://localhost:8080 - BASE_URL_TEST=http://localhost:8080 volumes: - .:/app - /app/node_modules - /app/.next ports: - 3000:3000 networks: - bsb-network networks: bsb-network: name: bsb-network external: true
后端docker-compose.yaml
version: "3.4" services: bsb_php: container_name: bsb_php image: bsb_php build: dockerfile: docker/php/Dockerfile target: sylius_php depends_on: - bsb_database env_file: - .env.local environment: - PHP_DATE_TIMEZONE=${PHP_DATE_TIMEZONE:-UTC} networks: - backend volumes: - .:/srv/sylius:rw,cached - ./public:/srv/sylius/public:rw,delegated - public-media:/srv/sylius/public/media:rw bsb_database: container_name: bsb_database image: mysql:8.0.36 networks: - backend env_file: - docker/mysql/.env volumes: - ./docker/mysql/data:/var/lib/mysql:rw ports: - "3306:3306" cap_add: - SYS_NICE bsb_node: image: bsb_node container_name: bsb_node build: dockerfile: docker/nodejs/Dockerfile depends_on: - bsb_php environment: - GULP_ENV=dev - PHP_HOST=bsb_php - PHP_PORT=9000 networks: - backend volumes: - ./public:/srv/sylius/public:rw,delegated ports: - "35729:35729" bsb_nginx: image: bsb_nginx container_name: bsb_nginx build: dockerfile: docker/nginx/dev/Dockerfile networks: - bsb-network - backend depends_on: - bsb_php - bsb_node volumes: - ./public:/srv/sylius/public:ro - public-media:/srv/sylius/public/media:ro,nocopy ports: - "8080:80" volumes: mysql-data: public-media: networks: backend: name: backend external: false bsb-network: external: true
Next.js配置
// .env.development NEXT_SERVER_API_URL="http://bsb_nginx:8080" NEXT_PUBLIC_API_URL=http://localhost:8080
// next.config.js serverRuntimeConfig: { apiUrl: process.env.NEXT_SERVER_API_URL, }, publicRuntimeConfig: { apiUrl: process.env.NEXT_PUBLIC_API_URL, }
// api base url import getConfig from "next/config"; export const getBaseUrl = () => { const { serverRuntimeConfig, publicRuntimeConfig } = getConfig(); const apiUrl = (serverRuntimeConfig.apiUrl as string) || (publicRuntimeConfig.apiUrl as string); return apiUrl; };
错误信息
Error: {"duration":76,"problem":"CONNECTION_ERROR","originalError":{"message":"connect ECONNREFUSED 172.25.0.2:8080","name":"Error","stack":"Error: connect ECONNREFUSED 172.25.0.2:8080\n at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1555:16)","config":{"url":"shop-api/products/by-code/APPL-MTV03ZP","method":"get","headers":{"Accept":"application/ld+json, application/json","Content-Type":"application/json","User-Agent":"axios/0.21.4"},"params":{},"baseURL":"http://bsb_nginx:8080","transformRequest":[null],"transformResponse":[null],"timeout":50000,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","maxContentLength":-1,"maxBodyLength":-1,"transitional":{"silentJSONParsing":true,"forcedJSONParsing":true,"clarifyTimeoutError":false}},"code":"ECONNREFUSED"},"ok":false,"status":null,"headers":null,"config":{"url":"shop-api/products/by-code/APPL-MTV03ZP","method":"get","headers":{"Accept":"application/ld+json, application/json","Content-Type":"application/json","User-Agent":"axios/0.21.4"},"params":{},"baseURL":"http://bsb_nginx:8080","transformRequest":[null],"transformResponse":[null],"timeout":50000,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","maxContentLength":-1,"maxBodyLength":-1,"transitional":{"silentJSONParsing":true,"forcedJSONParsing":true,"clarifyTimeoutError":false}},"data":null}
问题排查与解决方案
1. 修正服务端API端口配置
容器间通信使用容器内部端口,而非宿主机映射端口。后端Nginx容器内部监听80端口(宿主机映射到8080),因此服务端配置的NEXT_SERVER_API_URL需改为:
// .env.development NEXT_SERVER_API_URL="http://bsb_nginx:80"
2. 确保后端服务真正就绪
depends_on仅保证容器启动顺序,不确保服务内部初始化完成(如PHP-FPM、Nginx是否真正监听端口)。需给后端服务添加健康检查:
- 给
bsb_php添加健康检查:
bsb_php: # ... 其他配置 healthcheck: test: ["CMD", "curl", "-f", "http://localhost:9000/status"] # 根据PHP-FPM状态接口调整 interval: 10s timeout: 5s retries: 5
- 给
bsb_nginx添加健康检查:
bsb_nginx: # ... 其他配置 healthcheck: test: ["CMD", "curl", "-f", "http://localhost/health"] # 需在Nginx配置中添加健康检查端点 interval: 10s timeout: 5s retries: 5
或在前端启动脚本中添加等待逻辑:
command: sh -c "until curl -f http://bsb_nginx:80; do sleep 5; done && yarn dev"
3. 验证外部网络存在
确认bsb-network外部网络已创建:
docker network ls | grep bsb-network
若不存在,手动创建:
docker network create bsb-network
4. 检查Nginx配置
确认Nginx配置中正确监听80端口,且反向代理到PHP-FPM的配置无误,确保bsb_nginx容器内部可正常访问后端服务。
内容的提问来源于stack exchange,提问作者Tsolmonx

