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

两个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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 19:05:00