HTML served from Nginx does not display images - html

I am having an issue with Nginx configuration. I have enabled proxy_intercept_errors and created rewrite rules to display a particular HTML page from the server directory in case if one of the 404, 502, 503 error occurs. I have tested these error codes and they are intercepted correctly and the necessary HTML page with text is displayed. But the issue is that these images somehow are not displayed in my custom HTML page. Maybe there is something wrong with file paths or Nginx configuration.
HTML file location on the server:
/var/www/html/
Images location:
/var/www/html/images/
For these aforementioned directories I have set chmod 755, but for files chmod 644
Nginx settings:
server {
listen 443 ssl http2;
server_name example.net;
proxy_intercept_errors on;
root /var/www/html;
error_page 404 #404;
error_page 502 #502;
error_page 503 #503;
access_log /var/log/nginx/example.net.ssl.access.log;
error_log /var/log/nginx/example.net.ssl.error.log;
ssl_certificate /etc/letsencrypt/live/example.net/cert.pem;
ssl_certificate_key /etc/letsencrypt/live/example.net/privkey.pem;
location / {
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://localhost:8080;
}
location #404 {
rewrite ^(.*)$ /404.html break;
}
location #502 {
rewrite ^(.*)$ /502.html break;
}
location #503 {
rewrite ^(.*)$ /503.html break;
}
HTML file content:
<!DOCTYPE html>
<meta charset="UTF-8">
<html>
<title>404</title>
<style>
img {
display: block;
margin-left: auto;
margin-right: auto;
}
</style>
<body>
<img src="/var/www/html/images/404.jpg" alt="404 Not Found" style="width:50%;">
</body>
</html>
When I change location in Nginx directly to the image files, then they are served and displayed correctly. Problem with images not displaying only appears when html file is served.

You need to tell Nginx how to handle the /images/404.jpg URL. It does not know that it came from a previous error_page 404 exception. The request to the URL that caused the error_page 404 exception and the request to the URL for the image are essentially independent of each other.
Assuming that localhost:8080 never needs to see any URL that begins with /images/, just add a simple location block:
location /images/ {}
It will use the value of root defined in the outer block.
If localhost:8080 needs to see some URLs that begin with /images/, use a more specific rule:
location = /images/404.jpg {}
location = /images/502.jpg {}
location = /images/503.jpg {}

Related

HTML files are downloaded instead of rendered in browser using NGINX

My contact.html file is being downloaded rather than rendered in the browser when running my site on NGINX.home.html is working properly. This is how my default (in folder sites-available) file looks like:
server {
listen 90;
listen [::]:90;
server_name example.com;
root /home/myname/www;
location / {
try_files $uri /home.html;
add_header Access-Control-Allow-Origin *;
}
location = /contact {
default_type text/html;
alias /home/myname/www/contact.html;
}
}
When I add /contact to my url on my browser, contact.html gets downloaded as unknown file format. After having done an extensive search, these are the things I've tried:
Clear the browser cache (it also happens in Edge, so clearly this isn't the issue)
In nginx.conf I commented out the default_type application/octet-stream and un-commented default_type text/html
I have checked the in mime.types file the type text/html exists.
using try_files $uri /contact.html
Any help will be appreciated!
The issue was that default_type text/html property in nginx.conf lives in http {...} block. Since my server is listening to port 90 this configuration does not apply. once I changed the port to 80 the issue was resolved.

Preserve base URL when loading assets on proxied web page

I'm trying to host a site (called site1) nested within an existing domain (www.gateway.com).
e.g. Instead of www.site1.com/profile, it would be www.gateway.com/site1/profile.
I have an NGINX reverse proxy that detects the /site1/ path and proxies it to some upstream machines:
location ~/site1/(.*)$ {
proxy_pass http://upstreams/$1$is_args$args;
proxy_set_header Host $host;
}
The proxy itself is working fine - it redirects all the paths correctly. However, the site's assets (e.g. JS, CSS, etc.) do not preserve the base path (www.gateway.com/site1).
e.g. It is trying to load www.gateway.com/normalize.css, when the actual asset lives at www.gateway.com/site1/normalize.css.
For reference, the HTML for site1 is sourcing assets like so:
<link href="/normalize.css" rel="stylesheet" />
I've also tried removing the leading / in the href, but this results in the asset's path including the full route (less the last fragment) - also not what is desired.
Note that site1 works fine when hosted at the root of a domain (e.g. www.gateway.com/profile).
Any insights would be helpful. Thanks!
You might already have a block that checks for static fields that is messing up your asset delivery. To me what you are doing seems fine, but you have other nginx asset code possibly either on the upstream or site1 messit up. Add a block that checks for static files. If you are only doing this for one or two sites, this is reasonable.
The code below should work until you get us more info on other asset code.
location ~/site1/(.*)$ {
location ~* \.(?:js|css|jpg|jpeg|gif|png|ico|cur|svg)$ {
alias /location/of/site1;
expires 1M;
access_log off;
sendfile on;
sendfile_max_chunk 1m;
add_header Cache-Control public;
}
location ~* {
try_files $uri #nonStatic;
}
}
location #nonStatic {
proxy_pass http://upstreams/$1$is_args$args;
proxy_set_header Host $host;
}

