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

Docker容器内调用API报错:目标机器主动拒绝连接

问题:Docker容器内调用API连接被拒绝

HttpRequestException: No connection could be made because the target machine actively refused it. (localhost:21000)

前后端部署在同一机器上,直接在浏览器访问http://localhost:21000/WeatherForecast可正常运行,但前端容器内调用API时报错。相关配置如下:

前端Dockerfile

FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /src
COPY ["DockerBasicClientServe2/DockerBasicClientServe2.csproj", "DockerBasicClientServe2/"]
RUN dotnet restore "DockerBasicClientServe2/DockerBasicClientServe2.csproj"
COPY . .
WORKDIR "/src/DockerBasicClientServe2"
RUN dotnet build "DockerBasicClientServe2.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "DockerBasicClientServe2.csproj" -c Release -o /app/publish /p:UseAppHost=false

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "DockerBasicClientServe2.dll"]

API的Dockerfile

FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
WORKDIR /app
EXPOSE 80

FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /src
COPY ["MyRestApi/MyRestApi.csproj", "MyRestApi/"]
RUN dotnet restore "MyRestApi/MyRestApi.csproj"
COPY . .
WORKDIR "/src/MyRestApi"
RUN dotnet build "MyRestApi.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "MyRestApi.csproj" -c Release -o /app/publish /p:UseAppHost=false

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "MyRestApi.dll"]

docker-compose.yml

version: '3.4'

services:
  dockerbasicclientserve2:
    image: ${DOCKER_REGISTRY-}dockerbasicclientserve2
    build:
      context: .
      dockerfile: DockerBasicClientServe2\Dockerfile
    ports:
     - "5200:80"
     - "5201:443"

  myrestapi:
    image: ${DOCKER_REGISTRY-}myrestapi
    build:
      context: .
      dockerfile: MyRestApi\Dockerfile
    ports:
     - "21000:80"

调用API的代码

public async Task<IActionResult> Weather()
{
    var weatherForeCastResponse = await this._client.GetAsync("http://localhost:21000/WeatherForecast");
    var temp = await weatherForeCastResponse.Content.ReadAsStringAsync();
    var weatherForeCast = JsonConvert.DeserializeObject<IEnumerable<WeatherForecast>>(temp);

    return View(weatherForeCast);
}

解决方案

1. 修改API调用地址

将前端代码中的http://localhost:21000/WeatherForecast替换为http://myrestapi:80/WeatherForecast,修改后代码如下:

public async Task<IActionResult> Weather()
{
    var weatherForeCastResponse = await this._client.GetAsync("http://myrestapi:80/WeatherForecast");
    var temp = await weatherForeCastResponse.Content.ReadAsStringAsync();
    var weatherForeCast = JsonConvert.DeserializeObject<IEnumerable<WeatherForecast>>(temp);

    return View(weatherForeCast);
}

2. (可选)通过环境变量配置地址

为提升灵活性,建议将API地址配置为环境变量:

  • 在docker-compose.yml的dockerbasicclientserve2服务下添加环境变量:
environment:
  - ApiBaseUrl=http://myrestapi:80
  • 在前端项目中读取环境变量并使用:
var apiUrl = Environment.GetEnvironmentVariable("ApiBaseUrl") ?? "http://localhost:21000";
var weatherForeCastResponse = await this._client.GetAsync($"{apiUrl}/WeatherForecast");

原因说明

  • Docker容器内的localhost指向容器自身,而非宿主机。前端容器访问localhost:21000时,实际是在访问容器自己的21000端口,而非宿主机上映射的API端口。
  • Docker Compose会自动为同一网络下的服务创建DNS解析,服务名(myrestapi)可直接作为域名访问对应容器,端口使用容器内部暴露的80端口(无需使用宿主机的21000端口)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 08:25:28