Problem with several static sources


(Alwx) #1

I have an SPA with django as API backend.
My problem is that i have 3 different sources of static files with following structure and I build them from different docker volumes which I can’t properly combine in one folder.

tree /var/www/django/
/var/www/django/
├── dist
│   ├── index.html
│   ├── main.406ac75403562d145b5f.js
│   ├── styles.194bf91866fc202ae066.css
├── media
│   ├── events
│   │   └── 1
│   │       └── 01.png
│   └── tournaments
│       └── 1
│           └── 01.png
└── static
    ├── admin
    │   ├── css
    │   │   └── autocomplete.781713f30664.css
    │   └── js
    │       ├── urlify.js
    │       └── vendor
    │           └── jquery
    │               └── jquery.min.js
    └── staticfiles.json

I need to serve files from /static, /media and /dist folders.
I tried:

  • Set root to parent folder /var/www/django, proxy all requests to django and rewrite domain access to dist/index.html. Doesn’t work because seems that caddy (or my mistake somewhere) redirected.
  tls {$EMAIL}
  header / Strict-Transport-Security "max-age=31536000;"

  root /var/www/django
  
  rewrite {
    if {path} is /
    to /var/www/django/dist/index.html
  }

  proxy / web:8000 {
    except /static /media /dist
  }

}
  • Proxy only api and admin requests to django, set parent root to /dist folder and rewrite /static and /media requests. Do not understand why does’n work. In caddy logs there is line - "GET /static/admin/css/base.a419cbad388f.css HTTP/1.1" 404
    But in browser there is a problem with MIME type - Refused to apply style from 'https://{DOMAIN_NAME}/static/admin/css/base.a419cbad388f.css' because its MIME type ('text/plain') is not a supported stylesheet MIME type, and strict MIME checking is enabled.
{$DOMAIN_NAME} {
  tls {$EMAIL}

  root /var/www/django/dist

  mime .css text/css  # this line does not help also

  #rewrite {  either this
  #  if {path} starts_with /static
  #  if {path} starts_with /media
  #  to /var/www/django{path}
  #}

  # or this two blocks
  rewrite /static {
    r (.*)
    to /var/www/django/static/{1}
  }

  rewrite /media {
    r (.*)
    to /var/www/django/media/{1}
  }

  proxy /api web:8000 {
    transparent
  }

  proxy /admin web:8000 {
    transparent
  }

}

In the end, I can’t figure out how to serve this properly.


(Matthew Fay) #2

This means Caddy can’t find the file. I’ll explain why in a moment, but it’s also what’s causing this:

When Caddy gives a 404, it also returns, via the response body, the message: 404 Not Found. This is sent as plain text, hence the browser error.

This part doesn’t work like you expect it to. When you rewrite, you’re not selecting the file on disk, you’re altering the effective URI of the request. With the above rewrite, you’re essentially telling Caddy: “Pretend the client requested example.com/var/www/django/dist/index.html instead”.

By rewriting in this way, you’re gonna run into two problems - the second you haven’t actually encountered yet, but I’ll also explain that in a minute. Caddy takes the web root, appends the URI path, and looks for a file there. There’s likely no file at /var/www/django/var/www/django/dist/index.html, hence the 404.

The second issue you’re going to find, when you change the rewrite to just /dist/index.html to fix the 404s, is that the canonical method of requesting an index is actually to request the directory itself. Caddy will enforce this, so when the client requests /, and you rewrite it to /dist/index.html, Caddy will redirect the client to /dist/ and you’ve got yourself a landing page redirect.

TL;DR: Change your rewrite to /dist/.


(Alwx) #3

Well, that wasn’t obvious for me.
Thanks, now it works.