Docker容器间网络问题:C# Consumer无法连接RabbitMQ
我有一套Docker部署环境:
- 用Docker Compose运行MongoDB和RabbitMQ
- 单独的Dockerfile运行C# Consumer应用(从RabbitMQ读取数据写入MongoDB)
- 第三个Dockerfile运行带C#后端的前端服务(从MongoDB拉取和更新记录)
本地运行Consumer时,通过localhost连接Docker映射的RabbitMQ 15672端口和MongoDB 27017端口完全正常,但将Consumer部署到Docker容器后,无法连接RabbitMQ。已尝试配置命名网络,使用ai-rabbitmq、rabbitmq_go_net作为主机名,甚至指定IP地址,均连接失败。
当前配置文件
Docker Compose配置
version: '3.1' services: mongo: image: mongo restart: always container_name: ai-mongodb ports: - '27017:27017' environment: MONGO_INITDB_ROOT_USERNAME: root MONGO_INITDB_ROOT_PASSWORD: example mongo-express: image: mongo-express restart: always container_name: ai-mongoexpress ports: - '8081:8081' volumes: - 'C:\MongoDb\data:/data/db' environment: ME_CONFIG_MONGODB_ADMINUSERNAME: root ME_CONFIG_MONGODB_ADMINPASSWORD: example ME_CONFIG_MONGODB_URL: 'mongodb://root:example@ai-mongodb:27017/' rabbitmq: image: 'rabbitmq:3-management-alpine' container_name: ai-rabbitmq ports: - '5672:5672' - '15672:15672' volumes: - '~/.docker-conf/rabbitmq/data/:/var/lib/rabbitmq/' - '~/.docker-conf/rabbitmq/log/:/var/log/rabbitmq' networks: - rabbitmq_go_net networks: rabbitmq_go_net: driver: bridge
Consumer的Dockerfile
#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging. FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base WORKDIR /app EXPOSE 80 EXPOSE 443 FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build WORKDIR /src COPY ["Consumer/Consumer.csproj", "Consumer/"] RUN dotnet restore "Consumer/Consumer.csproj" COPY . . WORKDIR "/src" RUN dotnet build "Consumer/Consumer.csproj" -c Release -o /app/build FROM build AS publish RUN dotnet publish "Consumer/Consumer.csproj" -c Release -o /app/publish /p:UseAppHost=false FROM base AS final WORKDIR /app COPY --from=publish /app/publish . ENTRYPOINT ["dotnet", "Consumer.dll"]
1. 确保所有服务在同一个Docker网络中
当前Compose仅将RabbitMQ加入rabbitmq_go_net网络,MongoDB、Mongo-Express和你的Consumer容器都不在该网络内,导致容器间无法通信。
推荐方案:将Consumer作为服务加入Docker Compose
这样Docker会自动处理网络连接,无需手动配置。修改后的Compose示例如下:
version: '3.1' services: mongo: image: mongo restart: always container_name: ai-mongodb ports: - '27017:27017' environment: MONGO_INITDB_ROOT_USERNAME: root MONGO_INITDB_ROOT_PASSWORD: example networks: - rabbitmq_go_net # 加入同网络 mongo-express: image: mongo-express restart: always container_name: ai-mongoexpress ports: - '8081:8081' volumes: - 'C:\MongoDb\data:/data/db' environment: ME_CONFIG_MONGODB_ADMINUSERNAME: root ME_CONFIG_MONGODB_ADMINPASSWORD: example ME_CONFIG_MONGODB_URL: 'mongodb://root:example@ai-mongodb:27017/' networks: - rabbitmq_go_net # 加入同网络 rabbitmq: image: 'rabbitmq:3-management-alpine' container_name: ai-rabbitmq ports: - '5672:5672' - '15672:15672' volumes: - '~/.docker-conf/rabbitmq/data/:/var/lib/rabbitmq/' - '~/.docker-conf/rabbitmq/log/:/var/log/rabbitmq' networks: - rabbitmq_go_net consumer: build: ./Consumer # 指向Consumer项目的根目录(Dockerfile所在位置) container_name: ai-consumer depends_on: - rabbitmq - mongo networks: - rabbitmq_go_net environment: # 配置环境变量,让Consumer读取正确的连接字符串 RABBITMQ_CONNECTION: 'amqp://guest:guest@rabbitmq:5672/' MONGODB_CONNECTION: 'mongodb://root:example@mongo:27017/' networks: rabbitmq_go_net: driver: bridge
备选方案:手动将Consumer容器连接到指定网络
如果不想修改Compose,运行Consumer容器时显式指定网络:
docker run --network rabbitmq_go_net your-consumer-image-name
2. 修正RabbitMQ连接端口
注意:RabbitMQ的AMQP协议端口是5672,15672是Web管理控制台的端口。Consumer应用应该连接5672端口,而不是15672。本地运行时通过端口映射能通,但容器内必须使用内部端口5672。
3. 正确使用服务名作为主机名
在Docker容器网络中,直接使用Compose中定义的服务名(如rabbitmq、mongo)作为主机名即可,Docker会自动解析到对应容器的IP。无需使用container_name(如ai-rabbitmq)或手动指定IP。
Consumer的RabbitMQ连接字符串示例(默认账号密码为guest/guest,若修改过请对应调整):
var factory = new ConnectionFactory() { HostName = "rabbitmq", Port = 5672, UserName = "guest", Password = "guest" };
内容的提问来源于stack exchange,提问作者user1730289

