fullstackhero / dotnet-starter-kit

Production Grade Cloud-Ready .NET 8 Starter Kit (Web API + Blazor Client) with Multitenancy Support, and Clean/Modular Architecture that saves roughly 200+ Development Hours! All Batteries Included.
https://fullstackhero.net/dotnet-webapi-boilerplate/
MIT License
5.08k stars 1.52k forks source link

Docker build: container quits immediately after initialization. #282

Closed fretje closed 2 years ago

fretje commented 2 years ago

I'm trying to build a docker container for the api. The container builds fine with the included Dockerfile (although there's an error wrt oracle, but that's no problem as I'm not using oracle... I've actually edited the Dockerfile to include a copy of the oracle project so that error is even gone).

But when I try to run the container, it runs fine at first, but stops immediately after initialization. This is the output:

[15:45:12 INF] Server Booting Up...
[15:45:12 INF] Hangfire: Current Storage Provider : mssql
[15:45:12 INF] For more Hangfire storage, visit https://www.hangfire.io/extensions.html
[15:45:13 INF] Current DB Provider : mssql
[15:45:14 INF] Connection to root's Database Succeeded.
[15:45:14 INF] For documentations and guides, visit https://www.fullstackhero.net
[15:45:14 INF] To Sponsor this project, visit https://opencollective.com/fullstackhero

After that last message, the process stops with 0 (so meaning success?)

To be able to get here...

I'm not too familiar with docker compose, but by googling I've created a docker-compose.yml file like this:

services:
    api:
        build: .
        container_name: api
        environment:
            ASPNETCORE_ENVIRONMENT: "production"
        ports:
            - "8080:5050"
        depends_on:
            - db
        networks:
            - linuxaspnetcore
        restart: "on-failure" #unless-stopped
    db:
        image: "mcr.microsoft.com/mssql/server:2019-latest"
        container_name: db
        restart: always
        environment:
            MSSQL_SA_PASSWORD: "SuperSecurePassword123!"
            SA_PASSWORD: "SuperSecurePassword123!"
            ACCEPT_EULA: "Y"
        ports:
            - "1433"
        volumes:
            - linuxaspnetcoredata:/var/opt/mssql
        networks:
            - linuxaspnetcore

volumes:
    linuxaspnetcoredata:

networks:
    linuxaspnetcore:
        driver: "bridge"

I've added a database.production.json file like this:

{
  "DatabaseSettings": {
    "DBProvider": "mssql",
    "ConnectionString": "Server=db;Database=fullStackHeroDb;User=sa;Password=SuperSecurePassword123!"
  }
}

and a similar for Hangfire (I've actually changed the code to take the default connectionstring when none is defined, so it's taking the same provider and connectionstring).

I'm starting the whole thing with

docker-compose up -d --build

When I ran it for the first time, I saw the log messages that the database was initialized and seeded, so the connection to the database works fine for sure. It's just that the api container quits just before starting to listen for http requests.

Anybody got any idea? My docker skills need some training and my google-fu also didn't find a solid answer ;-)

fretje commented 2 years ago

Hmm, I've been playing around a bit more with this, and the problem is probably not with docker, but rather with the publishing of the app. I've run a local publish on my system of the app:

dotnet publish "Host.csproj" -c Release -o ../../publish

And when I then run dotnet .\DN.WebApi.Host.dll from the publish folder (which is what also happens in the container), the same thing happens:

PS C:\Projects\fretje\dotnet-webapi-boilerplate\publish> dotnet .\DN.WebApi.Host.dll
[20:36:01 INF] Server Booting Up...
[20:36:01 INF] Hangfire: Current Storage Provider : mssql
[20:36:01 INF] For more Hangfire storage, visit https://www.hangfire.io/extensions.html
[20:36:01 INF] Current DB Provider : mssql
[20:36:03 INF] Connection to root's Database Succeeded.
[20:36:03 INF] For documentations and guides, visit https://www.fullstackhero.net
[20:36:03 INF] To Sponsor this project, visit https://opencollective.com/fullstackhero
PS C:\Projects\fretje\dotnet-webapi-boilerplate\publish>

The app just quits... no error message no nothing... not even the Log.Information("Server Shutting down..."); which is in the finally block of the app??? Things are getting weird...

Or maybe I'm just doing something very wrong?

fretje commented 2 years ago

I even have the same problem when I run that command (dotnet .\DN.WebApi.Host.dll) in my Host\bin\debug\net6.0 folder... There seems to be something wrong with the code? I'm not sure anymore...

I simply can't get the project to run outside the context of visual studio (or the dotnet sdk for that matter) :-s

iammukeshm commented 2 years ago

Out of my head, I remember one thing. This application needs a Folder named "Files" to be present at the root of the application for it to store static files. Could you ensure that such a folder exists? I remember that the application used to quit because of this.

fretje commented 2 years ago

The files folder is there... Like I said it's also on my devbox... probably on yours as well... just try running dotnet .\DN.WebApi.Host.dll in your host project's bin folder.

iammukeshm commented 2 years ago

if you can see the docketfile available on the API project, there is a line

WORKDIR /app/Files

this ensures that there is a new folder created. I have not tested docker compose of this project for a long time. Will test and get back,

fretje commented 2 years ago

It has nothing to do with docker... the files folder gets created anyway by the publish step, as there is that full-stack-hero-logo.png there...

iammukeshm commented 2 years ago

image

Looks ok to me..You get something different?

fretje commented 2 years ago

yes I do... damn that's strange must be something with my system... I'll try a full reboot first... ;-)

fretje commented 2 years ago

Ok, got it working on my system again, must have been some fluke...

