Develop환경은 Windows고 Release환경은 Linux이다보니 BasePath/ContentRoot를 찾는데에 문제가 발생하였다.
그 중 릴리즈 환경(Release/Linux)에서 500 에러
(Failed to load resource : the server responded with a status of 500())가 발생하며 index.html
을 가져올 수 없는 문제.
오류 사항은 대강 다음과 같았다.
dotnet[{secret}]: System.InvalidOperationException: No file provider has been configured to process...
dotnet[{secret}]: at Microsoft.AspNetCore.Mvc.Infrastructure.VirtualFileResultExecutor.GetFileInfor...
dotnet[{secret}]: at Microsoft.AspNetCore.Mvc.Infrastructure.VirtualFileResultExecutor.ExecuteAsync...
dotnet[{secret}]: at Microsoft.AspNetCore.Mvc.VirtualFileResult.ExecuteResultAsync(ActionContext co...
dotnet[{secret}]: at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultAsync(IAct...
dotnet[{secret}]: at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFi...
dotnet[{secret}]: at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeNextResultFilter...
dotnet[{secret}]: --- End of stack trace from previous location where exception was thrown --- ...
dotnet[{secret}]: at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecuted...
dotnet[{secret}]: at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFi...
dotnet[{secret}]: at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters() ...
dotnet[{secret}]: --- End of stack trace from previous location where exception was thrown --- ...
dotnet[{secret}]: at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineA...
dotnet[{secret}]: at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaite...
dotnet[{secret}]: at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_...
dotnet[{secret}]: at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context) ...
dotnet[{secret}]: at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context) ...
dotnet[{secret}]: at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext ...
dotnet[{secret}]: at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContex...
dotnet[{secret}]: at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessReq...
주요사항은
System.InvalidOperationException: No file provider has been configured to process the supplied file.
이며, 제공된 파일을 처리할 File Provider가 없다는 이야기를 한다.
감사하게도, 문제를 파악하기 쉽게 이하와 같이 구동시에 Content root path를 보여준다.
info: Microsoft.Hosting.Lifetime[0]
dotnet[{secret}]: Now listening on: {secret}
dotnet[{secret}]: info: Microsoft.Hosting.Lifetime[0]
dotnet[{secret}]: Application started. Press Ctrl+C to shut down.
dotnet[{secret}]: info: Microsoft.Hosting.Lifetime[0]
dotnet[{secret}]: Hosting environment: Production
dotnet[{secret}]: info: Microsoft.Hosting.Lifetime[0]
dotnet[{secret}]: Content root path: /
상기 로그에 기재된 Content root path
가 최상단 루트인 /
이다.
Content root path가 최상위 폴더라서, wwwroot에 있는 webpage를 가져올 수 없었던 것이다.
wwwroot를 static한 content폴더로 사용하고 있다면, Main
문이 포함된 Program.cs
의 CreateHostBuilder
함수를 다음과 같은 방식으로 설정하여 Content Root
를 수정할 수 있다.
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseContentRoot(AppDomain.CurrentDomain.BaseDirectory);
webBuilder.UseStartup<Startup>();
});
상기와 같이 작성하게 되면 Windows/Development
환경에서도 Release(publish)
폴더를 참조한다.
그래서 이번엔 Dev환경에서 500 오류
를 발생
다음과 같이 수정하였다.
public static IHostBuilder CreateHostBuilder(string[] args){
var coreEnv = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
var isRelease = coreEnv != Environments.Development;
var builder = Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
if (isRelease)
{
webBuilder.UseContentRoot(AppDomain.CurrentDomain.BaseDirectory);
}
webBuilder.UseStartup<Startup>();
});
return builder;
}
Startup
의 Configure
에서 env.ContentRootPath
를 수정하는 것은 별 도움이 되지 않았다.