Search code examples
apacheubuntuasp.net-corestatic-fileskestrel-http-server

Unable to load static files from .NET Core web app using Ubuntu/Apache


I have a .NET Core 3.1 web app running on an Ubuntu 20.04 server through Apache 2.4.41. When I visit the web address, I'm served the website - links work fine, but I'm getting 404 file not found errors for images, styles and JavaScript.

Example from journalctl Kestrel service log:

Request starting HTTP/1.1 GET http://example.com/favicon.ico
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
Request finished in 0.3686ms 404

My static file directory structure is default:

wwwroot
- css
-- site.css
- images
-- image1.jpg
-- image2.jpg
- js
-- site.js
- favicon.ico

My Configure method is mostly default:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseForwardedHeaders();

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Shared/Error");
        app.UseHsts();
    }
    app.UseStaticFiles();
    app.UseHttpsRedirection();
    app.UseCookiePolicy();
    app.UseRouting();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
    });
}

Website's config in '/etc/apache2/sites-enabled' is:

<VirtualHost *:80>
    ServerName example.com
    Redirect permanent / https://example.com
</VirtualHost>

<IfModule mod_ssl.c>
        <VirtualHost _default_:443>
                ProxyPreserveHost On
                ProxyPass / http://127.0.0.1:5000/
                ProxyPassReverse / http://127.0.0.1:5000/
                ServerAdmin webmaster@localhost
                ServerName example.com:443
                DocumentRoot /var/www/example.com
                ErrorLog ${APACHE_LOG_DIR}/example.com-error.log
                CustomLog ${APACHE_LOG_DIR}/example.com-access.log combined
                SSLEngine on
                SSLCertificateFile      <certificate path>
                SSLCertificateKeyFile   <key path>
                <FilesMatch "\.(cgi|shtml|phtml|php)$">
                    SSLOptions +StdEnvVars
                </FilesMatch>
                <Directory /usr/lib/cgi-bin>
                    SSLOptions +StdEnvVars
                </Directory>
        </VirtualHost>
</IfModule>

Any ideas? I noticed the GET URL shown in the service log is HTTP rather than HTTPS, does that affect anything?


Solution

  • TL;DR: Restart kestrel service file & apache with:

    service apache2 restart
    service <kestrel service filename>.service restart 
    

    or

    systemctl restart apache2
    systemctl restart <kestrel service filename>.service restart
    

    I had the exact same problem. Here was my solution:

    If everything worked in development with the following code in Program.cs,

    public static IHostBuilder CreateHostBuilder(string[] args) =>
      Host.CreateDefaultBuilder(args)
         .ConfigureWebHostDefaults(webBuilder =>
         {
            webBuilder.UseStartup<Startup>();
         });
    

    Then I use the following for Kestrel on my Ubuntu instance:

    public static IHostBuilder CreateHostBuilder(string[] args) =>
      Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
           {
              webBuilder.UseKestrel()
                .UseContentRoot(Directory.GetCurrentDirectory())
                .UseUrls("http://*:5000")
                .UseStartup<Startup>();
           });