两个Docker开发环境通信失败问题排查求助
Docker容器间通信问题排查与修复
问题背景
我运行两个Docker开发环境,需测试它们的通信:
- mgmt-service:包含Express服务端(提供API接口)和Next.js应用(带交互按钮),用于提供服务选择UI;
- api-service:计划接收请求并转换数据后返回,目前已实现基础/test等接口。
当前异常
- mgmt-service发送Axios请求时出现异常:自身端点返回404,调用api-service时触发500错误,报错信息为
getaddrinfo ENOTFOUND ocd-api-service-app-1; - 点击Next.js按钮可触发/api/proxy接口(能打印"hit1"日志),但无法访问api-service的/test接口。
我主要从事Serverless开发,对Docker不熟悉,怀疑mgmt-service配置存在问题,相关配置文件如下:
mgmt-service 配置文件
compose-dev.yaml
networks: ocd-network: driver: bridge services: app: entrypoint: - sleep - infinity image: docker/dev-environments-javascript:stable-1 networks: - ocd-network init: true volumes: - type: bind source: /var/run/docker.sock target: /var/run/docker.sock
app.cjs
const express = require("express"); const next = require("next"); const axios = require('axios'); const port = 80; const dev = process.env.NODE_ENV !== "production"; const app = next({ dev }); const handle = app.getRequestHandler(); app.prepare().then(() => { const server = express(); server.get('/server-connection', (req, res) => res.send('We are good to go!')); // 代理路由:从ocd-api获取数据 server.get("/api/proxy", async (req, res) => { console.log("hit1") try { const response = await axios.get("http://ocd-api-service-app-1:3001/test"); res.json(response.data); } catch (error) { console.error("请求ocd-api失败:", error); res.status(500).json({ error: "发生错误", error }); } }); // 让Next.js处理所有其他路由 server.all("*", (req, res) => { return handle(req, res); }); server.listen(port, (err) => { if (err) throw err; console.log(`> 服务已启动:http://localhost:${port}`); }); });
api-service 配置文件
compose-dev.yaml
networks: ocd-network: driver: bridge services: app: entrypoint: - sleep - infinity image: docker/dev-environments-javascript:stable-1 networks: - ocd-network init: true volumes: - type: bind source: /var/run/docker.sock target: /var/run/docker.sock
index.ts
import express, { Express, Request, Response } from 'express'; import dotenv from 'dotenv'; import cors from "cors" dotenv.config(); const app: Express = express(); const port = process.env.PORT; app.use(cors()); app.get('/', (req: Request, res: Response) => { res.status(200) res.send("ok") }); app.get("/test", (req, res) => { res.status(200); res.send({ message: "Winner, winner chicken dinner", time: new Date(), }); }); app.listen(port, () => { console.log(`服务运行地址:http://localhost:${port}`); })
错误详情
cause: Error: getaddrinfo ENOTFOUND ocd-api-service-app-1 at GetAddrInfoReqWrap.onlookup [as oncomplete] (node:dns:109:26) at GetAddrInfoReqWrap.callbackTrampoline (node:internal/async_hooks:130:17) { errno: -3008, code: 'ENOTFOUND', syscall: 'getaddrinfo', hostname: 'ocd-api-service-app-1' }
docker ps 结果
containerId imageName command:"sleep infinity" ... ocd-api-service-app-1 containerId imageName command:"sleep infinity" ... ocd-mgmt-service-app-1
修复步骤
1. 解决容器名称解析问题
ENOTFOUND错误说明mgmt-service容器无法通过ocd-api-service-app-1主机名找到api-service容器,需:
- 确认docker ps输出的api-service容器名称完全正确(注意大小写和后缀);
- 替换mgmt-service中Axios请求地址为正确的容器名称+端口:
// 确保容器名称与docker ps输出一致,端口与api-service的PORT环境变量匹配 const response = await axios.get("http://ocd-api-service-app-1:3001/test");
2. 手动启动容器内服务
你的容器启动命令是sleep infinity,服务并未自动启动,需要手动进入容器启动:
- 启动api-service:
docker exec -it ocd-api-service-app-1 bash # 容器内执行 npm install npm run start - 启动mgmt-service:
docker exec -it ocd-mgmt-service-app-1 bash # 容器内执行 npm install npm run dev # 或对应启动命令
3. 验证api-service端口配置
检查api-service的.env文件,确认PORT=3001,与请求端口一致。若端口不同,同步修改Axios请求地址。
4. 修复404问题
mgmt-service中server.all("*", ...)让Next.js处理所有未匹配路由,若Next.js无对应页面则返回404。解决方式:
- 在Next.js项目中添加对应页面;
- 调整路由优先级,将自定义API路由放在
server.all之前。
5. 优化配置(可选,提升稳定性)
为docker-compose服务设置固定容器名称,避免自动生成名称变化:
修改api-service的compose-dev.yaml:
services: app: container_name: api-service-app # 固定容器名称 # 其他配置不变
mgmt-service的compose-dev.yaml同理设置container_name: mgmt-service-app,之后请求地址可改为http://api-service-app:3001/test,更稳定。
内容的提问来源于stack exchange,提问作者CleverlyDone
相关产品推荐
相关产品推荐

