falafel
falafel

Reputation: 23

API doesn't work, using Docker and ASP.NET CORE

I made an ASP.NET Core web API that pings a Mongodb and a docker container for it. The web api calls work when not using docker but returns a Not Found error when I do use it. I think it has something to do with the ports I'm running on but I'm not sure cause this is the first time I've used docker.

In the command prompt I do:

docker build -t projectname .

And then I run the image with

docker run -p 8080:80 projectname

Once running, if I make a call to http://localhost:8080/api/classname, I get a Not Found error with the message "this is my invalid message" so it seems like my docker container IS running. When I make a call to http://localhost:8080/api/classname?id=1 (this is a valid id), I still get a Not Found error but don't get the "this is my invalid message" text.

ClassNameController API GET:

[Route("api/[controller]")]
    [ApiController]
    public class ClassNameController : Controller
    {
        [HttpGet]
        public IActionResult GetDescendents(int id)
        {
            var mongoDbService = new MongoDbService();

      
            try
            {
                var node = mongoDbService.GetTreeNodeById(id);

                if (node == null)
                {
                    return NotFound("this is my invalid message");
                }
                else
                {
                    //stuff happens
                }
            }
            catch (Exception e)
            {
                return BadRequest(e);
            }

            return Ok();
        }

Dockerfile:

See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY ["ProjectName/ProjectName.csproj", "ProjectName/"]
RUN dotnet restore "ProjectName/ProjectName.csproj"
COPY . .
WORKDIR "/src/ProjectName"
RUN dotnet build "ProjectName.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "ProjectName.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "ProjectName.dll"]

launchSetting.json:

{
  "iisSettings": {
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:8080",
      "sslPort": 8080
    }
  },
  "$schema": "http://json.schemastore.org/launchsettings.json",
  "profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "launchUrl": "",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "DockerAPI": {
      "commandName": "Project",
      "launchBrowser": true,
      "launchUrl": "",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      },
      "applicationUrl": "https://localhost:5001;http://localhost:5000"
    },
    "Docker": {
      "commandName": "Docker",
      "launchBrowser": true,
      "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/",
      "publishAllPorts": true,
      "useSSL": true
    }
  }
}

Upvotes: 1

Views: 1668

Answers (1)

The web API and mongo service are likely to be on different networks when you use it in a docker container, considering that you have not defined it.

A quick way to solve this is to change the localhost from your mongo connection string from your IP number, in your appsettings, like this:

"ConnectionString":"mongodb://192.168.0.27:27017"

Pay attention, in your Dockerfile you don't define the environment, in this case, your app in docker will use the production appsettings and not your appsettings.Development.

If you prefer up both of then in a compose, you'll can define a network for all your services and then use just the name of the service on the connection string, like this:

 "ConnectionString":"mongodb://mongo"

Example docker-compose.yml:

version: "3.7"

services:
  mongo:
    image: mongo
    restart: always
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: example
    networks:
      - mynetwork  

  mongo-express:
    image: mongo-express
    restart: always
    ports:
      - 8081:8081
    environment:
      ME_CONFIG_MONGODB_ADMINUSERNAME: root
      ME_CONFIG_MONGODB_ADMINPASSWORD: example
    networks:
      - mynetwork

  webapi:
    container_name: webapi
    build:
      context: .
      dockerfile: ./YourProject/Dockerfile
    ports:
      - 8080:80
    depends_on:
      - mongo
    links:
      - mongo
    networks:
      - mynetwork

networks:
  mynetwork:
    driver: bridge

And then:

docker-compose up

Upvotes: 2

Related Questions