API Net 6 :: CORS issues when running inside Docker container

Hi people

I’m trying to deploy Net 6 API on docker container (using Dockerfile created by Visual Studio itself)

I’m under Ubuntu 22.04 LTS

I get CORS error on Angular and 500 error on postman (when running Net 6 API on docker)

if running outside docker “$ dotnet run” then I get CORS error on Angular but it works on postman

I’m making petitions to a 2nd docker container (which has MS SQL)

both containers are running on same computer

What should I do to solve the issue?

that’s my Dockerfile >>

FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

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

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

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

Hello and welcome!

I guess you have multiple things to consider/check/fix - these are the steps I would do:

  • How do you start and access the container? A Dockerfile is only a blueprint how to create one image based on another image. It does not describe how you start the image to become a container and what the application is trying to do (where it tries to connect to).
  • Maybe you see a more detailed errormessage for the 500-error within Postman? Maybe you need to adjust some settings on how to access the database?
  • The CORS-error also needs more information - where is your Angular-application located (URL?) and where is you Backend (URL?)? I guess both URLs are different. If true you either need to put them behind the same hostname (using a reverse proxy). OR you need some CORS-header to the API’s response to allow you Angular-application-URL to access this ressource.

both containes are answering from localhost and are hosted in the same machine

I can connect to SQL Server machine with Azure Data Studio

Angular app is also in same machine

all is in my home machine, is a personal/home dev enviornment

just I work mainly under Linux OS, hence I prefer to have all my things running on it

I can always start a virtualmachine with windows and work there, but I want to avoid that

I doubt being problem of sql docker container, since the error that gives angular is

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://localhost:6001/api/achats/recollirBesoinsCondi. (Reason: CORS request did not succeed). Status code: (null).

yet I do have CORS allowing any origin on API side

also note that when running from linux console (out of Docker) postman then return the results, yet Angular still giving CORS error

I do not find documentation on official MIcrosoft / Docker webpages about this kind of CORS situation and I do sincerily believe that is a recurrent error

Regarding the CORS-error:
This is a error-message created by your browser, not by the API-container, because protocol, host and port have to be identical (see see: Same Origin Policy - Web Security) to allow access from JavaScript (that is what Angular is [at least in my opinion]: a JavaScript/TypeScript-frontend-framework) or you have to add information to your API’s response-header.
So if your Angular-application might be running on https://localhost:443/… and your api on https://localhost:6001/… the API has to send som header-information telling the browser that it is OK to be called from https://localhost:443/… and the browser will then be happily accepting the API’s response. To allow everyone (you should probably NOT do that): Access-Control-Allow-Origin: *
You wrote that you have added a CORS-header to your API’s responses to allowed all URLs to acces this API - but according to the errormessage your browser has a different opinion on this topic :slight_smile:
If you use Postman to directly access the API there is no CORS-checking involved. It is one request to https://localhost:6001/… and hopefully a successful response.

Maybe another pitfall when moving a service working on a physical computer into a container:
A Docker-container’s localhost is not the same as your physical computer’s localhost. So if you want to connect from within a Docker-container to a service on the physical computer’s localhost you have to use 172.17.0.1 (on Linux it is the default-host-ip-address within Docker’s default network) or host.docker.internal (on Windows-machines). If might be easier if you have all containers needed for your service within the same Docker-network - then you should also be able do access the other container’s service using the container’s name without exposing this container’s port(s) to the outside world (maybe useful for a database in a productive environment).

I tried with 172.17.0.1 since ifconfig was shoing me that IP

at this point I think is the same Net 6 API that even when I’m applying CORS maybes is not working properly

in the code I have

            app.UseCors(x => x.AllowAnyOrigin()
                .AllowAnyHeader()
                .AllowAnyMethod()
            );

yet seems API is not taking care of those, or maybe CORS policies are rewritten by an external service

I’ve seen there is Net 7 around (not yet Linux version)

also…

I’ve just noticed something at launSettings.json (I haven0t tried yet to create a new docker container), if I let Visual Studio create a model Net 6 API with Docker support (mine I started without and later I added Dockerfile)

launchSettings.json have a section called Docker ponting to swagger, I’m just thinking about swaping swagger for api

her is how launchSettings.json are looking
(*changed a bit due limitation of being new user and not being able to post 2 links on a post)

{
  "$schema": "<someschemalink>/launchsettings.json",
  "iisSettings": {
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "<herelinktolocalhost_butIm_new_user_cantpost:2190>",
      "sslPort": 44384
    }
  },
  "profiles": {
    "API": {
      "commandName": "Project",
      "dotnetRunMessages": true,
      "launchBrowser": false,
      "launchUrl": "weatherforecast",
      "applicationUrl": "herelinktolocalhost_butIm_new_user_cantpost:6001;herelinktolocalhost_butIm_new_user_cantpost:6000",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "launchUrl": "swagger",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "Docker": {
      "commandName": "Docker",
      "launchBrowser": true,
      "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger",
      "publishAllPorts": true,
      "useSSL": true
    }
  }
}

First you have to get your API-container up and running fine. Within postman you hopefully can see what your API is responding to the client. Normally it should return a helpful text why it failed to do its job.

CORS: You can check/verify with Postman if your API does send the header as expected (or not):

And if your API is running on a different protocol, host or port (compared to your application) you definitely have to add a Access-Control-Allow-Origin-header.