skip to Main Content

I have implemented an application with REST interfaces in C# on .NET 6. When the URLs are called, then the data is fetched from a Postgresql database and returned. The application is implemented as code first. That means the tables are created because of my application. This has all worked so far.

Now I am trying to put the application and the database each into a Docker container and connect them together. For this I have a Dockerfile:

#build stage
FROM mcr.microsoft.com/dotnet/sdk:6.0 as build
WORKDIR /src
COPY . .
RUN dotnet restore "./Notification/Notification.csproj" --disable-parallel
RUN dotnet publish "./Notification/Notification.csproj" -c release -o /app --no-restore

#Serve stage
From mcr.microsoft.com/dotnet/sdk:6.0
WORKDIR /app
COPY --from=build /app .
ENTRYPOINT ["dotnet", "Notification.dll"]

A docker-compose.yaml:

version: '3'

networks:
  mynetwork:
    driver: bridge

services:

   notification:
      build: .
      ports:
      - "8080:80"
      - "8081:443"
      environment:
         ASPNETCORE_URLS: "https://+;http://+"
         ASPNETCORE_HTTPS_PORT: "8001"
         ASPNETCORE_Kestrel__Certificates__Default__Password: "1234"
         ASPNETCORE_Kestrel__Certificates__Default__Path: "/https/notification.pfx"
      volumes:
         - ${USERPROFILE}.aspnethttps:/https/
      depends_on:
         - postgres
      networks:
         - mynetwork 

   postgres:
      image: postgres:9.6.21-alpine
      container_name: postgres
      ports:
      - "5432:5432"
      environment:
         - POSTGRES_USER=postgres
         - POSTGRES_PASSWORD=1234
         - POSTGRES_DB=mail
      networks:
         - mynetwork 

My AppSettings from my C# application:

{
  "Serilog": {
    "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ],
    "MinimumLevel": "Debug",
    "WriteTo": [
      { "Name": "Console" },
      {
        "Name": "File",
        "Args": { "path": "../Logs/log.txt" }
      }
    ]
  },
  "AllowedHosts": "*",
  "AppSettings": {
    "ConnectionStrings": {
      "MailDb": "Server=postgres; Database = mail;  User Id = postgres; Password = 1234"
    },
    "MailServers": [
      {
        "Type": "ethereal",
        "URL": "smtp.ethereal.email",
        "Port": 587
      }
    ],
    "SlackChannels": [
      {
        "Channel": "Slackbot",
        "URL": "https://hooks.slack.com/services/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"
      }
    ]
  }
}

and my Program.cs:

using Microsoft.EntityFrameworkCore;
using Notification.Helper;
using Notification.Models;
using Notification.Service.EMail;
using NotificationService.Database;
using Serilog;

var builder = WebApplication.CreateBuilder(args);

builder.Configuration
    .SetBasePath(Directory.GetCurrentDirectory())
    .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);

//Der ähnliche Code muss da stehen, da es ein anderes Objekt ist
var configuration = new ConfigurationBuilder()
    .SetBasePath(Directory.GetCurrentDirectory())
    .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
    .Build();

Log.Logger = new LoggerConfiguration()
    .ReadFrom.Configuration(configuration)
    .CreateLogger();

var appSettings = new AppSettings();
builder.Configuration.GetSection("AppSettings").Bind(appSettings);

// Add services to the container.
builder.Services.Configure<AppSettings>(builder.Configuration.GetSection("AppSettings"));
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

builder.Services.AddScoped<IMessageService, MessageService>();

builder.Services.AddDbContext<MailContext>(
    o => o.UseNpgsql(appSettings.ConnectionStrings.MailDb)
    );

var app = builder.Build();

app.UseSwagger();
app.UseSwaggerUI();

app.UseAuthorization();
app.MapControllers();

app.Run();

When I run docker-compose -f docker-compose.yaml up, both containers are set up. However, no tables are created in the postgresql container, only the database mail. When I send a GET request via Swagger, then I get the following error messages:

fail: Microsoft.EntityFrameworkCore.Database.Connection[20004] notification-notification-1 |
An error occurred using the connection to database ‘mail’ on server ”.
notification-notification-1 | fail: Microsoft.EntityFrameworkCore.Query[10100] notification-notification-1 | An exception occurred while iterating over the results of a query for context type ‘NotificationService.Database.MailContext’.

Microsoft.AspNetCore.Server.Kestrel[13] notification-notification-1 | Connection id "0HMUMN18UPCED", Request id "0HMUMN18UPCED:00000001": An unhandled exception was thrown by the application.
notification-notification-1 | System.InvalidOperationException: An exception has been raised that is likely due to a transient failure.
notification-notification-1 | —> Npgsql.NpgsqlException (0x80004005): Failed to connect to [::1]:5432

3

Answers


  1. Chosen as BEST ANSWER

    Okay I am new to Docker and just learning it. That's why this is a stupid mistake. I deleted my images and created a new image and ran the docker compose. This solved the connection error. However, a new error pops up:

    : Microsoft.EntityFrameworkCore.Database.Command[20102] notification-notification-1 | Failed executing DbCommand (43ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] notification-notification-1 | SELECT n."NotificationId", n."Message", n."Platform", n."Recipient", n."SendDate", n."Sender", n."Subject" notification-notification-1 | FROM notification AS n notification-notification-1 | fail: Microsoft.EntityFrameworkCore.Query[10100] notification-notification-1 | An exception occurred while iterating over the results of a query for context type 'NotificationService.Database.MailContext'. notification-notification-1 | Npgsql.PostgresException (0x80004005): 42P01: relation "notification" does not exist

    This is probably because the database is not migrated. It would be very nice if someone could tell how to do this, but I think a connection problem is solved with this


  2. However, no tables are created in the postgresql container, only the
    database mail.

    You haven’t applied the migrations to your database.
    You can do this programmatically like:

    dbContext.Database.Migrate();

    More Ways to run your Migrations.

    So in your case it would be:

    using (var scope = app.Services.CreateScope())
    {
        var _context= scope.ServiceProvider.GetRequiredService<MailContext>();
    
        _context.Database.Migrate();
    }
    
    Login or Signup to reply.
  3. Try changing your connectionstring to :
    "MailDb": "Server=postgres; Database = mail; User Id = postgres; Password = 1234; TrustServerCertificate=True;"

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search