I have some trouble getting Thymeleaf to form relative URL's correctly when it is used on a server behind a reverse proxy (nginx in my case).
Let's say I have the following location in nginx:
location /app {
proxy_pass http://10.0.0.0:8080;
}
I have the following Thymeleaf 3 page (index.html
):
<html xmlns:th="http://www.thymeleaf.org">
<head>
<link rel="stylesheet" th:href="@{/css/some.css}" />
</head>
<body>
Hello world!
</body>
</html>
The server used is an embedded Tomcat server (Spring boot), running at context /
.
When I send a request to http://example.com/app
, then I get the index.html
page as response. The css cannot be retrieved however, because when the URL is constructed in the Thymleaf template, it uses the context path of the tomcat server, which is /
. The constructed url in the index.html
looks as follows:
http://example.com/css/some.css
This obviously results in a 404 not found. The URL needs to be formed as follows:
http://example.com/app/css/some.css
What do I need to configure to let Thymeleaf form the URL as http://example.com/app/css/some.css
? I would rather not hardcode the base URL anywhere for certain profiles or something like that. I think I need to add something to the nginx configuration, but I'm not sure what exactly.
Correct solution is to inform springboot application that it is being behind proxy.
Try to extend nginx config to something like this:
location /app {
proxy_pass http://10.0.0.0:8080;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host:$server_port;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Prefix /app;
}
To learn about using Forwarded header (standard for a few years), have a look at https://www.nginx.com/resources/wiki/start/topics/examples/forwarded/ There are a bit mismatch in spring documentation for this topic and you can have a look at some issues/project to gain more info:
PS: If you are testing your springboot app configuration, it can come handy to do it locally with cURL, without need to use nginx. To simulate request headers like comming from proxy, you can use this command:
curl -i http://localhost:8080 \
-H 'X-Forwarded-Host: example.com' \
-H 'X-Forwarded-Port: 443' \
-H 'X-Forwarded-prefix: /myDevelApp' \
-H 'X-Forwarded-proto: https'
Or using standardized header:
curl -i http://localhost:8080 \
-H 'X-Forwarded-prefix: /myDevelApp' \
-H 'Forwarded: for=123.333.333.333;host=example.com;proto=https'
Ended up matching the context of the Tomcat server to the desired Nginx location. According to above example, the context would be set to '/app'.
Edit:
I set the application context property in the application.yml
:
server:
servlet:
contextPath: /app
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With