1

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": "*"
}

2 Answers 2

1

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";
Sign up to request clarification or add additional context in comments.

1 Comment

Hi, thanks for your help. Changing the connection string or appsettings is only effecting the api when it is not running in a container. Even manually changing the connection string e.g services.AddDbContext<DataContext>(options => options.UseNpgsql("notarealconnectionstring")); is only causing an effect when running the API without a container. It seems no matter what the string actually is, the container tries to connect to the database at tcp://localhost:5432,
0

Turns out my configuration was fine, however I needed to run docker-compose build before docker-compose up so the changes actually had effect.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.