Can I serve my static website content and run a node server on the same ec2 Instance .
My ec2 instance is a t2.micro ubuntu 14.04 Image.
Tasks done :
Nodejs,npm installed. Nginx installed configured. Set up the ../../www/ directory to serve content through nginx.
I have a domain xyz.com pointed its # value to the elastic IP associated with the instance.
uploaded website files to directory . So now if I access xyz.com I get my website content through the nginx .
Cool.
But the node app is not accessible.
My node app is running on the port 3000.
tried adding
server {
root /var/www;
index: example.js
server_name _;
location / {
proxy_pass http://127.0.0.1:3000;
expires 30d; # not required
access_log off;
}
}
/etc/nginx/sites-available to point to the node server .
Cool . now xyz.com runs my node app . But no website content is accessible now :
(
And if I try hitting any API whose routes are defined in my Express routes there are no logs on the server side . only an nginx 404 error
eg:
xyz.com/myroute -404 nginx error, works on localhost:3000/myroute
xyz.com/ - returns the default route set for /
xyz.com:3000 - doesnot hit the node server. no logs.
Many online resources suggest rerouting the port 80 in the security zone to serve content over the port on which node is running. I could run the node app this way but again the whole website would have to be served through node.
I want to run them separately .
xyz.com - serves me the website
xyz.com:3000 - allows me to hit my node server Should I separate the app and website on to two different instances ? How can they be routed??
Hi I am running a similar setup but with a Jetty server instead of Node.
Below is my config;
server {
listen 80;
root /var/www/html/;
index index.php index.html index.htm;
server_name my_domain;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
try_files $uri /index.php =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;
}
location /app {
proxy_pass http://localhost:8080;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded_For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
}
}
As I understand it, you should only have to change the location /app to whatever your app path is, and obviously point the proxy_pass at the right port.
The other way of going about it will be to proxy pass on subdomain and have 2 virtual servers in nginx, so for example app.mydomain.com and app2.mydomain.com. For that kind of setup have a look at; nginx reverse proxy multiple backends
I believe you are looking for the kind of setup I have above. Good luck.
Related
I have a svelte kit project. I want to deploy the app in an Nginx web server after an npm run build. At the moment I have a node container and I use to start using npm run preview. It's working fine, but I want to deploy in a production environment using build.
How could I do that?
ref: https://kit.svelte.dev/docs#command-line-interface-svelte-kit-build
As #Caleb Irwin said, you can run node ./build/index.js
The NGINX configuration will look like this:
upstream sveltekit {
server 127.0.0.1:3000;
keepalive 8;
}
server {
# listen ...
# servername ...
# root ... (folder with an index.html in case of sveltekit being crashed)
location / {
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_set_header X-Forwarded-Proto $scheme;
proxy_pass http://sveltekit;
proxy_redirect off;
error_page 502 = #static;
}
location #static {
try_files $uri /index.html =502;
}
}
(I'm not a NGINX pro and welcomes feedback to improve on it)
You may also want to make the SvelteKit app listen only to localhost by adding the environment HOST=127.0.0.1 before running node build/index.js. This will prevent the port 3000 from being reached from the outside.
You can also look into using pm2 to manage the sveltekit process, including running it on each of your cores in cluster mode, automatic restart in case of server crash / reboot.
If you have a static website (ie no endpoints) you should use #sveltejs/adapter-static#next. It will put the files you should serve in /build directory. You can then serve the generated pages using NGINX. A sample NGINX config would be:
server {
listen 80;
server_name test.jasonrigden.com;
root /path/to/build/directory;
index index.html;
}
If your site is not static you should use #sveltejs/adapter-node and run that in your container. You could put NGINX in front of it to use its features (SSL, load balancing, firewall, etc). After building your site (using npm run build) you can run node ./build/index.js.
Alternatively, you could use Netlify, Vercel, or Cloudflare Pages to host you site.
To see how to change your adapter see the docs.
Good luck!
I've managed to deploy a Svelte Kit app to my Google Cloud Engine virtual machine and serve it using Nginx. I've still got some outstanding questions myself, but so far these are my steps:
Run the build locally as per the docs referenced by OP. Local directory: $ npm run build
Local directory:$ gcloud compute scp --recurse build/ user#gcpinstance:~/Desktop
Local directory:$ gcloud compute scp package*.* user#gcpinstance:~/Desktop
On the remote vm, from the directory to which I uploaded my build folder and the package files, (e.g.~/Desktop$), I run npm install. That re-created the node-modules folder (otherwise it takes forever to upload the node-modules folder from the local machine).
~/Desktop$ mkdir SvelteKitProd/
~/Desktop$ mv package*.* build/ node-modules/ SvelteKitProd/
~/Desktop$ sudo chown -R root:root SvelteKitProd/
~/Desktop$ mv SvelteKitProd/ /var/www/domainname/
9 ~/Desktop$ cd /var/www/domainname/
/var/www/domainname:$ sudo vi /etc/nginx/sites-available/domainname (this is my nginx configuration for this domain and this app).
upstream hijacked-media {
server 127.0.0.1:3000;
keepalive 64;
}
server {
server_name hijacked.media www.hijacked.media;
#root /var/www/hijacked.media/sveltekittest/sveltekitprod/PROD-GCP;
# index index.html index.htm;
access_log /var/log/nginx/hijacked.media.access.log;
error_log /var/log/nginx/hijacked.media.error.log;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_pass http://hijacked-media;
proxy_redirect off;
proxy_read_timeout 240s;
#proxy_cache_bypass $http_upgrade;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/hijacked.media/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/hijacked.media/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = www.hijacked.media) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = hijacked.media) {
return 301 https://$host$request_uri;
} # managed by Certbot
server_name hijacked.media www.hijacked.media;
listen 80;
return 404; # managed by Certbot
}
/var/www/domainname$ pm2 start SvelteKitProd/build/index.js
I'm still trying to figure out what all I need to do in order to serve multiple apps each from its own top-level domain. I was hoping that I could change the PORT once built and uploaded (see the build/index.js file), but so far that isn't working for me. So I'll try specifying a unique port number while building it locally or messing with it once uploaded to the remote server; or perhaps use PM2 and Nginx to make multiple apps work on the same port, e.g. 3000.
I am trying to run a react app with Node.js backend on the Nginx server.
Here's my server block in the nginx.conf file:
include /etc/nginx/conf.d/*.conf;
server {
listen 80;
listen [::]:80;
server_name _;
root /usr/share/nginx/folder-name/frontend/build;
index index.html index.htm;
location / {
proxy_pass http://localhost:5000;
}
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
The build folder contains the compiled react js code(using npm run build)
Node.js backend is running on port 5000 using pm2/forever.
After restarting the Nginx Server, the react UI appears on the server IP but the UI is distorted.
Also, I am not able to access my backend APIs on MyIP/api/endpoint.
What am i doing wrong.? This nginx configuration was built from SO and other online resources so there's a huge probabilty that it could be wrong. Please help!
Thanks in advance!
The issue is you are setting the API proxy for the root (/). The correct one should look like this:
server {
listen 80;
listen [::]:80;
server_name _;
root /usr/share/nginx/folder-name/frontend/build;
index index.html index.htm;
location /api {
proxy_pass http://localhost:5000;
}
location / {
try_files $uri $uri/ =404;
}
}
If you don't have /api path in your Node.js, you will need a rewrite rule for it like this:
location /api {
rewrite ^/api/?(.*) /$1 break;
proxy_pass http://localhost:5000;
proxy_redirect off;
proxy_set_header Host $host;
}
I had experience that.Please check my image file
This configuration is running successfully on aws.
Your mistakes is proxy area. Please change like that.
location /api/ {
proxy_pass http://127.0.0.1:5000/api/
}
If you want, I can HELP you.
Yes, you can host both API and static files (build files of your front-end) on the same domain or host. Below, you can find a server block for a sample API hosted on port 3000 and static HTML files at a root location being served on port 80.
server {
listen 80;
server_name localhost;
location / {
root /var/www/html;
index index.html;
error_page 404 index.html;
}
location /api/ {
proxy_pass http://localhost:3000/;
}
}
You can access the front-end at http://localhost/<blah...> and the API at http://localhost/api/<blah...> (please note how /api is handled in the URL here and the server block above). Replace localhost with your domain name.
What am i doing wrong.?
One issue is with your proxy_pass directive. You are missing trailing slash /
...
location / {
proxy_pass http://localhost:5000/;
}
...
First, try this and share your result.
I have one static react website and one application that connects to the API which is the express project. The landing page does not contain any routes and I'm trying to serve it at domain.com/. The dashboard has routes and I am trying to serve it under domain.com/app/. Finally, the express app should be served from domain.com/api/. Before the separation of location blocks, the react apps were one project and the express project sent the build files to the client. Everything worked then. The previous version was served from location / using the config like this:
location / {
root /var/www/domain.com;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://000.00.00.000:5000; # my droplet IP is normally here
}
The /var/www/ directory currently has a structure like this:
- var
--www
---domain.com
----landing
----dashboard
----server.js
----other files from the express project
I am trying to understand how I can separate these three projects under one server block. Using the configuration shown below the only one that shows up is the landing which is served from domain.com/.
server {
server_name domain.com www.domain.com;
#Configures the publicly served root directory
#Configures the index file to be served
#root /var/www/domain.com/landing/build;
#index index.html index.htm;
location app/ {
root /var/www/domain.com/dashboard/build;
try_files $uri $uri/ =404;
}
location api/ {
root /var/www/domain.com;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://000.00.00.000:5000; # my droplet IP is normally here
}
location / {
root /var/www/domain.com/landing/build;
try_files $uri $uri/ =404;
}
# Certbot stuff
}
How can these three projects be served separately under the same domain? Thank you in advance.
I have set up Ubuntu droplet with UFW, MySQL, Node, Vue-Cli, and NginX.
I have created an “apps” folder inside “html”
/var/www/html/apps/
apps folder contains two folders:
/var/www/html/apps/codnode
/var/www/html/apps/codvue
Inside codvue folder, I cloned the Vue app
and for codnode folder, I cloned the node api (uses port 3001)
Here are NginX server blocks (or whatever they are called) settings.
Default server config:
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html/apps/codvue/dist;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name _;
error_page 404 /;
location / {
try_files $uri $uri/ =404;
}
}
Created another server block named node:
server {
listen 81 default_server;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name IPADDRESS;
error_page 404 /;
location / {
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_pass http://127.0.0.1:3001;
proxy_set_header Host $http_host;
proxy_cache_bypass $http_upgrade;
proxy_redirect off;
}
}
Both the Default and node are linked to sites-enabled…
The issue that I’m currently experiencing is:
When I go to /var/www/html/apps/codvue/ and create a build using:
sudo npm run build
After restarting Nginx service, I open the website using the IP address, the interface of the app loads just fine (means Vue is working, correct?). Alongside I’m running the Node app in another terminal which says running at port 3001 and Db connection successful.
But other than the Vue interface no data is shown. front end working. Backend NOT Displaying. When I try to access this URL: http://IPADDRESS:81/Api/category/categories-list it shows the data:
[{"catID":1,"catName":"sabdasdv1","catDesc":"qdjqbwd","isActive":"1","date":....
Now I go back to /var/www/html/apps/codvue/ and execute the following command:
sudo npm run serve
The app is served on port 8080. When I open the http://IPADDRESS:8080, the app loads just fine… Both the interface and the data is there.
Can someone please guide me on how can I get the build version to work? What am I doing wrong here?
Below is the Vue config file:
const path = require('path');
module.exports = {
// outputDir :path.resolve(__dirname, '../server/public'),
devServer:{
proxy:{
'/api':{
target: 'http://IPADDRESS:81'
}
}
}
}
I have a feeling that I’m missing a very small but important piece of this puzzle to make this thing work with Vue’s Build version.
Any sort of help will be highly appreciated. Thank you for your time in reading it to the end.
Thanks again!
Let's try a different configuration.
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html/apps/codvue/dist;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name _;
error_page 404 /;
location / {
try_files $uri $uri/ =404;
}
location /api {
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_pass http://127.0.0.1:3001;
proxy_set_header Host $http_host;
proxy_cache_bypass $http_upgrade;
}
}
Please comment the block with configuration with server on port 81 (whole file).
After make the configuration, test the configuration to check if there is syntax errors:
sudo nginx -t
If everything ok, output should be:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Then restart your nginx with:
sudo nginx -s reload
Cache clean your browser and try again.
I'm currently running into some configuration problems with NGINX where I keep getting a 502 error instead of NGINX falling back onto a different directory if either the server is down or the directory doesn't exist.
I'm running a Node.js application on port :3000, have SSL set up, and have all HTTP requests redirect to HTTPS. Given the scenario where my node.js application is offline, I wish to send the client to the default NGINX root directory /usr/share/nginx/html index index.htm index.html if possible.
I'm trying to have the nodejs application on port 3000 be shown on / but in the case that the server is down, to fallback on NGINX default directory and display the index.html in there instead. Can anyone help or guide me through this process?
Thank you
Edit: I've tried jfriend00 said in the comments, but now my proxy_pass doesn't seem to work. It would now default to the 500.html regardless whether my server is running or not. I've attached my nginx.conf file, would appreciate any help.
events {
worker_connections 1024;
}
http {
upstream nodejs {
server <<INTERNAL-PRIVATE-IP>>:3000; #3000 is the default port
}
...
server {
listen 80;
server_name <<PUBLIC-IP>>;
return 301 $scheme://<<DOMAIN>>$request_uri;
}
server {
listen 443;
ssl on;
server_name <<DOMAIN>>.com www.<<DOMAIN>>.com;
...
location / {
proxy_pass http://nodejs;
proxy_redirect off;
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-Forwarded-Proto https;
}
error_page 501 502 503 /500.html;
location = /500.html {
root /usr/share/nginx/html;
}
}
}
Adding the error_page works as I did above and it successfully kicks back. Thanks #jfriend00.
If you're deploying it to a live server, you might want to check this out since I had a hard time trying to figure out why my proxy_pass and my NGINX configuration wasn't working on CentOS deployed on EC2. It had nothing to do with the error_page.