Reputation: 29
I'm trying connect a .Net 5 API running in a Docker container with a Postgres db running in a separate container. The connection works when running the API locally without a container, however when I run the API in a container I get the error
An error occurred using the connection to database 'databasename' on server 'tcp://localhost:5432'.
I think this is because the docker container is not running on localhost. I have attempted to change the host in the docker-compose file and tried manually changing the connection string in startup.cs. This changes the connection the API uses when run locally, however does not change the connection within the container, or the error I am getting. Any help would be appreciated.
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:
- [email protected]
- 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": "*"
}
Upvotes: 1
Views: 3044
Reputation: 29
Turns out my configuration was fine, however I needed to run docker-compose build before docker-compose up so the changes actually had effect.
Upvotes: 0
Reputation: 25189
When you try to connect to localhost:5432
, you're trying to connect to the same container as your web container.
Docker compose creates a virtual network where each container can be reached by it's service name. So you need to change the database server name from localhost
to postgresql_database
like this in your appsettings:
{
"PostgresSettings": {
"Host": "postgresql_database",
"Port": "5432",
"Database": "databasename",
"Username": "admin"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"JwtConfig": {},
"AllowedHosts": "*"
}
Your connection string code should be
var connectionString = $"Host=postgresql_database;Port=5432;Database=databasename;Username=username;Password=password";
Upvotes: 1