But not on docker... there I still have the same problem after I change connectionstrings for both database and hangfire to connect to the sql server in another container.

Have you got docker working with sql server? Or otherwise with any other database?

iammukeshm commented 2 years ago

image

Yes it works

iammukeshm commented 2 years ago

https://github.com/fullstackhero/dotnet-webapi-boilerplate/blob/main/deployments/dotnet-webapi-with-mssql/docker-compose.mssql.yml

Check this pls

iammukeshm commented 2 years ago

Try this new YAML for building the docker image and then running it.

  api:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: api
    environment:
      - "DatabaseSettings__ConnectionString=Server=db;Database=rootTenantDb;Use\
        r=sa;Password=SuperSecurePassword123!;MultipleActiveResultSets=true"
      - "DatabaseSettings__DBProvider=mssql"
      - "HangfireSettings__Storage__ConnectionString=Server=db;Database=rootTen\
        antDb;User=sa;Password=SuperSecurePassword123!;MultipleActiveResultSets\
        =true"
      - "HangfireSettings__Storage__StorageProvider=mssql"
      - "CacheSettings__RedisURL=redis"
      - "ASPNETCORE_Kestrel__Certificates__Default__Password=securePassword123"
      - "ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx"
      - "ASPNETCORE_URLS=https://+:5051;http://+:5061"
    volumes:
      - ~/.aspnet/https:/https:ro
    ports:
      - "5051:5051"
      - "5061:5061"
    depends_on:
      - db
    restart: on-failure
  db:
    image: "mcr.microsoft.com/mssql/server"
    container_name: db
    restart: always
    environment:
      MSSQL_SA_PASSWORD: "SuperSecurePassword123!"
      SA_PASSWORD: "SuperSecurePassword123!"
      ACCEPT_EULA: "Y"
iammukeshm commented 2 years ago

image

fretje commented 2 years ago

Oh my god... the deployments folder... has that been there all the time? How could I have missed that ;-)

Unfortunately, I tried with your last updates, but still have the same problem:

This is the command I used: PS C:\Projects\fretje\dotnet-webapi-boilerplate> docker-compose up -d --build

The container starts, but stops immediately after the Sponsor message:

image

What command exactly are you using?

iammukeshm commented 2 years ago

https://user-images.githubusercontent.com/31455818/146304848-782f641b-db20-4799-8a79-e7f05d4f7752.mp4

Can you pull the latest and try again?

fretje commented 2 years ago

Still having the same problem.

https://youtu.be/2PIYRKQSl6E

Maybe it has something to do with that certificate? I have a .aspnet\https folder in my home drive, but it's empty... Allthough, when I do this:

PS C:\Projects\fretje\dotnet-webapi-boilerplate> dotnet dev-certs https
A valid HTTPS certificate is already present.

Also very strange that it doesn't say "Server Shutting down"... It must crash somewhere (probably kestrel), but without any errors? Is there a way to enable more kestrel logging?

iammukeshm commented 2 years ago

The above is from a readme on one of repos. can u check if this helps. for installing the cert.

iammukeshm commented 2 years ago

can you also try to change the configured ports and check. Maybe it has some port clash issues and exits.

fretje commented 2 years ago
PS C:\Projects\fretje\dotnet-webapi-boilerplate> dotnet dev-certs https -ep $env:USERPROFILE\.aspnet\https\aspnetapp.pfx -p securePassword123
A valid HTTPS certificate is already present.
fretje commented 2 years ago

Yeah if it's port clashing, we should be able to see that in a log somewhere? Anyways, I tried different port combinations but no different output.

fretje commented 2 years ago

I also don't understand why exactly we need that? What's different with a regular new web api project? Those also work over https right? And that just works in docker on my machine without those ASPNETCORE_Kestrel... variables?

fretje commented 2 years ago

Ok, got it working now, after I did:

PS C:\Projects\fretje\dotnet-webapi-boilerplate> dotnet dev-certs https --clean
Cleaning HTTPS development certificates from the machine. A prompt might get displayed to confirm the removal of some of the certificates.
HTTPS development certificates successfully removed from the machine.
PS C:\Projects\fretje\dotnet-webapi-boilerplate> dotnet dev-certs https -ep $env:USERPROFILE\.aspnet\https\DN.Host.pfx -p SuperSecurePassword123!
The HTTPS developer certificate was generated successfully.
PS C:\Projects\fretje\dotnet-webapi-boilerplate> dotnet dev-certs https --trust
Trusting the HTTPS development certificate was requested. A confirmation prompt will be displayed if the certificate was not previously trusted. Click yes on the prompt to trust the certificate.

and update the values for environment to

      - "ASPNETCORE_Kestrel__Certificates__Default__Password=SuperSecurePassword123!"
      - "ASPNETCORE_Kestrel__Certificates__Default__Path=/https/DN.Host.pfx"

Things finally start working... yay! Thanks for all the help!

Next question is... how to get that running onto an external server... ;-)

iammukeshm commented 2 years ago

You can push this image to docker hub and pull the image from the actual server and spin up the container.

For ex.

docker pull iammukeshm/dotnet-webapi:latest

This command would pull the latest image of the api.

fretje commented 2 years ago

Yep, that I understand, but what about the certificate?

fretje commented 2 years ago

I'm adding a bit of doc's (DOCKER_README.md) to the repository... will issue a pr soon... might be interesting to put all findings over there ;-)

fretje commented 2 years ago

Ok, so TLDR there was an issue with certificates. It's resolved now, so this issue can be closed, apart from the fact maybe that we don't get any meaningful error messages or any error messages at all when that is the case. Although that's probably more of an issue with kestrel? Anyways adding more docs so people can find their way out when they run into this is part of the solution... see #283.