Nginx alias still points to and loads from root directory - nginx

I have a django backend and react frontend.
I want to serve the react on / and use /admin, /api and /auth for Django. Here's what I have in my Nginx.
upstream backend {
server 127.0.0.1:8000;
}
server {
listen 80;
server_name x.x.x.x;
root /home/user/folder/frontend;
index index.html index.htm;
# for serving static
location /static {
alias /home/user/folder/backend/staticfiles;
}
# for serving react built files
location / {
try_files $uri $uri/ /index.html;
}
# for everything django
location ~^/(admin|api|auth) {
include snippets/proxyinfo.conf;
proxy_pass http://backend;
}
}
With the above, the expected behavior is
/ uses the default root folder, /home/user/folder/frontend and loads the built index files from react accordingly
/(admin|api|auth) points to django
/static loads static files saved in the /home/user/folder/backend/staticfiles folder.
So not sure why when I hit example.com/static/myfile.css, Nginx is going to /home/user/folder/frontend/static/myfile.css
I'd expect none of the above configuration says that's what it should do, so what magic is going on?
I thought this answer was self explanatory enough, yet Nginx keeps doing whatever it likes.
I'm using nginx/1.18.0 (if that matters)

Try adding root inside the location / directive too.
Like this:
upstream backend {
server 127.0.0.1:8000;
}
server {
listen 80;
server_name x.x.x.x;
root /home/user/folder/backend/staticfiles;
# for serving static
location /static {
alias /home/user/folder/backend/staticfiles;
}
# for serving react built files
location / {
root /home/user/folder/frontend;
try_files $uri $uri/ /index.html;
}
# for everything django
location ~^/(admin|api|auth) {
include snippets/proxyinfo.conf;
proxy_pass http://backend;
}
}
Also have a look at those QAs:
serve react frontend and php backend on same domain with nginx
Nginx -- static file serving confusion with root & alias
Deploy both django and react on cloud using nginx

from ngix documentation here, it seems you are missing a / at the end of your paths. this trailing / can cause a lot of pain in many languages to be the root cause of many errors.
please give it a try like this:
# for serving static
location /static/ {
alias /home/user/folder/backend/staticfiles/;
}

Related

How to route different webservers to different URL using nginx

creating a website for my self and need to host projects.
Basically, i hhave different projects with different framework. ie, Flask, Django, Node.JS and some html file projects. I would like to host them at projects.domain.com/<project name>
I tried to set server_name projects.domain.com/asdf but in error.log it says, server name "projects.domain.com/asdf" has suspicious symbols
Next up, i tried to nest location blocks (which i presume isn't how its supposed to be)
location /asdf {
location /static/ {
root blah blah;
}
location / {
..
proxy_pass http://localhost:3000 ;
}
}
But, this errors out saying location static is outside asdf
Some suggested to alias instead of root in the location /static/ block, but that doesnt work too.
Any help is appreciated :)
First of all a server_name can not contain URI segments. So a hostname or IP should be used as a value.
If you want to mix different local directories and proxy-locations a configuration could look like this.
Notice: Your location URI (/one, /two) will be appended to the root path.
The root directive can be used in every location block to set the document root.
http://nginx.org/en/docs/http/ngx_http_core_module.html#root
This is the reason why alias exists. With alias the location will not be part of the directory path. Check this out:
http://nginx.org/en/docs/http/ngx_http_core_module.html#alias
server {
server_name project.domain.com;
listen 80;
location / {
proxy_pass http://localhost:3000;
}
location /one/ {
alias/var/www/html/project1/;
index index.html;
}
location /two/ {
alias/var/www/html/project2/;
index index.html;
}
}

Nginx location not resolved

