I was about to deploy my Frontend (Angular Version 16) and my Backend (ASP.NET Core Version 7 with dotnet version 7) on a docker container each.
Those Containers are on my Raspberry Pi 4 ([IP_ADDRESS]:4200 and [IP_ADDRESS]:5180)
.
When I visit my Angular App with my browser I can click through it and it seems to work fine, until I send a request to my backend. When I send a request, I get:
“POST http://localhost:5180/api/auth/login net::ERR_CONNECTION_REFUSED”
The URL is fine, because both docker containers are on the same phsical machine, therefore I want to access localhost.
The Request Header in Chrome network:
Accept:
application/json, text/plain, */*
Content-Type: application/json
Referer: [IP_ADDRESS]:4200/
Sec-Ch-Ua: [OMITTED] // I see the omitted values as not relevant
Sec-Ch-Ua-Mobile: [OMITTED]
Sec-Ch-Ua-Platform: "[OMITTED]"
User-Agent: [OMITTED]
There is no response header. My Angular logging shows me:
“Http failure response for http://localhost:5180/api/auth/login: 0 Unknown Error”
Those are my Dockerfiles:
Angular
FROM node:18 as build
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=build /usr/src/app/dist/recipe_frontend /usr/share/nginx/html
EXPOSE 4200
CMD ["nginx", "-g", "daemon off;"]
ASP.NET
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
WORKDIR /app
COPY . .
RUN dotnet restore
RUN dotnet build -c Release
RUN dotnet publish -c Release -o /app/publish
FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS final
WORKDIR /app
COPY --from=build /app/publish .
EXPOSE 5180
ENTRYPOINT ["dotnet", "recipe_backend.dll"]
My Docker Compose File:
version: '2.27.0'
services:
frontend:
build:
context: ../dev/recipe-app/recipes/recipe_frontend
ports:
- "4200:80"
depends_on:
- backend
networks:
- recipe_network
backend:
build:
context: ../dev/recipe-app/recipes/recipe_backend
ports:
- "5180:80"
networks:
- recipe_network
networks:
recipe_network:
driver: bridge
I also activaed CORS with AllowAnyOrigin, which confuses me even more because It does not work.
I was expecting that it works because My Program.cs file is properly configured if you ask me. CORS is activated at first and used before Authentication and Authorization.
Program.cs
using System.Text;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Mvc.ModelBinding.Binders;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using recipe_backend.Models;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddCors();
builder.Services.AddMvc();
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
// DB Connection
var versionNumber = builder.Configuration.GetSection("DB_Version").Get<int[]>();
var version = new MySqlServerVersion(new Version(versionNumber[0],versionNumber[1],versionNumber[2]));
var connectionStr = builder.Configuration.GetConnectionString("FullStackConnectionString");
builder.Services.AddDbContext<RecipesDbContext>(options => options.UseMySql(connectionStr, version));
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters {
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = builder.Configuration["Jwt:Issuer"],
ValidAudience = builder.Configuration["Jwt:Audience"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]))
};
});
builder.Services.AddAuthorization();
//builder.Services.AddRazorPages();
builder.Services.AddControllers().AddJsonOptions(options =>
{
// Omitted
});
builder.Services.AddHostedService<StartupService>();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
//app.UseSwagger();
//app.UseSwaggerUI();
}
app.UseCors(policy => policy.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
What is even more confusing and this is the most important point where I try to debug:
When i start my Angular application on my PC locally and send a request to my Raspberry Pi ASP.NET backend Docker Container, it perfectly works! But I want the frontend container to work on the Raspberry pi, too…
After hours of configuring Program.cs and inspecting the requests, I don’t know what to do anymore.
How can I solve the Problem of CORS Policy failing when using my Angular NGINX container?