Hi Abp Team,
I am having trouble configuring the URL for the Blazor UI for Docker container after publishing. The situation is that after publishing, the container only works with the AppSelfUrl that was used while creating the project image. So, I tried the solution suggested in placing UseStaticFiles() before AbpMapStaticAssets(), but it did not solve the issue. I also tried adding BlazorEnableCompression to Blazor.Client.csproj to disable compression, but it also did not help. I used methods like UseStaticFilesForPatterns("appsettings*.json") and UseStaticFiles() with and without AbpMapStaticAssets().
What I want is to be able to change the configuration of the Blazor project after publishing. The project consists of multiple modules.
29 Answer(s)
-
0
To change the configuration (such as API URLs) of an ABP Blazor WebAssembly application after publishing—especially in a Docker or cloud environment—you should use environment-specific configuration files that can be overridden at runtime.
Key Solution Steps:
Use environment-specific JSON files:
- Place
appsettings.{ENVIRONMENT}.json(e.g.,appsettings.Production.json) in thewwwrootfolder of your Blazor WASM project. - At runtime, the Blazor app will fetch the appropriate configuration file based on the environment.
- Place
Override configuration at runtime:
- In Docker or Kubernetes, mount a volume or use a ConfigMap/Secret to provide the correct
appsettings.{ENVIRONMENT}.jsonfile at container startup. - This allows you to change URLs and other settings without rebuilding the image.
- In Docker or Kubernetes, mount a volume or use a ConfigMap/Secret to provide the correct
Static file serving order:
- Ensure
app.UseStaticFiles()is called beforeapp.MapAbpStaticAssets()in your host project’sProgram.csorStartup.cs. - Example:
- Ensure
app.UseStaticFiles(); app.MapAbpStaticAssets();- Disable Blazor compression if needed:
- If you need to disable compression for easier file replacement, add the following to your
.csproj:
- If you need to disable compression for easier file replacement, add the following to your
<BlazorEnableCompression>false</BlazorEnableCompression>- This ensures files like
appsettings.jsonare not compressed and can be replaced or read as plain text.
- UseStaticFilesForPatterns:
- If you want to serve only specific files, you can use:
app.UseStaticFilesForPatterns("appsettings*.json");- Reload configuration:
- Blazor WASM reads configuration at startup. If you replace the config file, you must reload the app in the browser to pick up changes.
Summary:
For Dockerized or cloud deployments, provide the correctappsettings.{ENVIRONMENT}.jsonat runtime via volume mounts or similar mechanisms. Ensure static files are served correctly and compression is disabled if you need to override files after publishing.Sources:
- Deployment microservices solution in K8S public cloud
- ABP Documentation: Configuration
- ABP Documentation: Blazor WASM Deployment
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
-
0
It did not solve the problem.
-
0
hi
Please share your startup module code?
The correct middleware code/order should be:
app.UseRouting(); var configuration = context.GetConfiguration(); if (Convert.ToBoolean(configuration["AuthServer:IsOnK8s"])) { app.Use(async (context, next) => { if (context.Request.Path.Value != null && context.Request.Path.Value.StartsWith("/appsettings", StringComparison.OrdinalIgnoreCase) && context.Request.Path.Value.EndsWith(".json", StringComparison.OrdinalIgnoreCase)) { // Set endpoint to null so the static files middleware will handle the request. context.SetEndpoint(null); } await next(context); }); app.UseStaticFilesForPatterns("appsettings*.json"); } app.MapAbpStaticAssets();Thanks.
-
0
hi, I tried you suggestion but without if.It still did not worked.
Below is Blazor Module ▼
public override void OnApplicationInitialization(ApplicationInitializationContext context) { var env = context.GetEnvironment(); var app = context.GetApplicationBuilder(); // Configure the HTTP request pipeline. if (env.IsDevelopment()) { app.UseWebAssemblyDebugging(); } else { // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseHttpsRedirection(); app.UseRouting(); app.Use(async (context, next) => { if (context.Request.Path.Value != null && context.Request.Path.Value.StartsWith("/appsettings", StringComparison.OrdinalIgnoreCase) && context.Request.Path.Value.EndsWith(".json", StringComparison.OrdinalIgnoreCase)) { // Set endpoint to null so the static files middleware will handle the request. context.SetEndpoint(null); } await next(context); }); app.UseStaticFilesForPatterns("appsettings*.json"); app.MapAbpStaticAssets(); app.UseAntiforgery(); app.UseConfiguredEndpoints(builder => { builder.MapRazorComponents<App>() .AddInteractiveWebAssemblyRenderMode() .AddAdditionalAssemblies(WebAppAdditionalAssembliesHelper.GetAssemblies<BillingBlazorClientModule>()); }); } -
0
hi
Can you output some logs when
context.SetEndpoint(null);? Make sure theEndpointisnullfor appsettings.json request.// Set endpoint to null so the static files middleware will handle the request. context.SetEndpoint(null);
Or can you try that?
public override void OnApplicationInitialization(ApplicationInitializationContext context) { var env = context.GetEnvironment(); var app = context.GetApplicationBuilder(); // Configure the HTTP request pipeline. if (env.IsDevelopment()) { app.UseWebAssemblyDebugging(); } else { // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAntiforgery(); app.UseConfiguredEndpoints(builder => { builder.MapRazorComponents<App>() .AddInteractiveWebAssemblyRenderMode() .AddAdditionalAssemblies(WebAppAdditionalAssembliesHelper.GetAssemblies<BillingBlazorClientModule>()); }); }Thanks.
-
0
-
0
-
0
-
0
I tried still same result. Also removed volumes and on creating image used --no-cache. It always works on url that was configured before docker build.
-
0
hi
The Blazor wasm
appsettings.jsonfile is under thewwwrootfolder. Have you changed the correct file?Thanks.
-
0
Yes, by mounting
volumes: - ./appsettings.json:/app/wwwroot/appsettings.json -
0
hi
Can you enter the container and use
lessorvimcommand to check the file content?Thanks.
-
0
-
0
hi
Can you share a demo project?
I will check it in my local Docker Desktop
liming.ma@volosoft.com
Thanks
-
0
I have an Internet issue, so may i ask you to create project in AbpStudio for criterias like :
- Application(layerd)
- BlazorWevAssembly
- EntityFramework
- PostgreSQL
- Enable Multi-Tenancy
- Add public website
- Solution structure: Tiered true
- Kubernetes false
- Set up as a modular solution
Then create images and in directory ./etc/docker-compose in appsettings.json file change url for blazor , then update docker-compose file with the same url where it used in relations like db-migrator, api, auth and set port of blazor service to 80
-
0
hi
The final question is: In Docker, when you change the
appsettings.jsonunderwwwrootfor Blazor WASM, the browser can't get the latest changes, right?Thanks.
-
0
Yes, thats right.
-
0
ok, I will test it in Docker.
Thanks.
-
0
Thanks, will wait for your responce.
-
0
ok, I will test it asap.
Thanks.
-
0
hi
It works on my side.
public override void OnApplicationInitialization(ApplicationInitializationContext context) { var env = context.GetEnvironment(); var app = context.GetApplicationBuilder(); // Configure the HTTP request pipeline. if (env.IsDevelopment()) { app.UseWebAssemblyDebugging(); } else { // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseHttpsRedirection(); app.UseRouting(); app.Use(async (context, next) => { if (context.Request.Path.Value != null && context.Request.Path.Value.StartsWith("/appsettings", StringComparison.OrdinalIgnoreCase) && context.Request.Path.Value.EndsWith(".json", StringComparison.OrdinalIgnoreCase)) { // Set endpoint to null so the static files middleware will handle the request. context.SetEndpoint(null); } await next(context); }); app.UseStaticFilesForPatterns("appsettings*.json"); app.MapAbpStaticAssets(); app.UseAntiforgery(); app.UseConfiguredEndpoints(builder => { builder.MapRazorComponents<App>() .AddInteractiveWebAssemblyRenderMode() .AddAdditionalAssemblies(WebAppAdditionalAssembliesHelper.GetAssemblies<AbpSolution6BlazorClientModule>()); }); }services: abpsolution6-blazor: image: abpsolution6-blazor:latest container_name: abpsolution6-blazor build: context: ../../ dockerfile: src/AbpSolution6.Blazor/Dockerfile.local environment: - ASPNETCORE_URLS=https://+:8081; - Kestrel__Certificates__Default__Path=/app/certs/localhost.pfx - Kestrel__Certificates__Default__Password=d55cb215-fa18-408d-80c9-e21ca6061c84 ports: - "44336:8081" depends_on: - abpsolution6-api restart: on-failure volumes: - ./appsettings.json:/app/wwwroot/appsettings.json - ./certs:/app/certs networks: - abp-network abpsolution6-api: image: abpsolution6-api:latest container_name: abpsolution6-api hostname: abpsolution6-api build: context: ../../ dockerfile: src/AbpSolution6.HttpApi.Host/Dockerfile.local environment: - ASPNETCORE_URLS=https://+:8081; - Kestrel__Certificates__Default__Path=/app/certs/localhost.pfx - Kestrel__Certificates__Default__Password=d55cb215-fa18-408d-80c9-e21ca6061c84 - App__SelfUrl=https://localhost:44349 - App__CorsOrigins=http://localhost:44336 - App__HealthCheckUrl=http://abpsolution6-api:8080/health-status - AuthServer__RequireHttpsMetadata=false - AuthServer__Authority=https://localhost:44366 - ConnectionStrings__Default=Data Source=sql-server;Initial Catalog=AbpSolution6;User Id=sa;Password=myPassw0rd;MultipleActiveResultSets=true;TrustServerCertificate=True; ports: - "44366:8081" depends_on: sql-server: condition: service_healthy restart: on-failure volumes: - ./certs:/app/certs networks: - abp-network db-migrator: image: abpsolution6-db-migrator:latest container_name: db-migrator build: context: ../../ dockerfile: src/AbpSolution6.DbMigrator/Dockerfile.local environment: - OpenIddict__Applications__AbpSolution6_Blazor__RootUrl=http://localhost:44336 - ConnectionStrings__Default=Data Source=sql-server;Initial Catalog=AbpSolution6;User Id=sa;Password=myPassw0rd;MultipleActiveResultSets=true;TrustServerCertificate=True; restart: on-failure depends_on: sql-server: condition: service_healthy networks: - abp-network sql-server: container_name: sql-server image: mcr.microsoft.com/azure-sql-edge:1.0.7 ports: - "1434:1433" environment: SA_PASSWORD: "myPassw0rd" ACCEPT_EULA: "Y" volumes: - sqldata:/var/opt/mssql networks: - abp-network healthcheck: test: /opt/mssql-tools/bin/sqlcmd -S sql-server -U sa -P "myPassw0rd" -Q "SELECT 1" -C -b -o /dev/null interval: 10s timeout: 3s retries: 10 start_period: 10s volumes: sqldata: name: abpsolution6_sqldata networks: abp-network: name: abpsolution6-network driver: bridge -
0
Hi, yes it is working. It overriding it. Try to change localhost to random url. In api it works, but in blazor it does not work. Thanks.
-
0
-
0
No, I ment url not port
{ "App": { "SelfUrl": "http://test.company:44336" }, "AuthServer": { "Authority": "https://localhost:44376", "ClientId": "Billing_Blazor", "ResponseType": "code" }, "RemoteServices": { "Default": { "BaseUrl": "https://localhost:44317" }, "AbpAccountPublic": { "BaseUrl": "https://localhost:44376" } } } -
0