nginx: location of static content within a subfolder

I'm trying to set up an nginx server to serve a React app at the address http://mydomain/memorygame
Currently I have the following nginx routing config:
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/mydomain.com;
index index.html;
server_name mydomain.com www.mydomain.com;
location /memorygame {
root /var/www/mydomain.com/memorygame;
try_files $uri /$uri $uri/ /index.html $uri/index.html =404;
location ~* \.(css|js)$ {
try_files $uri /$uri =404;
}
}
The css files are stored under /var/www/mydomain.com/memorygame, in the index.html the link is /static/css/main.d5dd0bd5.css.
The index.html load fine, but the css requests aren't routed to where I want them. If I take out "/index.html" from try_files, the css loads, but index.html doesn't. How can I make them both work at the same time?
(My guess is that part of the problem is that css request issued goes to mydomain.com/static/css/style.css instead of mydomain.com/memorygame/static/css/style.css, but I might be wrong. If I'm correct, is there a way to auto-prepend the /static/css/style.css to be relative to the mydomain.com/memorygame folder?)
Thanks in advance!
I figured it out myself. Deleting everything out of the location /memorygame block did the trick. Nginx does what I was trying to achieve by default.

nginx configure Front and Backend

I have a backend running at localhost:8080. And the path /runFuction executes a certain command.
Now I would like to use nginx as web server for my front end and only sent certain request to my backend.
My nginx config looks as follows
server {
listen 80;
server_name localhost;
location / {
root <path to site>;
index index.html index.htm;
}
location /api {
proxy_pass http://localhost:8080/;
}
}
In my index.html site I have a form that
...
<form action="api/runFuction" method="post" enctype="multipart/form-data">
....
<input type="submit" value="Do" />
</form>
I assumed that this would be possible but somehow I am missing something. How can I reach the backend path since I alway get a 404 page not there?
Could you try it?
location /api/ {
rewrite ^/api^/ /$1 break;
proxy_pass http://localhost:8080;
}

How can Nginx serve index.html while proxying POST requests using React Router's HistoryLocation

I cannot figure out how to have nginx to serve my static files with React Router's HistoryLocation configuration. The setups I've tried either prevent me from refreshing or accessing the url as a top location (with a 404 Cannot GET /...) or prevent me from submitting POST requests.
Here's my initial nginx setup (not including my mime.types file):
nginx.conf
# The maximum number of connections for Nginx is calculated by:
# max_clients = worker_processes * worker_connections
worker_processes auto;
# Process needs to run in foreground within container
daemon off;
events {
worker_connections 1024;
}
http {
# Hide nginx version information.
server_tokens off;
# Define the MIME types for files.
include /etc/nginx/mime.types;
# Update charset_types due to updated mime.types
charset_types
text/xml
text/plain
text/vnd.wap.wml
application/x-javascript
application/rss+xml
text/css
application/javascript
application/json;
# Speed up file transfers by using sendfile() to copy directly
# between descriptors rather than using read()/write().
sendfile on;
# Define upstream servers
upstream node-app {
ip_hash;
server 192.168.59.103:8000;
}
include sites-enabled/*;
}
default
server {
listen 80;
root /var/www/dist;
index index.html index.htm;
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires 1d;
}
location #proxy {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_http_version 1.1;
proxy_redirect off;
proxy_pass http://node-app;
proxy_cache_bypass $http_upgrade;
}
location / {
try_files $uri $uri/ #proxy;
}
}
All the functionality I'm expecting of nginx as a reverse proxy is there, except it gives me the aforementioned 404 Cannot GET. After poking around for solutions, I tried to add
if (!-e $request_filename){
rewrite ^(.*)$ /index.html break;
}
in the location / block. This allows me to refresh and directly access the routes as top locations, but now I can't submit PUT/POST requests, instead getting back a 405 method not allowed. I can see the requests are not being handled properly as the configuration I added now rewrites all my requests to /index.html, and that's where my API is receiving all the requests, but I don't know how to accomplish both being able to submit my PUT/POST requests to the right resource, as well as being able to refresh and access my routes using React Router's HistoryLocation.