树莓派Docker部署Angular+ASP.NET应用跨域连接失败问题求助
问题描述
将前端(Angular 16)和后端(ASP.NET Core 7)分别部署在树莓派4的Docker容器中,访问地址为[IP_ADDRESS]:4200(前端)和[IP_ADDRESS]:5180(后端)。浏览器访问前端可正常操作,但发送请求至后端时出现错误:
POST http://localhost:5180/api/auth/login net::ERR_CONNECTION_REFUSED
Http failure response for http://localhost:5180/api/auth/login: 0 Unknown Error
已配置Docker Compose将两个容器加入同一bridge网络,后端Program.cs中已启用AllowAnyOrigin的CORS策略且配置在认证授权之前,但本地运行的Angular前端可正常请求树莓派上的后端容器。
相关配置文件如下:
Angular Dockerfile
FROM node:18 as build WORKDIR /usr/src/app COPY package*.json ./ RUN npm install COPY . . RUN npm run build FROM nginx:alpine COPY --from=build /usr/src/app/dist/recipe_frontend /usr/share/nginx/html EXPOSE 4200 CMD ["nginx", "-g", "daemon off;"]
ASP.NET Dockerfile
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build WORKDIR /app COPY . . RUN dotnet restore RUN dotnet build -c Release RUN dotnet publish -c Release -o /app/publish FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS final WORKDIR /app COPY --from=build /app/publish . EXPOSE 5180 ENTRYPOINT ["dotnet", "recipe_backend.dll"]
Docker Compose文件
version: '2.27.0' services: frontend: build: context: ../dev/recipe-app/recipes/recipe_frontend ports: - "4200:80" depends_on: - backend networks: - recipe_network backend: build: context: ../dev/recipe-app/recipes/recipe_backend ports: - "5180:80" networks: - recipe_network networks: recipe_network: driver: bridge
Program.cs核心配置
var builder = WebApplication.CreateBuilder(args); // 添加服务 builder.Services.AddCors(); builder.Services.AddMvc(); builder.Services.AddControllers(); // ... 省略DB连接、JWT认证等配置 ... var app = builder.Build(); // 配置请求管道 app.UseCors(policy => policy.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader()); app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.Run();
问题分析
核心问题出在前端请求的目标地址错误:
- 浏览器访问容器化前端时,代码中的
http://localhost:5180会被解析为用户本地机器的localhost,而非树莓派上的后端容器;本地运行Angular时,localhost:5180能映射到树莓派端口,因此可以正常访问。 - 即使前端容器内部请求
localhost:5180,也只会指向前端容器自身,而非同一网络中的后端容器。
解决方案
1. 修改Angular的API基础地址
将前端代码中的API请求地址改为Docker Compose服务名backend(容器间通信可直接用服务名),端口使用后端容器内部的80(后端容器内部暴露80端口,Compose仅将树莓派的5180映射到容器80)。
示例修改(Angular环境配置)
在src/environments/environment.prod.ts中更新API base URL:
export const environment = { production: true, apiBaseUrl: 'http://backend:80/api' };
若需支持本地开发和容器部署双场景,可通过构建时环境变量传递:
- 构建命令调整为:
npm run build -- --configuration production --base-href / --environment apiBaseUrl=http://backend:80/api - 或在Dockerfile的构建步骤注入变量:
然后在Angular代码中读取该环境变量。RUN API_BASE_URL=http://backend:80/api npm run build
2. 修正Docker配置冗余项
- Angular Dockerfile中
EXPOSE 4200冗余,容器实际使用Nginx的80端口,Compose映射4200:80,可删除该语句。 - ASP.NET Dockerfile中
EXPOSE 5180冗余,容器内部服务运行在80端口(.NET默认),建议改为EXPOSE 80保持配置一致。
3. 验证容器网络和CORS
- 确认双容器在同一网络:执行
docker inspect recipe_network查看容器列表,确保frontend和backend均在其中。 - 后端CORS配置已正确放置在管道最前端,无需调整;若后续需限制Origin,可将允许的Origin设为前端外部访问地址
http://[IP_ADDRESS]:4200,替代AllowAnyOrigin。
验证步骤
- 重新构建启动容器:
docker-compose down && docker-compose up --build - 浏览器访问
http://[IP_ADDRESS]:4200执行登录操作,检查控制台是否仍有连接错误。 - 若问题依旧,可进入前端容器测试连通性:
docker exec -it <frontend_container_id> sh,执行curl http://backend:80/api/auth/login模拟请求,确认是否能正常访问后端接口。
内容的提问来源于stack exchange,提问作者F.S
相关产品推荐
相关产品推荐

