7

I am trying to run a simple web api via docker.

I have followed all the steps mentioned in the docs.

FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build-env
WORKDIR /app

# Copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore

# Copy everything else and build
COPY . ./
RUN dotnet publish -c Release -o out

# Build runtime image
FROM mcr.microsoft.com/dotnet/core/aspnet:2.2
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "aspnetapp.dll"]

Screenshot:

enter image description here enter image description here

Commands that I am using to run api via docker:

docker build -t aspnetapp .
docker run -d -p 8080:80 --name myapp aspnetapp

Please note that the api works when I execute the following commands in command line so there is likely nothing wring with the api itself:

dotnet publish -c Release -o out
dotnet run out/ApiForDocker.dll

EDIT:

enter image description here

launchSettings

{
  "$schema": "http://json.schemastore.org/launchsettings.json",
  "iisSettings": {
    "windowsAuthentication": false, 
    "anonymousAuthentication": true, 
    "iisExpress": {
      "applicationUrl": "http://localhost:63852",
      "sslPort": 44318
    }
  },
  "profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "launchUrl": "api/values",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "ApiForDocker": {
      "commandName": "Project",
      "launchBrowser": true,
      "launchUrl": "api/values",
      "applicationUrl": "https://localhost:5001;http://localhost:5000",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}
SamuraiJack
  • 5,131
  • 15
  • 89
  • 195
  • 1
    Check the Ports. You try to open localhost:5001, but map the internal port 80 to 8080 on your machine. – Edub Mar 27 '20 at 07:50
  • 1
    @Edub I corrected the port. Thanks. But its still not working :/ please see my edit – SamuraiJack Mar 27 '20 at 07:59
  • @Edub also why does it always say `Now listening on: http://[::]:80` – SamuraiJack Mar 27 '20 at 08:29
  • That's fine the app is listening on Port :80. To be clear you started your container with docker run -d -p 5001:80 --name myapp aspnetapp right? Looks fine to me if it is this way. – Edub Mar 27 '20 at 10:01
  • I would change the dockerfile to include EXPOSE 80 command so that the port 80 is opened. Then as you did with the port mapping, the app should be available in the host port which redirects to port 80 of the container. – Jeeva Mar 27 '20 at 10:15

2 Answers2

17

I'm new on docker and I had same problem when create new mvc core project, with docker debugger on VS2019, trying a lot of things and finally got my answer on this: https://stackoverflow.com/a/69036711/12537072 thank to @ChinaHelloWorld, just edit 'launchSettings.json' and change "publishAllPorts" to false.

"Docker": {
    "commandName": "Docker",
    "launchBrowser": true,
    "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}",
    "publishAllPorts": false,
    "useSSL": true
}
1

It looks right to me.

A useful debugging option is to add RUN ls -al to your runtime step to make sure your are targeting the right app-name.dll entry.

# Build runtime image
FROM mcr.microsoft.com/dotnet/core/aspnet:2.2
WORKDIR /app
COPY --from=build-env /app/out .
RUN ls -al
ENTRYPOINT ["dotnet", "aspnetapp.dll"]

Then look for the output during build. Or you can ssh into the a running container to verify it.

$ docker exec -it container-id bash.

Also, you can always try switching to another port in Properties > launchSettings.json and then update your Dockerfile entrypoint with that port and --urls-args like:

ENTRYPOINT ["dotnet", "aspnetapp.dll", "--urls", "http://*:6001"]

Then you also need to map that port on your host machine -p 8080:6001. Also make sure your container is listening to that interface as well (0.0.0.0).

Update

Now when you have provided your launchSettings:

"ApiForDocker": {
  "commandName": "Project",
  "launchBrowser": true,
  "launchUrl": "api/values",
  "applicationUrl": "https://localhost:5001;http://localhost:5000",
  "environmentVariables": {
    "ASPNETCORE_ENVIRONMENT": "Development"
  }
}

You can update your docker entrypoint to:

ENTRYPOINT ["dotnet", "aspnetapp.dll", "--urls", "http://*:5000"]

and map the container on your host machine with -p 5000:5000 and then localhost:5000/api/values should give you your API GET response on that route in your browser.

Henkolicious
  • 1,273
  • 2
  • 17
  • 34
  • 2
    Bingo! it's working now. This is the first time I have run an app in Docker! Yeey! Couple of questions here: 1. What is the relationship between "applicationUrl" and "http://*:5000"? 2. Can I not have ""https://*" ? 3. How do I map multiple host ports to a single docker port? – SamuraiJack Mar 27 '20 at 10:54
  • Congratz! Well, you are building a web server called kestrel with .NET Core which you are hosting in a docker container. 1. The `applicationUrl` is the startup option for your kestrel web server I believe . And the `*` part I think exposes interface 0.0.0.0. `--urls` is actually a dotnet thing: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/host/web-host?view=aspnetcore-3.1#override-configuration – Henkolicious Mar 27 '20 at 11:10
  • 1
    2. Not sure what you mean. 3. When you start your container, just add the `-p`argument for port mapping between your host and the running container. Like `-p 5000:5000 -p 3333:5000` and browse to `localhost:5000/api/values` or `localhost:3333/api/values` and you will hit the same running container. – Henkolicious Mar 27 '20 at 11:16
  • 2. I meant can i not have https instead of http as you have mentioned "http://*:5000" 3. I get that I could map ports with -p What I meant was Can I map multiple host ports to single docker port at the same time? For eg/ `localhost:3333` and `localhost:3334` both should be mapped to port 80 in docker. I dont think I can do `docker run -d -p 3333,3334:80` – SamuraiJack Mar 27 '20 at 11:34
  • 1
    2. Well of course you can use SSL on kestrel, but then you need to place your certificate in the container (or via volumes) and tell kestrel to use that certificate I believe. When you run this command in docker `RUN dotnet publish -c Release -o out` your local developer cert is not legit hence it's a release configuration. 3. Maybe I don't understand your question on what you're trying to achieve here. Do you want to map your host machine (your PC) ports `localhost:3333` and `localhost:3334` to your running container port `localhost:80`? – Henkolicious Mar 27 '20 at 11:48
  • 3. When I type localhost:3333/api/values I browser address bar, I should get "hello world" when I type localhost:3334/api/values I should again get "hello world" I want to point both the ports to same api container – SamuraiJack Mar 27 '20 at 11:53