How to run nodejs inside container correctly? - node.js

I have docker image that consist of nginx to server my index.html file with the following config:
server {
listen 80;
server_name mysite;
root /var/www/application;
index index.html;
}
No I need to add nodejs to handle /api/ location just like the following:
upstream api_node_js {
server 127.0.0.1:3000;
}
server {
listen 80;
server_name mysite;
root /var/www/application;
index index.html;
}
location /api {
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;
proxy_set_header X-NginX-Proxy true;
rewrite ^/api/?(.*) /$1 break;
proxy_pass http://api_node_js;
proxy_redirect off;
}
So I need to install and run NodeJS server on 3000 to handle api requests. My question is how should I run it correctly?
I've already tried add running via forever with the following command in my Dockerfile:
WORKDIR /var/www/application
CMD ["forever", "start", "server.js"]
But unfortunately after starting of container it immediately exited now with no errors.
Please help me what I'm doing wrong?

While #ilyapt is right, and you should separate the nginx and node into two containers, this is not the answer to your question. What you should do is omit the start from your docker cmd, to prevent forever from running in the background - causing the container to exit.
Try changing your last line in the dockerfile to this - CMD ["forever", "server.js"] and see if it helps.

Really way to correctly run is run nginx and node.js in separated containers. Docker is a platform to isolate applications from one another and it run one application in foreground and control only this application.
Start more one applications in one container is possible but this is bad idea.

Related

How to deploy a svelte kit app after build using nginx as web server

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.

Issue with Deploying Vue.js + Node + MySQL + NginX app #DigitalOcean

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.

Cant deploy correctly Vuejs app from git in Jelastic

its the first time i use Jelastic and i need to deploy a vuejs app from git.
I've make a Nodejs env and deploy my vuejs app. Then, i run:
cd ROOT
npm install
npm run build
And i get an successfully message: Build complete. The dist directory is ready to be deployed.
So, what i usually do next in localhost is something like this:
cd dist
npm http-server
But in Jelastic i don't really know whats next after the build. I've try to go into http://node-env.route/dist but i get a 502 error page (The opened link forwards to the environment where the application server is down or is not picked up yet.)
Hope you can help me, thank you!
In order to run your application I suggest you to install pm2 on your server and run this command:
pm2 start npm --name "your-app-alias" -- start
After re-build you need to restart:
pm2 restart your-app-alias
Maybe after that you need a reverse proxy with NGINX to link your nodejs env to your localhost. Something like that:
server {
listen 80; # the port nginx is listening on
server_name YOUR-JELASTIC-ENV-URL; # setup your domain here
location / {
expires $expires;
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 $scheme;
proxy_read_timeout 1m;
proxy_connect_timeout 1m;
proxy_pass http://127.0.0.1:3000; # set the adress of the Node.js instance here
}
}

Make request to local server on port 8080

I have now the following flow.
example.com => https://example-example.mycompany.com => myproxy => someServer
I am right now developing myproxy and it changes the answers that the clients of the website example.com are receiving.
In order to test this, I thought that the best idea I could come up with was changing my local machine (in which I have an instance of myproxy running on the port 8080) so I redirect only my requests that go to example-example.mycompany.com to localhost:8080
I have tried with nginx adding the following configurationbut I was unable... and also changing /etc/hosts didn't help me.
Question
Is there any way to change the call of example-example.mycompany.com JUST for my computer, so that while I am testing there is no client of example.com affected by the changes in the local myproxy?
Trials
Create a docker container running in 8080 and 80 and try to make the requests against it
docker run --name my-custom-nginx-container -v $(pwd)/nginx.conf:/etc/nginx/nginx.conf:ro -p 80:80 -p 3000:8080 --rm -d nginx
Creating an nginx server (so I don't have issues with containers maybe not being properly bind)
nginx.conf
server {
listen 80;
server_name example-example.mycompany.com;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://localhost:3000/;
proxy_redirect http://localhost:3000/ https://$server_name/;
}
}
Adding the example-example.mycompany.com to the etc/hosts file (didn't do anything)
/etc/hosts
127.0.0.1 example-example.mycompany.com
NOTE: I've seen it work in the computer of my coworker which is using windows. I can't get it to work in Linux/MacOs.

Subdomain problems using nginx as a reverse proxy for node apps

I am new to nginx and I'm struggling to get my configuration for a reverse proxy working. I have a node app running on localhost:3010 and I'm trying to serve pages through nginx from this app at the subdomain dev.[sitename].org. Let's just say dev.example.org for readability. Here are the contents of a file I created in sites-available called example.org (is that the correct name for this file?):
server {
server_name www.example.org example.org;
}
upstream app_dev.example.org {
server 127.0.0.1:3010;
}
server {
listen 0.0.0.0:80;
server_name dev.example.org;
access_log /var/log/nginx/dev.example.access.log;
location / {
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;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://app_dev.example.org/;
proxy_redirect off;
}
}
This is mostly based off this related question: Node.js + Nginx - What now? however when I try to open dev.example.org in my browser, Chrome reports that it can't find the page. I can ping dev.example.org and get an IP address, so the server seems to be available, but my nginx configuration incorrect. I created the symlink in sites-enabled and restarted nginx, in case you thought I might have forgotten those steps.
So my thought now is that I'm not referring to the subdomain correctly somewhere, or maybe my file in sites-available is named wrong. Any push in the right direction would be appreciated.
Just to be sure the problem is on nginx try these steps:
Set a test server at port 3030, serving the system doc folder or anything else.
server {
listen 3030
location / {
root /usr/share/doc/;
autoindex on;
}
}
upstream simple_test {
server 127.0.0.1:3030
}
Then use simple_test below as well:
proxy_pass http://simple_test/;
If you see the /usr/share/doc dir listing when you access dev.example.org then your issue is on the node side.
Turned out something was blocking port 80! fixed that and the config as posted above worked

Resources