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)
- 
    0To 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. 
- 
    0It did not solve the problem. 
- 
    0hi 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. 
- 
    0hi, 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>()); }); }
- 
    0hi 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
- 
    0I 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. 
- 
    0hi The Blazor wasm appsettings.jsonfile is under thewwwrootfolder. Have you changed the correct file?Thanks. 
- 
    0Yes, by mounting volumes: - ./appsettings.json:/app/wwwroot/appsettings.json
- 
    0hi Can you enter the container and use lessorvimcommand to check the file content?Thanks. 
- 
    0
- 
    0hi Can you share a demo project? I will check it in my local Docker Desktop liming.ma@volosoft.com Thanks 
- 
    0I 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 
- 
    0hi The final question is: In Docker, when you change the appsettings.jsonunderwwwrootfor Blazor WASM, the browser can't get the latest changes, right?Thanks. 
- 
    0Yes, thats right. 
- 
    0ok, I will test it in Docker. Thanks. 
- 
    0Thanks, will wait for your responce. 
- 
    0ok, I will test it asap. Thanks. 
- 
    0hi 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
- 
    0Hi, 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
- 
    0No, 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









 
                                