I am trying to have my nginx instance host from two separate static files.
The config for root path works but using any other prefix pattern gives 404 not found.
The config is as follows:
server {
listen 80;
server_name *.saurabhharwande.com;
root /var/www/certbot;
location /abc/ {
index vindex.html;
}
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
www.saurabhharwande.com Works
www.saurabhharwande.com/abc Gives 404
Am I missing something?
Edit: My basic understanding of how nginx configuration works was flawed. I thought that index file is searched in the root itself /<domain>/<root>/index.html and location is just used to point to different roots. It is rather searched at <domain>/<root>/<location>/index.html

nginx serving static files from root and uploaded files from alias

I run nginx as a reverse proxy server in front of apache.
I need to access uploaded files from frontend in backend so the way to go is to use an alias in nginx site config but static files in backend should be handled directly by nginx. I'm new to nginx so here is my partial config that handles static files. I also specified an alias (/images) but it will not work because it is overwritten by second condition.
How can the two conditions be combined so that nginx handles static files from root (backend app) and uploaded files from frontend app.
In apache config I included an alias for this problem and it works but without nginx in front.
Here is my partial nginx config:
server {
listen 80;
root /var/www/website/backend/www;
# Add index.php to the list if you are using PHP
index index.html index.php index.htm;
server_name admin.website.com www.admin.website.com;
location / {
proxy_pass http://localhost:8080;
include /etc/nginx/proxy_params;
}
#The alias to handle uploaded files(.jpeg, .pdf) from frontend
location /images {
alias /var/www/website/frontend/www/images;
}
#let nginx handle static files from root
location ~* \.(js|css|jpg|jpeg|gif|png|svg|ico|pdf|html|htm)$ {
expires 30d;
}
.
.
.
}
The regular expression location block takes precedence over a prefix location block (unless the ^~ modifier is used). See this document for details.
Try:
location ^~ /images {
root /var/www/website/frontend/www;
}
Note that the root directive is preferred in this case (see this document for details)

Serving static HTML files in Nginx without extension in url

root directory = /srv/myproject/xyz/main/
in the "main" folder I have few *.html files and I want all of them to point at a url say /test/ (which is quite different from the directory structure)
this is my very basic nginx configuration
server {
listen 80;
error_log /var/log/testc.error.log;
location /test/ {
root /srv/myproject/xyz/main/;
#alias /srv/myproject/xyz/main/;
default_type "text/html";
try_files $uri.html ;
}
}
If I use simple alias
location /test/ {
alias /srv/myproject/xyz/main/;
}
then its work perfectly, I mean I can access those html files by http://www.myurl.com/test/firstfile.html and so on
but I dont want that html extension.
I tried to follow these threads but no success
http://forum.nginx.org/read.php?11,201491,201494
How to remove both .php and .html extensions from url using NGINX?
how to serve html files in nginx without showing the extension in this alias setup
Try this
location ~ ^/test/(.*)$ {
alias /srv/myproject/xyz/main/;
try_files $1.html =404;
}

nginx - Serve file conditionally without redirection

I'm currently building a multi-domain cms in rails. Since this content is the same until the next change I'd like to do caching via static files.
The public directory with some cached pages of foo.com and baz.com (/ and /asdf in both cases):
public/
assets/
cms.css
sites/
foo.com/
assets/
screen-some-hash.min.css
index.html
asdf/
index.html
baz.com/
assets/
screen-some-hash.min.css
index.html
asdf/
index.html
What I want to do is the following:
redirect www to non-www (works)
If the requests contains a subdomain (cms, admin, whatever):
If the path contains /assets serve the file in public/assets and set the expire stuff to 30d or so. No problem here since /assets = public/assets and public/ is the passenger root.
Everything else: handle it via rails, no special caching or anything required.
For all other requests (meaning no subdomain):
If the path contains /assets serve the file in public/sites/$host$request_uri and set the expire stuff to 30d or so. Everything else: check for public/sites/$host$request_uri or fall back to the rails app.
I have never worked with nginx conditionals other than the www/non-www redirects and don't really know what I have to do for the conditions mentioned above. If at all possible, I don't want to use redirects for the cached stuff (ie redirection to /sites/foo.com/asdf), instead I'd like to have nginx serve this file directly when going to http://foo.com/asdf.
Further: I don't want to hardcode the hostnames as I'd like to handle an unknown amount of domains. I also don't want to use more than a single rails application for this.
Got something that works, not 100% but good enough for now.
server {
listen 80;
server_name *IP*;
if ($host ~* www\.(.*)) {
set $host_without_www $1;
rewrite ^(.*)$ http://$host_without_www$1 permanent;
}
location ~ ^/(assets)/ {
try_files /sites/$host$uri $uri #passenger;
root /home/cms/app/current/public;
gzip_static on;
expires max;
add_header Cache-Control public;
}
location / {
try_files /sites/$host$uri/index.html /sites/$host$uri $uri #passenger;
root /home/cms/app/current/public;
}
location #passenger {
access_log /home/cms/app/shared/log/access.log;
error_log /home/cms/app/shared/log/error.log;
root /home/cms/app/current/public;
passenger_enabled on;
}
}
For subdomains, this should do the trick:
server {
server_name ~^(?<subdomain>.+)\.example\.com$;
access_log /var/log/nginx/$subdomain/access.log;
location /assets {
expires max;
}
location / {
proxy_pass http://your_rails_app;
}
}
Not really sure about the proxy_pass setting as my only experience with Ruby apps is Gitlab, which I'm running this way. I hope this helps at least a little.
server {
server_name example.com;
location /assets {
root /public/sites/$hostname/$request_uri;
expires max;
}
}
You'll have to add your own settings and play with it a little as I don't have a chance to actually test it now. But it should show you the way.

Resources