在 Docker 容器中运行 .Net 5 API 时无法连接到 Postgres
Posted
技术标签:
【中文标题】在 Docker 容器中运行 .Net 5 API 时无法连接到 Postgres【英文标题】:Can't connect to Postgres when running .Net 5 API in Docker container 【发布时间】:2021-10-01 01:21:41 【问题描述】:我正在尝试将在 Docker 容器中运行的 .Net 5 API 与在单独容器中运行的 Postgres db 连接起来。在没有容器的情况下在本地运行 API 时连接有效,但是当我在容器中运行 API 时出现错误
使用连接到服务器“tcp://localhost:5432”上的数据库“databasename”时出错。
我认为这是因为 docker 容器没有在 localhost 上运行。 我试图更改 docker-compose 文件中的主机,并尝试手动更改 startup.cs 中的连接字符串。这会更改 API 在本地运行时使用的连接,但不会更改容器内的连接或我收到的错误。任何帮助将不胜感激。
Startup.cs
//var connectionString = Configuration.GetSection(nameof(PostgresSettings)).Get<PostgresSettings>().ConnectionString;
var connectionString = $"Host=tryingtochangehost;Port=5432;Database=databasename;Username=username;Password=password";
services.AddDbContext<DataContext>(options => options.UseNpgsql(connectionString));
services.AddScoped<IDataContext>(provider => provider.GetService<DataContext>());
docker-compose.yml
version: "3.4"
services:
web:
build: .
ports:
- "8080:80"
environment:
- JWTCONFIG:SECRET=secret
- POSTGRESSETTINGS:PASSWORD=password
- POSTGRESSETTINGS:HOST=postgresql_database
depends_on:
- "postgresql_database"
networks:
- mynetwork
postgresql_database:
image: postgres:latest
environment:
- POSTGRES_USER=admin
- POSTGRES_PASSWORD=password
- POSTGRES_DB=databasename
ports:
- "5432:5432"
restart: always
volumes:
- database-data:/var/lib/postgresql/data/
networks:
- mynetwork
pgadmin:
image: dpage/pgadmin4
environment:
- PGADMIN_DEFAULT_EMAIL=pgadmin@admin.org
- PGADMIN_DEFAULT_PASSWORD=password
ports:
- "5050:80"
restart: always
volumes:
- pgadmin:/root/.pgadmin
networks:
- mynetwork
volumes:
database-data:
pgadmin:
networks:
mynetwork:
driver: bridge
Dockerfile
FROM mcr.microsoft.com/dotnet/aspnet:5.0-focal AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/sdk:5.0-focal AS build
WORKDIR /src
COPY ["Server.csproj", "./"]
RUN dotnet restore "Server.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "Server.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "Server.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Server.dll"]
appsettings.json
"PostgresSettings":
"Host": "localhost",
"Port": "5432",
"Database": "databasename",
"Username": "admin"
,
"Logging":
"LogLevel":
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
,
"JwtConfig": ,
"AllowedHosts": "*"
【问题讨论】:
【参考方案1】:当您尝试连接到 localhost:5432
时,您正在尝试连接到与您的 Web 容器相同的容器。
Docker compose 创建了一个虚拟网络,每个容器都可以通过它的服务名称访问。因此,您需要在 appsettings 中将数据库服务器名称从 localhost
更改为 postgresql_database
:
"PostgresSettings":
"Host": "postgresql_database",
"Port": "5432",
"Database": "databasename",
"Username": "admin"
,
"Logging":
"LogLevel":
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
,
"JwtConfig": ,
"AllowedHosts": "*"
你的连接字符串代码应该是
var connectionString = $"Host=postgresql_database;Port=5432;Database=databasename;Username=username;Password=password";
【讨论】:
您好,感谢您的帮助。更改连接字符串或 appsettings 只会在 api 不在容器中运行时影响它。甚至手动更改连接字符串,例如 services.AddDbContext事实证明我的配置很好,但是我需要在 docker-compose up 之前运行 docker-compose build,这样更改才会真正生效。
【讨论】:
以上是关于在 Docker 容器中运行 .Net 5 API 时无法连接到 Postgres的主要内容,如果未能解决你的问题,请参考以下文章
在 overlay 中运行容器 - 每天5分钟玩转 Docker 容器技术(51)
将已发布的 .Net Core Web API 文件和公共 selenium/standalone-chrome 容器合并到一个 Docker 容器中
ASP.NET Core 5 + SQL Server Docker 容器:无效的撰写项目