I'm writing an AngularJS single page application using nginx.
I just switched from apache to nginx, but I cant make my config file working.
I'm trying to rewrite everything to index.html to let Angular do the routing.
My nginx.conf is as follow:
server {
index index.html;
location / {
expires -1;
add_header Pragma "no-cache";
add_header Cache-Control "no-store, no-cache, must-revalidate, post-check=0, pre-check=0";
try_files $uri $uri/ /index.html;
}
}
Is it possible to have my nginx.conf file in the project root like my .htaccess did?
You dont want nginx.conf in the project root and its not necessary. Also, you don't want direct changes to nginx.conf, you will instead want specific files for different websites in /etc/nginx/sites-available which you enable with a ln in /etc/nginx/sites-enabled.
As far as the config:
server {
root /var/www/mysite/; #or whereever your site files are
index index.html;
location /{
try_files $uri $uri/ =404;
}
}
You are missing the root portion which tells nginx where the site is located.
Related
What I'm trying to achieve is to have a project use the subdomain as part of the request path for react SPA.
e.g. qem.xxx.com -> xxx.com/qem for a SPA where the file path doesn't change with the request.
I've been messing about for a while with rewrites but haven't been able to achieve it. Most of the resources seem to deal with the opposite, or with non-SPAs where the file path matches.
Here's the latest conf:
server {
listen ${NGINX_PORT};
server_name ${NGINX_HOST}
charset utf-8;
client_max_body_size 20M;
# what file to server as index
root /src/build;
index index.html index.htm;
error_page 503 #maintenance;
location #maintenance {
root /src;
rewrite ^(.*)$ /deploy/maintenance.html break;
}
location / {
# First attempt to serve request as file, then
# as directory, then fall back to redirecting to index.html
if (-f /src/maintenance.txt) {
return 503;
}
try_files $uri $uri/ #qem /index.html;
}
location #qem {
rewrite ^ /qem/$request_uri?;
try_files $uri $uri/ /index.html;
}
}
EDIT: Further details as requested:
NGINX_HOST=qem.xxx.com
Only one SPA application, so only one index.html in folder root
Have static resources that $uri and $uri/ match, all site content is served by index.html
Trying to achieve access to qem.xxx.com to serve as if the user accessed xxx.com/qem/ (i.e. this subdomain serves that part of SPA)
Currently semi-works in that it serves a blank page (200s).
Even just a general steer in the correct direction would be great!
Cheers,
Carl
How can I deploy these two together, I don't like the Laravel React preset, I want to separate both, bundle the React app and deploy them together with any web server (apache, nginx...)
EDIT
This is my config for Laravel, but it isn't loading the routes
server {
listen 8000;
server_name 127.0.0.1
root "..\..\Proyecto\Backend\JWT\public";
add_header 'Access-Control-Allow-Origin' '*';
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
index index.html index.htm index.php;
charset utf-8;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
error_page 404 /index.php;
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.(?!well-known).* {
deny all;
}
}
You can run them separately using nginx
you run each on separate ports and use methods (POST/GET) to push/get data
use pm2 (http://pm2.keymetrics.io/) for running React (I recommend it because you can monitor the activity of the react app and if you want to do maintenance you can stop the current app process and run a "under maintenance" app process)
you can read more about running laravel on nginx here (https://www.digitalocean.com/community/tutorials/how-to-deploy-a-laravel-application-with-nginx-on-ubuntu-16-04)
as for running react without pm2, you have to build the project yarn build and tell nginx that the file you want to load is the index.html inside of the build file
assuming that you are using an ubuntu server and you uploaded your code to github or gitlab
server {
listen 50;
root /var/www/[Your repo name]/build;
server_name [your.domain.com] [your other domain if you want to];
index index.html;
location / {
try_files $uri /index.html;
}
}
you write this inside of your nginx configuration along with the laravel configuration on a separate port
hope my answer helped a bit
This was proving to be very tricky and it took me at least 3 days to put everything together. Here is what you have to do.
Run
npm run build in the react project.
Copy the contents of the build folder to the server
scp react_project/build/* <server name or ip>:/var/www/html/react
Change the ownership of the project folders to the user www-data or add your user id to the group www-data.
Now. set up the Laravel project in a different directory (in /var/www/html/laravel, for example).
Set up the database, environment variables.
Run
php artisan key:generate
php artisan config:clear
php artisan config:cache
Now, proceed with nginx configuration. Create 2 configs for react and laravel projects as given below. Make sure that the listen ports are different for both projects.
Create configuration files for react and laravel projects under /etc/nginx/sites-available
Create symlinks to the created configs under /etc/nginx/sites-enabled as given below
sudo ln -s /etc/nginx/sites-available/react_conf /etc/nginx/sites-enabled/react_conf
sudo ln -s /etc/nginx/sites-available/laravel_conf /etc/nginx/sites-enabled/laravel_conf
And for the contents,
react_conf:
server {
listen 80;
server_name <server_ip or hostname>;
charset utf-8;
root /var/www/html/react;
index index.html index.htm;
# Always serve index.html for any request
location / {
root /var/www/html/react;
try_files $uri /index.html;
}
error_log /var/log/nginx/react-app-error.log;
access_log /var/log/nginx/react-app-access.log;
}
laravel_conf:
server {
listen 90;
server_name <server ip or hostname>;
charset utf-8;
root /var/www/html/laravel/public;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
index index.php index.html index.htm;
# Always serve index.html for any request
location /api {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
error_page 404 /index.php;
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.(?!well-known).* {
deny all;
}
error_log /var/log/nginx/laravel-app-error.log;
access_log /var/log/nginx/laravel-app-access.log;
}
Now, delete the default config present in /etc/nginx/sites-enabled
Also, verify that /etc/nginx/nginx.conf contains the following include directive where the server configs are expected(under http)
include /etc/nginx/sites-enabled/*;
Verify that the config is fine by running
sudo nginx -t
Restart the server
sudo service nginx restart
Now, you should be up and running.
You can approach it by two ways .
First one is when the you are creating react-app in different folder than the laravel project folder . In such case just deploy laravel app and react app in two different url .
The second condition is when the react-app is inside the laravel app . In such case build the react project and put the dist folder in views folder of the laravel project . So in routes/web.php add this
//Used for handling the html file of react project
View::addExtension('html', 'php');
Route::get('/{any}', function () {
//path to dist folder index.html inside the views directory
return view('build/index');
})->where('any', '.*');
Laravel will not server the required js and css file from inside the views folder . So you need copy and paste all the content of the dist folder to public folder of the laravel project . No need to copy paste index.html file but other file need to placed in the pubic folder .
After that visit the root url of the laravel project in the browser the react app should be working
I am trying to configure nginx server according to following guide: https://gkedge.gitbooks.io/react-router-in-the-real/content/nginx.html
But looks like it doesn't work, I am trying to use with my docker image of nginx. So,
Dockerfile:
FROM nginx:1.11.5
COPY /dist /usr/share/nginx/html
COPY /vhosts.conf /etc/nginx/conf.d/vhosts.conf
vhosts.conf:
server {
listen 80 default_server;
server_name /usr/share/nginx/html;
root /usr/share/nginx/html;
index index.html index.htm;
location ~* \.(?:manifest|appcache|html?|xml|json)$ {
expires -1;
# access_log logs/static.log; # I don't usually include a static log
}
location ~* \.(?:css|js|json)$ {
try_files $uri =404;
expires 1y;
access_log off;
add_header Cache-Control "public";
}
# Any route containing a file extension (e.g. /devicesfile.js)
location ~ ^.+\..+$ {
try_files $uri =404;
}
# Any route that doesn't have a file extension (e.g. /devices)
location / {
try_files $uri $uri/ /index.html;
}
}
Trying to open a page that doesn't exists.
GET localhost/somestupidrandomurl
nginx error log:
[error] 7#7: *3 open() "/usr/share/nginx/html/somestupidrandomurl" failed (2: No such file or directory), client: 172.17.0.1, server: localhost, request: "GET /somestupidrandomurl HTTP/1.1", host: "localhost"
Thanks in advance.
After a deep search, I realize that the thing is, there is one more default.conf file at /etc/nginx/conf.d/ path and that config overwrites my config.
I simply replace the Dockerfile line 3 as
COPY /vhosts.conf /etc/nginx/conf.d/default.conf and works like a magic.
So I'm trying to run my angularJS app on the linux server, and when I access any url different from / the page is redirected to /, my config for nginx is:
server {
server_name localhost;
root /var/www/myproject/public;
index index.html;
location ~* \.(gif|jpg|jpeg|png|js|css)$ {
}
location / {
allow 127.0.0.1;
expires -1;
add_header Pragma "no-cache";
add_header Cache-Control "no-store, no-cache, must-revalidate, post-check=0, pre-check=0";
try_files $uri $uri/ /index.html =404;
}
}
Just a fyi my app just doesn't make requests, just load a local json and navigate using #/page-name(the url is not going to nowhere, angular just use this to render templates in html, this templates is already inside html), nginx need config for accept urls with "#"? any config wrong in this snippet?
I solved this by using
$locationProvider.html5Mode(true).hashPrefix('!');
and this way I'm able to use routes without '#' :D
Here's the deal: I set up the simplest nginx configuration for practicing angular and I configured the routeProvider to use html5mode. So far, so good! I set the base to '/', my links to /view1 and /view2 works fine, but only when I click these links in my index page. When I try to access them directly in the browser (or reload the page), nginx returns me a 403 forbidden. That's a simple configuration but I can't find a simple explanation about it :(
I want to set things up in a way that any route works fine without have to explicitly set it (one by one) in my nginx site.conf. By the way, permissions are good !
Here's the actual conf file:
server {
listen *:80;
server_name rbs.ang;
root /_dev/angularjs/app;
index index.html;
charset UTF-8;
location / {
expires -1;
add_header Pragma "no-cache";
add_header Cache-Control "no-store, no-cache, must-revalidate, post-check=0, pre-check=0";
try_files $uri $uri/ index.html;
}
}
You need to configure a fallback route on your server to serve index.html file when a route is not matched.
This works:
location / {
try_files $uri $uri/ /index.html?$query_string;
}