Deploying React js build directory in nginx using kubernetes - javascript

Deploy React js(build directory) static files in Nginx server.
Using kubernetes, i am running the nginx server to serve the React js "build" directory for static files. I could access the simple index.html in the browser. But not the index.html with react js code. The root directory has the index.html file, static directory and other files in it. Directory structure is copied to this path.
nginx.conf is like below
events {
worker_connections 1024;
}
http {
server {
listen 80;
root /usr/share/nginx/html;
#index index.html;
location / {
index index.html;
try_files $uri $uri/index.html /index.html;
}
location /static/ {
autoindex on;
root /usr/share/nginx/html/static/;
}
}
}
In the browser, index.html is not loaded, but in source (right-click in the browser > select source), the index.html code is available. formatted index.html file copied from source in the browser is at this path. I am predicting that javascript(css,js) code is not executed or having issues loading in the browser. Otherwise, there is a problem with the nginx configuration to load the javascript files.
how to properly configure nginx to deploy Reactjs build directory files?

try_files does not tell nginx to serve the static file. Reaching the closing brace in the absence of any other operation causes it to serve the static file. try_files tests for the existence of the file in the local file system and may rewrite the URL.
You have syntax errors in your file i.a white spaces.
Remember to create service for nginx - type LoadBalancer and refer to it in deployment configuration file. You have to add your server if there are several servers that match the IP address and port of the request.
Here is example how you should execute this process. Make sure you followed every step from tutorial: nginx-configuration - there is example of exercise on PHP application but there are the same steps to reproduce with ReactJS app.
Your conf file should looks like this:
events {
worker_connections 1024;
}
http {
server {
listen 80;
root /usr/share/nginx/html;
index index.html index.htm;
server_name your_server_name_or_IP
location / {
try_files $uri $uri/index.html /index.html;
}
location /static/ {
autoindex on;
root /usr/share/nginx/html/static/;
}
}
}

The below code that works for me.
server {
listen 80;
root /usr/share/nginx/html;
index index.html index.htm;
server_name xyz.application.com;
server_name localhost;
location / {
ssi on;
set $inc $request_uri;
if (!-f $request_filename) {
rewrite ^ /index.html last;
}
index index.html;
try_files $uri $uri/index.html /index.html =404;
}
Setting the rewrite redirects to index.html page. I am not sure about the impact of ssi, set $inc $request_uri in the code.

Related

Rendering JavaScript & CSS files using Nginx in Angular app

I'm deploying an Angular application in a Docker container on AWS using ECS Fargate. The Angular application is being served up using nginx. I'm running into an issue where the application is routing all files back to the index.html file. This is preventing all the javascript & css files to load properly. Below is the nginx.conf that is being used in the container. Nginx is new territory for me, and I'm having some trouble getting the configuration file correct for the JS & CSS files. Initially, I was under the impression all files were rendering the index.html file because of the line try_files $uri $uri/ /index.html;
I have changed that line to be try_files $uri /index.html; but am still having the JS files render back to index.html.
Any advice to get the other static files to render would be appreciated.
nginx.conf
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log debug;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
server {
location /app {
try_files $uri /index.html;
include /etc/nginx/mime.types;
}
}
default_type application/octet-stream;
root /usr/share/nginx/html;
index /index.html;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" $request_time';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
client_max_body_size 10m;
include /etc/nginx/conf.d/*.conf;
}

NginX location management with Django&Vue.js setup

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/ {}
}

Return 404 for invalid routes via nginx

I am using nginx with react.
My nginx.conf file
server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html =404;
}
}
As per this config nginx is serving 200 for all routes..
Suppose my routes are
example.com/login
example.com/landing
Now suppose someone enter wrong url
example.com/test
In that case i want to throw 404 without landing to application at nginx level itself. Is this possible to handle routing at nginx level and send 404 despite of 200 and than handling at react level.
I found that to restrict any particular route at nginx level we can do it using below code
location ^~ /test/ {
return 404
}
But i want to restrict all routes which are invalid for that i used
# return 404 for all routes
location / {
return 404;
}
# define each possible route like this
location /login {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html =404;
}
location /landing {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html =404;
}
But after this my application is not loading getting 503 Service Temporarily Unavailable
First question is it really possible to achieve routing at nginx level if yes what approach i need to take any clue or reference will be of great help.
Thanks in advance
EDIT
Please find docker file
# Base Image
FROM node:10-alpine AS base
MAINTAINER test#test.com
RUN mkdir -p /usr/src/app
COPY . /usr/src/app
# Dependencies
FROM base as build
WORKDIR "/usr/src/app"
RUN npm install
RUN npm run test
RUN npm run build
# Web Server
FROM nginx:alpine
EXPOSE 80
COPY --from=build /usr/src/app/build /usr/share/nginx/html
COPY --from=build /usr/src/app/nginx.conf /etc/nginx/conf.d/default.conf
Yes, nginx can be used for this.
COPY --from=build /usr/src/app/nginx.conf /etc/nginx/nginx.conf
Just use this one.

Laravel 5.4 Served in subdirectory Nginx. 404 when including js files

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.

Change NGINX configuration to look for relative paths

I was wondering how I could get NGINX to look for files that are essentially out of the root value. This is how my nginx.conf looks like within server
server {
listen 80;
server_name localhost;
root /home/parallels/Downloads/nginx/rickshaw/examples;
location /all {
alias /home/parallels/Downloads/nginx/rickshaw/examples
try_files $uri $uri/ /sample.html /sample.htm;
}
#error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
I have a HTML file in rickshaw/examples that is calling on a javascript file that is located in /home/parallels/Downloads/nginx/rickshaw/javascript/charts.js by going like src="../javascript/charts.js. I tried using alias but that didn't really help. Any idea on how I could change the configuration file so that it can pick up on a file in a different relative directory. I know I could just copy the file into the root path but I want to find out how I can configure NGINX so that it looks for relative paths.
Thank you, and let me know if you need any further information!
try adding a static path
location /javascript/ {
alias /home/parallels/Downloads/nginx/rickshaw/javascript/;
autoindex off;
}
and access it src="/javascript/charts.js"

Categories