Docker部署.NET Core Api调用Selenium时出现地址分配失败问题
我开发了一个使用 Selenium Chrome Driver 的 .NET Core API,本地运行正常,但创建 Docker 镜像并运行时抛出 Cannot assign requested address (localhost:4444) 异常。
相关代码与配置
实例化 Chrome Driver 的代码
ChromeOptions options = new ChromeOptions(); options.AddArgument("no-sandbox"); options.AddArgument("headless"); driver = new RemoteWebDriver(new Uri("http://localhost:4444/wd/hub"), options);
Dockerfile
FROM selenium/standalone-chrome:latest AS base WORKDIR /app # build and copy dotnet project FROM mcr.microsoft.com/dotnet/aspnet:5.0 COPY bin/Release/net5.0/publish/ app/ WORKDIR /app ENTRYPOINT ["dotnet", "Pand.dll"]
Docker Compose 配置
version: "3" services: selenium-hub: image: selenium/hub:3.141.59-yttrium container_name: selenium-hub ports: - "4444:4444" expose: - 4444 chrome: image: selenium/standalone-chrome container_name: chrome deploy: replicas: 5 ports: - "5900:5900" volumes: - /dev/shm:/dev/shm depends_on: - selenium-hub environment: - HUB_HOST=selenium-hub - HUB_PORT=4444 #Api Service api: build: context: . #Use the DockerFile in that Directory dockerfile: DockerFile environment: - ASPNETCORE_ENVIRONMENT=Development
执行 docker run -p 8080:80 pand/backend 后的错误信息
crit: Microsoft.AspNetCore.Hosting.Diagnostics[6] Application startup exception OpenQA.Selenium.WebDriverException: An unknown exception was encountered sending an HTTP request to the remote WebDriver server for URL http://localhost:4444/wd/hub/session. The exception message was: Cannot assign requested address (localhost:4444) ---> System.Net.Http.HttpRequestException: Cannot assign requested address (localhost:4444) ---> System.Net.Sockets.SocketException (99): Cannot assign requested address at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken) at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(Int16 token) at System.Net.Sockets.Socket.<ConnectAsync>g__WaitForConnectWithCancellation|283_0(AwaitableSocketAsyncEventArgs saea, ValueTask connectTask, CancellationToken cancellationToken)
问题原因与修复方案
核心问题
Docker 容器内的 localhost 指向容器自身的网络栈,而非宿主机或其他容器。API 容器尝试访问自身的 4444 端口,但该端口并未在容器内开放,导致连接失败。
修复步骤
修改 RemoteWebDriver 连接地址
将代码中的http://localhost:4444/wd/hub替换为http://selenium-hub:4444/wd/hub。Docker Compose 会自动为服务创建 DNS 解析,通过服务名称selenium-hub可直接访问对应容器。修改后代码:
ChromeOptions options = new ChromeOptions(); options.AddArgument("no-sandbox"); options.AddArgument("headless"); driver = new RemoteWebDriver(new Uri("http://selenium-hub:4444/wd/hub"), options);通过 Docker Compose 启动集群
不要单独用docker run启动 API 容器,执行docker-compose up --build启动所有服务。Docker 会自动创建共享网络,保证容器间的互通性。简化 Dockerfile(可选)
Dockerfile 中FROM selenium/standalone-chrome:latest AS base未被后续阶段使用,可删除以简化镜像构建:FROM mcr.microsoft.com/dotnet/aspnet:5.0 COPY bin/Release/net5.0/publish/ app/ WORKDIR /app ENTRYPOINT ["dotnet", "Pand.dll"]添加启动重试逻辑(可选)
depends_on仅保证启动顺序,Selenium Hub 可能需要时间初始化。可在 API 启动时添加重试逻辑,避免因 Hub 未就绪导致的启动失败。
内容的提问来源于stack exchange,提问作者Sasan

