I have a project with the following folder structure
public
js
assets
index.html
event-public
js
assets
index.html
admin-public
assets
index.html
Each folder has its own set of unique assets (css, images, etc) and their own home page. I've set up my NGINX server to serve all of them from the same address (and proxying to a node server, which works fine).
server {
location /api/ {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_pass http://127.0.0.1:8000/;
}
location / {
root /home/ubuntu/project/public;
autoindex on;
try_files $uri $uri/ =404;
# any additional configuration for non-static content
}
location /event {
alias /home/ubuntu/project/event-public;
autoindex on;
try_files $uri $uri/ =404;
# any additional configuration for non-static content
}
location /admin {
alias /home/ubuntu/project/admin-public;
try_files $uri $uri/ =404;
# any additional configuration for non-static content
}
}
the public (home website) with the location / is served just fine, and the admin site works too since the most of the JS is in the same directory as the index folder. However, when I try to go to the events page the index.html is able to load just fine, but everything contained in the assets returns a 404. Looking at the console, I see the scripts embedded in index.html are trying to request the server root/whatever (ex. https://localhost/js/angular.min.js). my script tags in the event index.html look like this:
<script src="js/angular.min.js"></script>
I understand that I could just change this to event/js/angular.min.js, but is there a way to configure NGINX to recognize these paths relative to their location in the folder? I run this on my localhost and it works fine, but for deploying on the server I would rather not have to change these script tags every time.
Related
I have a Django backend and Vue.js frontend served by the same machine. I want a specific path to be directed to the django API and admin panel, while the rest should load Vue index.html and be passed to Vue router. My problem is, that while the base path is passed on to Vue.js, and my selected path does go through to Django, any other path results in 404, which means that if I want to revisit a path generated though Vue router, it's impossible to do so.
I figured the problem must be somewhere in the NginX config file:
# the upstream component nginx needs to connect to
upstream myproject {
server unix:///tmp/myproject .sock;
}
server {
listen 80;
listen [::]:80;
server_name serverurl.com;
return 301 https://serverurl.com$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
ssl_certificate /home/projects/myproject/ssl/ANY.serverurl.com.crt;
ssl_certificate_key /home/projects/myproject/ssl/ANY.serverurl.com.key;
server_name serverurl.com www.serverurl.com;
access_log /home/projects/myproject/logs/nginx_access.log;
error_log /home/projects/myproject/logs/nginx_error.log;
location / {
root /home/projects/insights/vue/dist;
try_files $uri $uri/ /home/projects/myproject/vue/dist/index.html =404;
}
location /backend/ {
include /etc/nginx/uwsgi_params;
uwsgi_pass myproject;
}
location /static/ {
alias /home/projects/myproject/static/;
}
location /media/ {
alias /home/projects/myproject/media/;
}
}
So the "/" path results in correctly rendering Vue index.html
And "/backend/" correctly loads django urls
But, for example, if the user tries to access "/" and is not logged in, he will be redirected to "/login" by Vue router, which works fine and the login page works correctly, and the user is redirected back to "/". But, if the user tries to access "/login" directly, or any other route such as "/options", "/profile", etc..
I have tried to use some kind of regex, but could not figure it out unfortunately, and resulted in an infinite redirect to "/index.html/index.html..." until the browser blocked the redirect.
Here is my attempt: I added this location to the end of config:
location ~* ^/(.*) {
index /home/projects/myproject/vue/dist/index.html;
}
Lets look at your try_files directive:
try_files $uri $uri/ /home/projects/myproject/vue/dist/index.html =404;
So what happened here when your user tries to access the /login URI directly?
nginx processed first try_files parameter $uri (which is equals to /login), tries to check the /home/projects/insights/vue/dist/login file existence and fails;
nginx processed second try_files parameter $uri/, tries to check the /home/projects/insights/vue/dist/login/ directory existence and fails;
nginx processed third try_files parameter /home/projects/myproject/vue/dist/index.html, tries to check the /home/projects/insights/vue/dist/home/projects/myproject/vue/dist/index.html file existence and fails;
nginx returns HTTP 404 Not Found code.
As it stated by the documentation, last parameter of the try_files directive can be
a new URI;
HTTP error code: =code;
named location ID: #location_name.
You need to process all requests for the non-existed files with your Vue app index.html file, so change your try_files directive to use /index.html as new URI if all other checks fails:
try_files $uri $uri/ /index.html;
(and I'm not sure you need that $uri/ part at all, maybe just try_files $uri /index.html; would be enough).
Additionally, I recommend you to use root /home/projects/myproject instead of alias /home/projects/myproject/static/ and alias /home/projects/myproject/media/ directives. As it said by the alias directive documentation:
When location matches the last part of the directive’s value:
location /images/ {
alias /data/w3/images/;
}
it is better to use the root directive instead:
location /images/ {
root /data/w3;
}
That way you can simplify your configuration to
server {
listen 443 ssl;
listen [::]:443 ssl;
ssl_certificate /home/projects/myproject/ssl/ANY.serverurl.com.crt;
ssl_certificate_key /home/projects/myproject/ssl/ANY.serverurl.com.key;
server_name serverurl.com www.serverurl.com;
access_log /home/projects/myproject/logs/nginx_access.log;
error_log /home/projects/myproject/logs/nginx_error.log;
root /home/projects/myproject;
location / {
root /home/projects/insights/vue/dist;
try_files $uri /index.html;
}
location /backend/ {
include /etc/nginx/uwsgi_params;
uwsgi_pass myproject;
}
location /static/ {}
location /media/ {}
}
I want all traffic going to my web server to be redirected to https on Nginx. However, when I go to my website at http://www.example.com, I get the error "414 Request-URI Too Large" and the URL is ridiculously long -- http://www.example.com/http:://www.example.com/http:: -- and it goes on for a while, which I am assuming is what is giving me this error. But I don't know how to fix this redirection error because my config file for Nginx doesn't contain a $request_uri parameter.
Here's the Nginx config file:
server {
server_name example.com;
return 301 https://www.example.com;
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}
server {
root /var/www/html;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name www.example.com;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
proxy_pass http://localhost:8080; #whatever port your app runs on
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
server {
if ($host = www.example.com) {
return 301 https://www.example.com;
}
if ($host = example.com) {
return 301 https://www.example.com;
}
listen 80 default_server;
server_name example.com www.example.com;
return 404;
}
Any help would be greatly appreciated!
I fix this issue with :
Open your nginx.conf file /etc/nginx/conf.d/nginx.conf
Add this code inside http
fastcgi_buffers 8 16k;
fastcgi_buffer_size 32k;
client_max_body_size 24M;
client_body_buffer_size 128k;
client_header_buffer_size 5120k;
large_client_header_buffers 16 5120k;
Reload your nginx with service nginx reload
I know this is an old question but for anyone looking for a solution, clearing cache & cookies from my browser was the working method.
Open Chrome, at the top right, click the three vertical dots icon.
Click More tools and then Clear browsing data.
At the top, choose a time range. (For me I deleted for the last hour)
Click Clear data.
Source
My problem is serving CSS and JS files using Laravel 5.4 on an Nginx server (Ubuntu). I have configured the server to serve the application from a nested sub-directory (not in the root of the web server). Routing is working. See:
https://zwestwind.com/sandboxes/zypth/blog/tasks
https://zwestwind.com/sandboxes/zypth/blog/posts
and just ..blog/ as well.
The problem is that I cannot include JS files (and likely css). The JS file is in "blog/public/js/posts.js".
Attached below is my site configuration, and the code to include a JS file in a blade template. You can view the error in the console when you hit the site.
Server Configuration:
server {
return 404;
}
server {
listen 80;
listen [::]:80 ipv6only=on;
listen 443 ssl;
root /var/www/zwestwind.com/html;
index index.php index.html index.htm;
# Make site accessible from http://localhost/
#server_name example.com www.example.com;
server_name zwestwind.com www.zwestwind.com;
ssl on;
ssl_certificate /etc/nginx/ssl/pub_clf_origin.pem;
ssl_certificate_key /etc/nginx/ssl/priv_clf_origin.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
ssl_prefer_server_ciphers on;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
# Uncomment to enable naxsi on this location
# include /etc/nginx/naxsi.rules
}
# route to laravel project: $uri = /sandboxes/zypth/blog/public/index.php
location ~ ^/sandboxes/zypth/blog {
alias /var/www/zwestwind.com/html/sandboxes/zypth/blog/public;
try_files $uri $uri/ #laravel;
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
#fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME /var/www/zwestwind.com/html/sandboxes/zypth/blog/public/index.php;
}
}
location #laravel{
rewrite /sandboxes/zypth/blog/(.*)$ /sandboxes/zypth/blog/index.php?/$1 last;
}
# Only for nginx-naxsi used with nginx-naxsi-ui : process denied requests
#location /RequestDenied {
# proxy_pass http://127.0.0.1:8080;
#}
error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
# With php5-cgi alone:
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
Blade code to include the JS file:
<script src="{{ URL::asset('posts.js', true) }}"></script>
Things that I have tried:
I have tried using 'js/posts.js' and many other variations, including hardcoded paths such as 'zwestwind.com/sandboxes/zypth/blog/public/posts.js' to no avail (with the protocol, I can only post 2 links due to reputation).
Adding a location block: location ~ .js$ {...} to add a content-header of application/x-javascript
I have configured a vhost server to serve the same application at (http)blog.zwestind.com/posts. All routing and inclusion of CSS/JS files works there, check it out. The server config for that sub domain is exactly as specified in the Laravel installation guide.
I am guessing this issue stems from a server config problem with the primary domain... ie) the location block listening for "^/sandboxes/zypth/blog" is catching the request for the JS file and modifying the URI, thus resulting in a 404. How would I fix this?
When the script works, it will say "posts.js is ready!" in the console (see the sub domain on http for an example).
Thanks.
P.S. If anyone is curious as to WHY I want to serve this app (and more) in a nested directory, it is because I want to host live demo apps using ONE SSL cert via ONE domain while also learning how to configure web servers. This server is not intended for heavy traffic.
Try including the file like this:
<script src="/js/posts.js"></script>
The "/" before the directory sends the request to the root (public folder), where the js and css directories are.
I found this better then adding new location root or aliases in the nginx config.
I do the same with images and it works fine.
Nginx appears to only be loading the first 72kbs of my javascript files. I've searched all around my nginx config files and cannot see this setting anywhere. I've added things like
location / {
...
proxy_max_temp_file_size 1m;
...
}
and
location / {
...
sendfile on;
sendfile_max_chunk 1m;
...
}
But still I'm unable to overwrite this weird setting that is only allowing first part of the file to load.
The connection uses nginx proxy_pass to foward port 80 to kibanas port '5601'. I feel like there could be a setting that limits file transfer over proxy? Just not sure where to find it.
proxypass connection looks like:
server {
listen 80;
server_name logs.mydomain.com;
auth_basic "Restricted Access";
auth_basic_user_file /etc/nginx/htpasswd.users;
location / {
proxy_pass http://localhost:5601;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
And my default nginx settings is posted here:
http://www.heypasteit.com/clip/OEKIR
Would appear when disk space is low NGINX defaults to minimal safe settings.
When I checked the VMs health I noticed that the disk drive was full. Elasticsearch was logging a couple of GBs worth of text in to error logs each day. I still Have not fully identified why elastic search is flooding the error logs.
But I think excessive disk space usage has contributed to this error. Nginx could be detecting this and switching over to minimal safe configuration which would only allow 72kbs of data to be served per file.
Once I cleared out the excessive logs, Nginx began serving the full JS files again without needing to restart nginx or kibana.
Good day, i want handle php file and html on same server, i want that html files handle node on port 8080, and php files handle php5 service. I wrote nginx config like this:
server {
listen 80 default_server;
root /home/examle/public_html;
index index.php index.html index.htm;
server_name www.examle.com examle.com;
location ~ \.html$ {
proxy_pass http://localhost:8080;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
}
location / {
try_files $uri $uri/ =404;
}
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
but when html pages opened nodejs didn't handle node javascript which contains in html page. How can i handle both type of files php and html on same server?
It won't work this way.
The thing is: when you use nginx+php, nginx doesn't really run php filename.php when you hit localhost/filename.php. There is php-fpm and nginx sends request to it. Then, php-fpm runs actual script, creating proper $_SERVER, $_GET, etc.
In node case, you don't have any node-fpm service. Nginx won't run node filename.html. You need to set up the real node process at 8080 port that serves http connections, because all nginx does is it "passes" an actual http connection to the http://localhost:8080, as you specified.
Learn how to get node http server working.
P.S. Clue: look at your nginx logs more often (/var/log/nginx/* at Ubuntu/Debian). :)