Luminus behind nginx

#1

So I am testing deploying a luminus app behind nginx.

In my testing I am redirecting based on the location /udt

However when I go to server/udt I can see the page but the style sheet is not loading and on top of that going to any route under the home route breaks. Basically luminus does not understand the base url. I have tried setting the app_context env var in the systemd script but that seems to have done nothing. Nor can I come up with rewrite. Is there a way to alter the base url a luminus uberjar understands?

Ken

#2

Hard to say from the info you’ve given but have you referring to the style sheet using an absolute url?

#3

It is more about all relative paths are pointing to /route instead of considering the base url. The stylesheet is really just one part of that.

Example server.org/udt/ works fine
but if I click on the about route it goes to:
server.org/about when it should go to server.org/udt/about

I am not convinced it is luminus vs nginx, the ip is getting messed up from the request

#4

So I think I found the answer. It is the context-path for ring http server. I will investigate more Monday into sorting things out.

#5

The fact that you’re using Luminus is mostly orthogonal to your server situation. I’m guessing you are trying to deploy using java -jar? Yes, I’ve had lots of trouble working off of sub-paths, too. Simple solutions would be nice.

#6

Yes that is the case, deploying the jar for now. I think deployed as a war in tomcat the solution is simpler. I have to test what I found on Monday when I get back to work, but if it is the correct solution I am going to make an end config file that will allow users to set sub path and port. I think that will make things easier for my target user base.

#7

That’s the work around I’ve had; since I build SPAs, if I’m going to be at a sub-directory I have the back-end provide a javascript “context” var to the generated pages, which can be used to construct the right links. This was another of those, “It works in dev… why not in prod?” issues I had. Mostly, though, I just use subdomain instead of subdirectory so I can avoid the problem. Easy fix if that’s a possibility in your situation.

#8

So I thought I had it, but well no:

I am setting the handler-path based on an ini value I can see the web context, etc.

Nginx is redirecting to the location, but no permutation of root-url=/path or path or path/ or /path/ works. Only / works and then I have to have nginx listen on port 8080 to test that out. I have tried with and without url rewrite in nginx

#9

I don’t know if this will help, but here’s the way one of my old Luminus apps obtains the context from the java applet:

;; myapp.layout
(declare ^:dynamic *app-context*)
;; app-context will get inserted as a js var into the page served

;; myapp.middleware
(defn wrap-context [handler]
  (fn [request]
    (binding [*app-context*
              (if-let [context (:servlet-context request)]
                (try (.getContextPath ^ServletContext context)
                     (catch IllegalArgumentException _ context))
                (:app-context env))]
      (handler request))))

(defn wrap-base [handler]
  (-> handler
  ;; ... all the middleware
   wrap-context
   ;; one more...
   ))
#10

So you did it in the wrap context. I did something like this:

indent preformatted text by 4 spaces
(mount/defstate http-server
    :start
    (http/start
      (-> env
        (assoc :handler (handler/app))
        (update :port #(or (-> env :options :port) %))
        (update :handler-path #(or (-> env :my-path) %))))
    :stop
    (http/stop http-server))

Based on this link:
http://www.luminusweb.net/docs/servers.html

1 Like
#11

Oh, cool! That wasn’t an option when I started using Luminus. Must have snuck in while I wasn’t looking.

#12

Unfortunately it is still not working though. I still feel like I am missing something stupid but I have no idea what and am running out of ideas.

#13

From your original problem description, it seems to me like there might be a <base href="...“> missing in your HTML output. It‘ll make all relative links/href/src URLs absolute, so a stylesheet with href="foo.css" will be prepended with the base URL.

That way, you also don‘t need to send a path to your script and manually construct URLs, as it can easily be done server-side (adding the base tag, that is).

2 Likes
#14

whoa… for real? I’ve never heard of this! TIL! https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base

1 Like
#15

Yes, you can even set a target! But take note of

If this attribute is specified, this element must come before any other elements with attributes whose values are URLs.

Also thanks, should’ve included the link in my comment.

#16

AS a mention, first of all thank you for all the help. I am not done sorting this out but have sorted some things out and figured out the direction I need to take.

The real problems are around 2 things:

  1. NGINX config is important, particularly how the location and the redirect are defined, particularly with regards to a trailing back slash. NGINX will use that as part of an auto url rewrite and I wasn’t paying attention at my first go at setting that up.

  2. I was looking for some pre-canned global place to do this. Like I was in rails or django. But luminus is a sane set of libraries and there are cases where if I want some central place to define things I need to define them. And that was me just not practicing the concepts correctly.

On a side note I am finding some interesting things with compile order of a luminus app in lein. Where things in handler and layout get evaluated before the core of the app. But I am dealing with that.

Ken