0

So I have a containerized app which consists of react + asp.net core + keycloak + nginx.

I don't want to publish the port of the API to the internet, I only want it to be accessible in the containers' network.

But I can't manage to make my API calls from the React app.

Right now I'm doing them here:

https://localhost:7266

docker-compose of asp.net core container

mediere-api:
    container_name: best-asp.net
    image: ${DOCKER_REGISTRY-}mediere-api
    build:
      context: ..
      dockerfile: Dockerfile
    env_file:
        - .env
    depends_on:
            - db
    expose:
      - "7266"
    volumes:
        - ../certs/certificate.pfx:/etc/https/certs

dockerfile of it

#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/aspnet:6.0 AS base
WORKDIR /app

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

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

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

appsettings.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    deleted
  }
}

launchSettings.json

{
  "profiles": {
    "mediere_API": {
      "commandName": "Project",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Production"
      },
      "applicationUrl": "https://localhost:7266",
      "dotnetRunMessages": true
    },
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Production"
      }
    },
    "Docker": {
      "commandName": "Docker",
      "launchBrowser": true,
      "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}",
      "publishAllPorts": true,
      "useSSL": true
    }
  }
}

.env

#ASP.Net core
ASPNETCORE_STATICWEBASSETS="/app/bin/Debug/net6.0/mediere-api.staticwebassets.runtime.CT.json"
ASPNETCORE_ENVIRONMENT=Production
ASPNETCORE_URLS=https://localhost:7266

Proogram.cs

using mediere_API.DataLayer;
using mediere_API.DataLayer.Repository.Implementations;
using mediere_API.DataLayer.Repository.Interfaces;
using mediere_API.Extensions;
using mediere_API.Middleware;
using mediere_API.Processors.Implementations;
using mediere_API.Processors.Interfaces;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args);

//Servicii
builder.Services.AddControllers();
builder.Services.ConfigureSwagger();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddRouting(options => options.LowercaseUrls = true);

builder.Services.AddRepositories();
builder.Services.AddProcessors();

//UnitsOfWork
builder.Services.AddScoped<ISchemaUnitOfWork, SchemaUnitOfWork>();
builder.Services.AddScoped<IMainUnitOfWork, MainUnitOfWork>();

//AutoMapper
builder.Services.AddAutoMapper(typeof(Program));
//Keycloak
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, o =>
    {
        o.MetadataAddress = "https://keycloak:8443/auth/realms/best-realm/.well-known/openid-configuration";
        o.Authority = "https://keycloak:8443/auth/realms/best-realm";
        o.Audience = "account";
        o.RequireHttpsMetadata = false;
    });
//CORS
builder.Services.AddCors(options =>
{
    options.AddDefaultPolicy(
        policy =>
        {
            policy.AllowAnyOrigin()
                .AllowAnyHeader()
                .AllowAnyMethod()
                .WithExposedHeaders("FileName");
        });
});

builder.Services.AddDbContext<EfDbContext>();
builder.Services.AddDbContext<SchemaEfDbContext>();


var app = builder.Build();
AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}
app.UseHttpsRedirection();

app.UseMiddleware<SchemaHandlingMiddleware>();

app.UseCors();

app.UseAuthorization();

app.MapControllers();

app.Run();

With these settings, my API calls don't seem to reach the Docker container. I get:

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

status code null means that the container couldn't be reached I think.

So what's wrong with my settings?

How should I do my API calls to the ASP container from docker in order for them to work?

Thanks.

2
  • Are you serving a react app through NGINX on the browser to send HTTP-request to DOTNET API? Commented Oct 8, 2022 at 21:06
  • Yes, that's right :) Commented Oct 9, 2022 at 16:39

1 Answer 1

2
  • Same Origin serving approach using reverse proxy:

    You should reverse proxy your API inside your nginx configuration. Something like this:

    nginx.conf:

    location / proxy_pass: TO_YOUR_REACT_APP or: SERVER_YOUR_REACT_APP_STATIC_FILES

    location /api proxy_pass: TO_YOUR_API

    This approach makes your API and REACT app to be at the same origin. So there will be no CORS error.

  • Enabling CORS for requests that you are sending via browser. Please share a screen shot from your browser console error in order th help you with.

Sign up to request clarification or add additional context in comments.

4 Comments

wouldn't that expose my API though? I want it to be available only in the docker bridge network, not outside
You can't send requests from the browser to your docker bridge network. It should be exposed. The internal network of Docker is only for inner services in the same network inside Docker. The browser is not inside the docker
So the API needs to be exposed?
Yes you have two options, Exposing your API and opening CORS requests. Proxying your API and exposing via NGINX-API internal network to avoid sending cross-origin requests

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.