Added docker-compose. Updated startups for API and Web layer.
Some checks failed
ci / build-test (push) Has been cancelled
ci / publish-image (push) Has been cancelled

This commit is contained in:
2026-02-24 00:25:03 -05:00
parent 80ca1296e5
commit ab3524ea20
13 changed files with 166 additions and 41 deletions

View File

@@ -2,13 +2,16 @@ using JSMR.Api.Startup;
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
ConfigurationManager configuration = builder.Configuration;
IWebHostEnvironment environment = builder.Environment;
builder.Services
.AddAppServices(builder)
.AddAppServices(configuration)
.AddAppJson()
.AddAppOpenApi()
.AddAppAuthentication()
.AddAppCors(builder)
.AddAppLogging(builder);
.AddAppAuthentication(environment)
.AddAppCors(configuration);
//.AddAppLogging(builder);
builder.Host.UseAppSerilog();

View File

@@ -1,9 +1,31 @@
using Serilog;
using Serilog.Events;
namespace JSMR.Api.Startup;
public static class HostBuilderExtensions
{
public static IHostBuilder UseAppSerilog(this IHostBuilder host)
=> host.UseSerilog();
{
return host.UseSerilog((context, services, loggerConfiguration) =>
{
IConfiguration configuration = context.Configuration;
IHostEnvironment environment = context.HostingEnvironment;
loggerConfiguration
.ReadFrom.Configuration(configuration)
.ReadFrom.Services(services)
.MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
.Enrich.WithProperty("Service", "JSMR.Api")
.Enrich.WithProperty("Environment", environment.EnvironmentName);
// Conditionally add Seq if configured correctly
string? seqUrl = configuration["Seq:ServerUrl"];
if (Uri.TryCreate(seqUrl, UriKind.Absolute, out _))
{
loggerConfiguration.WriteTo.Seq(seqUrl);
}
});
}
}

View File

@@ -4,8 +4,6 @@ using JSMR.Infrastructure.DI;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Http.Json;
using Microsoft.EntityFrameworkCore;
using Serilog;
using Serilog.Events;
using System.Text.Json;
using System.Text.Json.Serialization;
@@ -13,14 +11,14 @@ namespace JSMR.Api.Startup;
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddAppServices(this IServiceCollection services, IHostApplicationBuilder builder)
public static IServiceCollection AddAppServices(this IServiceCollection services, IConfigurationManager configuration)
{
services
.AddMemoryCache()
.AddApplication()
.AddInfrastructure();
string connectionString = builder.Configuration.GetConnectionString("AppDb")
string connectionString = configuration.GetConnectionString("AppDb")
?? throw new InvalidOperationException("Missing ConnectionStrings:AppDb");
services.AddDbContextFactory<AppDbContext>(opt =>
@@ -51,7 +49,7 @@ public static class ServiceCollectionExtensions
return services;
}
public static IServiceCollection AddAppAuthentication(this IServiceCollection services)
public static IServiceCollection AddAppAuthentication(this IServiceCollection services, IHostEnvironment environment)
{
services.AddAuthorization();
@@ -61,8 +59,15 @@ public static class ServiceCollectionExtensions
{
options.Cookie.Name = "vw_auth";
options.Cookie.HttpOnly = true;
options.Cookie.SameSite = SameSiteMode.None;
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
//options.Cookie.SameSite = SameSiteMode.None;
//options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
options.Cookie.SameSite = SameSiteMode.Lax;
options.Cookie.SecurePolicy =
environment.IsDevelopment()
? CookieSecurePolicy.SameAsRequest
: CookieSecurePolicy.Always;
options.Events = new CookieAuthenticationEvents
{
@@ -82,37 +87,44 @@ public static class ServiceCollectionExtensions
return services;
}
public static IServiceCollection AddAppCors(this IServiceCollection services, IHostApplicationBuilder builder)
public static IServiceCollection AddAppCors(this IServiceCollection services, IConfigurationManager configuration)
{
// Prefer config-based origins so you stop editing code for ports.
// appsettings.Development.json:
// "Cors": { "AllowedOrigins": [ "https://localhost:7112", ... ] }
string[] origins = builder.Configuration.GetSection("Cors:AllowedOrigins").Get<string[]>() ?? [];
string[] origins = configuration.GetSection("Cors:AllowedOrigins").Get<string[]>() ?? [];
services.AddCors(options =>
{
options.AddPolicy("ui", policyBuilder =>
{
if (origins.Length == 0)
{
// In container/prod you often don't need CORS at all (same-origin),
// but if it *is* needed and not configured, fail closed rather than crash.
// Do not call WithOrigins().
return;
}
policyBuilder.WithOrigins(origins)
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials());
.AllowCredentials();
});
});
return services;
}
public static IServiceCollection AddAppLogging(this IServiceCollection services, IHostApplicationBuilder builder)
{
var config = builder.Configuration;
var env = builder.Environment;
//public static IServiceCollection AddAppLogging(this IServiceCollection services, IHostApplicationBuilder builder)
//{
// var config = builder.Configuration;
// var env = builder.Environment;
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(config)
.MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
.Enrich.WithProperty("Service", "JSMR.Api")
.Enrich.WithProperty("Environment", env.EnvironmentName)
.CreateLogger();
// Log.Logger = new LoggerConfiguration()
// .ReadFrom.Configuration(config)
// .MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
// .Enrich.WithProperty("Service", "JSMR.Api")
// .Enrich.WithProperty("Environment", env.EnvironmentName)
// .CreateLogger();
return services;
}
// return services;
//}
}

View File

@@ -15,12 +15,18 @@ public static class WebApplicationExtensions
{
public static WebApplication UseAppPipeline(this WebApplication app, IHostEnvironment env)
{
app.UseCors("ui");
string[] origins = app.Configuration.GetSection("Cors:AllowedOrigins").Get<string[]>() ?? [];
if (origins.Length > 0)
app.UseCors("ui");
if (env.IsDevelopment())
app.MapOpenApi();
app.UseHttpsRedirection();
if (!env.IsDevelopment())
{
app.UseHttpsRedirection();
}
app.UseAuthentication();
app.UseAuthorization();

View File

@@ -25,11 +25,10 @@
},
"Enrich": [ "FromLogContext", "WithMachineName", "WithProcessId", "WithThreadId" ],
"WriteTo": [
{ "Name": "Console" },
{
"Name": "Seq",
"Args": { "serverUrl": "%SEQ_URL%" }
}
{ "Name": "Console" }
]
},
"Seq": {
"ServerUrl": ""
}
}