Carlo
Carlo

Reputation: 4148

Serving static website in nginx, wrong path for static files

I'm trying to use nginx to serve a static website that was given to me. Its folder structure is like this:

static_website/
    index.html
    www.example.com/
    resources.example.com/
    uploads.example.com/

The index.html file in the root is the one generated by httrack and it simply contains a redirect to www.example.com/index.html. Inside the folder www.example.com are all the html files, in the other two folders are the css, javascript and image files.

Here is the nginx configuration:

server {
    index index.php index.html index.htm;

    server_name example.com;

    location / {
        root /var/www/static_website/www.example.com;
        try_files $uri $uri/ =404;
        index index.html;
    }

}

I can navigate through the pages, but the css, javascript and image files are not loaded. The path to one of the css files inside the html is like this:

href="../resources.example.com/style.css"

The only way I managed to get this working was to have the have the url like this:

example.com/www.example.com/

This way, all the path are correct. I'd like to avoid this and have simply example.com. Is there a way to do this?

Upvotes: 3

Views: 2298

Answers (2)

random-forest-cat
random-forest-cat

Reputation: 35884

I want to share my experience with this problem for others encountering similar issues as the solution was not so obvious to me

My setup and problem in particular had to do with cloudlflare settings which i was using to leverage TLS instead of handling it on the origin server for one of my 2 sites. if you are serving your site from a CDN that supports encryption and you use nginx on your origin consider the following setup:

# static1.conf
{ server_name static1.com; root: /var/www/static1/public; listen 80; listen 443; }

# static2.conf - no tls setup in nginx, figured id let cloudflare handle it
{ server_name static2.com; root: /var/www/static2/public; listen 80; }

static1 was setup at the origin with letsencrypt to handle tls connections

static2 was setup at the origin without any tls configuration

from left to right, here are the appropriate cloudlfare TLS modes which allowed me to access the correct files thru nginx

enter image description here

The distinction between full and flexible is that full mode lets the origin handle the certificate.

Initially I had the static2 site misconfigured as full, which lacked a listen directive for 443 causing nginx to serve static1 instead.

I realize the original question has nothing to do with cdn's or cloudflare but this scheme / protocol mismatch cost me a few hours and I am hoping to save someone else from similar grief

Honestly I am surprised nginx doesn't stick to matching on server_name and that oit implicitly matches on scheme as a fallback (or atleast appears to), even without a default_server specified - and without any meaningful messages in the logs to boot! Debugging nginx is a nightmare sometimes.

Upvotes: 0

Richard Smith
Richard Smith

Reputation: 49672

It looks like the site was originally intended to operate with ugly URLs like //example.com/www.example.com/.

But the path-relative URIs for the resources should work just fine relative to /, you just need to provide a location block which matches /resources.example.com/.

For example:

location / {
    root /var/www/static_website/www.example.com;
    try_files $uri $uri/ =404;
    index index.html;
}
location /resources.example.com/ {
    root /var/www/static_website;
}

I originally commented that you should try this:

location ~ \.(css|js|jpg|png|svg)$ { 
    root /var/www/static_website;
}

Which achieves a similar goal, but Nginx will process prefix locations more efficiently that regular expression locations.

Upvotes: 1

Related Questions