google cloud pm2 start nodejs successfully but not accessible - node.js

I started node server successfully with pm2 but I couldn't access to my host.
I opened port on google cloud.
OS: Debian.
node version: v8.12.0
pm2 version: 3.2.2
I tried pm2 kill and restart but nothing happend. What am I wrong?

Take the following steps to remediate your connectivity issue:
Check to see what programs are running and what port(s) they are listening on. See if you can identify your program running:
sudo netstat -tnlp If you see a node process, notice the port it is listening on. Does this match 3000? If so, check to see what network address it is listening on: Does it show 0.0.0.0 or does it show 127.0.0.1? If it shows 127.0.0.1 then your application is only listening on localhost and you need to modify it to listen on 0.0.0.0.
Check the local firewall to see if you have allowed port 3000 by running sudo iptables -nL. If you do not see ANY rules period and see "policy ACCEPT" then you're ok. Otherwise, if you do not see TCP port 3000 then we need to add an allow/permit rule. To do so run sudo ufw allow 3000. If the ufw command is not found then you can run sudo iptables -A INPUT -p tcp --jport 2195 -j ACCEPT followed by sudo /etc/init.d/iptables save.
If you still cannot connect to your application please provide the output to the following commands:
sudo iptables -nL
sudo netstat -tnlp
gcloud compute firewall-rules list (if gcloud cli is installed, otherwise another screenshot of your firewall rules under your network settings in GCP console).

I config nginx default as a proxy to nodejs server. And It still work!
proxy_pass http://localhost:3000;
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;

Check first with curl http://localhost:3000
Make sure you open your project firewall port 3000
https://console.cloud.google.com/networking/firewalls/list?project=xxxx
Run this SELINUX, I'm on centos7
sudo setsebool -P httpd_can_network_connect on
sudo setsebool -P httpd_enable_homedirs on
sudo chcon -Rt httpd_sys_content_t /home/admin/www
sudo systemctl restart nginx

Related

Running Node app via PM2 on port 80

I have an express that I want to run on port 80. --> app.listen(80);
I'm using PM2 to manage the app (restarting, stopping, monitoring, etc.) . I have a deployment shell script whose last command is PM2 restart index. From the console output, I see no errors and PM2 reports that it successfully completed the command. Yet when I got to my.ec2.ip.address:80 the site is not up. Furthermore, if I run node index.js in my server project directory, I get a Error: listen EACCES 0.0.0.0:80. This makes some sense to me as port 80 is below 1024 and therefore a privileged port. sudo node index.js will allow the launch to work.
I'm a newbie to unix, servers, permissions, and deployment, so in addition to the solution, an explanation of the fundamental concepts contributing to my problem would be greatly appreciated. For instance.. is it bad to simply run my node app as super-user? Is it good practice to run PM2 (therefore possibly running node as..?) root/super-user? The command sudo PM2 restart index leads to sudo: pm2: command not found. Why is PM2 not found when running sudo PM2.. if PM2 is in my path?
Ultimately though, when using PM2 how can I ensure that my server runs on port 80? not found.
Dont use port 80, run on other port like 8080 and redirect 80 to that port with this command
sudo iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080
It's good to run as little as possible as a priviliged user, as you want to restrict the potential damage in case someone exploits your program. You don't want to run your Node code as root unless you absolutely have to.
Therefore, it's better to run your Node program on an unprivileged port (say, port 8000), and instead have a lightweight web server such as Nginx listen on port 80 and simply forward traffic to your Node program.
If you want to go with Nginx, you can use this configuration to do exactly what I described above, and then just listen with your Node program on port 3000:
server {
listen 80 default;
listen [::]:80 default;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-for $proxy_add_x_forwarded_for;
}
}
I had the same issue, for the ubuntu server.
Fixed with the tutorial below.
sudo apt-get install libcap2-bin
sudo setcap cap_net_bind_service=+ep /usr/local/bin/node
https://www.digitalocean.com/community/tutorials/how-to-use-pm2-to-setup-a-node-js-production-environment-on-an-ubuntu-vps
Also here is another solution from PM2
sudo apt-get install authbind
sudo touch /etc/authbind/byport/80
sudo chown %user% /etc/authbind/byport/80
sudo chmod 755 /etc/authbind/byport/80
https://pm2.keymetrics.io/docs/usage/specifics/#listening-on-port-80-w-o-root
Though, you may have solved the issue but for the one who comes here facing the same issue, this worked me :
For just troubleshooting, run your app using sudo npm start. If your app runs normally then you need to bind port 80 with the help of authbind package. Run these commands :
sudo apt-get install authbind
sudo touch /etc/authbind/byport/80
sudo chown %user% /etc/authbind/byport/80
sudo chmod 755 /etc/authbind/byport/80
Replace %user% with the user you run pm2. Mine was ubuntu by default.
Set start command in your package.json file to pm2 start <server_file_name>.
Run the app using npm start. It should work !
After lot of time spent configuring nginx, finally uninstall it and followed A.J. suggestion to configure iptables. Thank you A.J.
sudo iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080
But, if anyone know a perfect tutorial to configure nginx, would be a great help.

linux systemd service on port 80

I try to create systemd service on centos7:
[Unit]
Description=Node.js Weeki Server
Requires=After=mongod.service
[Service]
ExecStart=/usr/bin/node /var/node/myapp/bin/www
Restart=always
StandardOutput=syslog # Output to syslog
StandardError=syslog # Output to syslog
SyslogIdentifier=nodejs-weeki
User=weeki
Environment=NODE_ENV=production PORT=80
[Install]
WantedBy=multi-user.target
When i use port 8080 the service start successfully, but when i change the port to 80, the service failed to start.
I try to open the firewall with the command:
firewall-cmd --zone=public --add-port=80/tcp --permanent
But it still not working.
See the good advises that you got in the comments by arkascha.
First of all - what's the error?
What you can do to test if it's a problem of the user not being able to bind to low ports is trying use ports like 81, 82, 83 etc. If you still cannot bind to those ports then you likely don't have the permission. If you can, then it's not about permissions and the port is already used by some other process.
To see if you can open a given port by that user try running netcat:
nc -l 80
where 80 is the port number. Try low ports like 80, 81, 82 and high ports like 8080, 8081, 8082.
To see if anything is listening to that port try running:
curl http://localhost:80/
or:
nc localhost 80
To see open ports on your system run:
netstat -lnt
To see if other instances of your program are running, try:
ps aux | grep node
ps aux | grep npm
ps aux | grep server.js
If all else fails, you can restart and see if the problem remains:
sudo shutdown -r now
That should give you a clean state with no old processes hanging around.
Update
What you can do to listen on port 80 without running as root.
There are few things that you can do:
Drop privileges
You can start as root and drop privileges as soon as you open a port:
app.listen(80, function () {
try {
process.setuid('weeki');
process.setgid('weeki');
console.log('Listening on port 80');
console.log('User:', process.getuid(), 'Group:', process.getgid());
} catch (e) {
console.log('Cannot drop privileges');
process.exit(1);
}
});
Pros: You don't need to use anything other than your Node program.
Cons: You need to start as root.
See:
https://nodejs.org/api/process.html#process_process_setuid_id
https://nodejs.org/api/process.html#process_process_setgid_id
Reverse proxy
Your Node app can listen on high port like 3000 and you start nginx or other web server to listen on port 80 and proxy requests to port 3000.
Example nginx config:
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://localhost:3000;
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;
}
}
Pros: You don't need to start as root. You can host multiple domains on the same server. You can serve static content directly by nginx without hitting your Node app.
Cons: You need to install and run another software (like nginx).
Route tables
You can redirect the incoming traffic on port 80 to port 3000 with iptables:
iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 3000
(you need to run it as root)
Pros: No new software to install. No need to run the Node app as root.
Cons: Static content is served by your Node app. Hosting more than one app per server is not practical.
See:
https://help.ubuntu.com/community/IptablesHowTo
Allow low port for non-root
This is not always available but also an option. You can use the CAP_NET_BIND_SERVICE capability in the Linux kernel:
CAP_NET_BIND_SERVICE
Bind a socket to Internet domain privileged ports (port
numbers less than 1024).
Pros: No need to run other software. No need to start Node app as root. No need to mess with route tables.
Cons: Not practical to host more than one app per server. Needs using capabilities that may not be available on every system.
See:
http://man7.org/linux/man-pages/man7/capabilities.7.html
User should have root privileges to open ports below 1024.

Nginx & Node inside the same Docker container

I know that this is against the accepted convention but I need to run Nginx alongside a node.js server inside the same Docker container. I have no issues spinning up the container and getting Nginx and Node working alongside. Nginx works on Port 443 which is exposed by the container. The Node server listens on Port 8080 and is reverse proxied by Nginx
location /node/index.js {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X_Forwarded_For $proxy_add_x_forwarded_for;
}
Here is what I find
Access to the resources, https://example.com/text.txt on the Nginx server is straightforward
I startup the Nodejs server nodejs index.js & disown which has been configured to output a few diagnostic messages to a log file. Those messages tell me that the server is working just fine.
I can Telnet to Port 8080 from inside the Docker container - once again indicating that the Node server i sup and running
Precisely the same configuration but with Nginx running on a "real" server with Node running on the same server offers acceess to the Node server with no issues.
However, when I attempt to access the Node server running inside the Nginx Docker container, say, https://example.com/node/index.js I get a 404 error.
Examining my Nginx logs reveals that the request did reach Nginx inside its Docker host. However, examining the Node server log file indicates that the request never got forwarded.
It is not clear to me why this could be happening. From what I can tell when Nginx is running inside a Docker container it is failing to act as a reverse proxy for Node running inside the same container.
For good measure I tried EXPOSing the Node port, 8080 and starting up the Docker container with -p 8080:8080 -p 443:443 but that made no difference. I'd be most grateful to anyone who might be able to shed any light on what is going on here.

Mongodb Management Service Error, Failure dialing host

I've downloaded MMS by using this command
curl -OL https://mms.mongodb.com/download/agent/monitoring/mongodb-mms-monitoring-agent_latest_amd64.deb
Installed it by using sudo
sudo dpkg -i mongodb-mms-monitoring-agent_latest_amd64.deb
And edited /monitoring-agent.config file which located in
/etc/mongodb-mms
It was working Just fine Until I've started my mongod rplSet by adding --Fork flag, and by using this command
sudo mongod --fork --port 27017 --dbpath /mydbpath --logpath /mylogpath/mongodb.log --replSet Rplname
After starting the services using the above command, my MMS started showing that the host is Unreachable, and that following msg, in all of the members.
Task failure `hostIpAddr`. Err: `Failure determining IPv4 address for `myDnsAdd.cloudapp.net`. Err: `myDnsAdd.cloudapp.net: no such host` at monitoring-agent/components/task.go:221 at monitoring-agent/components/worker.go:153 at monitoring-agent/components/worker.go:224 at monitoring-agent/components/worker.go:236 at pkg/runtime/proc.c:1445`
I've edited the hosts file, and added the hosts ips and hostnames.
Opened the 443 port, and tried to start mmms with --system flag like this
sudo start mongodb-mms-monitoring-agent --system
But still, Host is Unreachable. I got access list on the mongoport (:27017) is it beacuse of this? if so what IP should I add to that access list?
Best,
If your OS is Ubuntu 14.04, then this link should be interesting for you:
https://jira.mongodb.org/browse/MMS-2202
Basically it says that it is a bug in glibc and the solution for this guy was to update Ubuntu to version 14.10.

Connection refused to MongoDB errno 111

I have a Linode server running Ubuntu 12.04 LTS and MongoDB instance (service is running and CAN connect locally) that I can't connect to from an outside source.
I have added these two rules to my IP tables, where < ip address > is the server I want to connect FROM (as outlined in this MongoDB reference):
iptables -A INPUT -s < ip-address > -p tcp --destination-port 27017 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -d < ip-address > -p tcp --source-port 27017 -m state --state ESTABLISHED -j ACCEPT
And I see the rule in my IP table allowing connections on 27017 to and from < ip address > however when I try to connect from , < ip address > to my mongo database using a command like this:
mongo databasedomain/databasename -u username -p password
I get this error:
2014-07-22T23:54:03.093+0000 warning: Failed to connect to databaseserverip:27017, reason: errno:111 Connection refused
2014-07-22T23:54:03.094+0000 Error: couldn't connect to server < ip address >:27017 (databaseserverip), connection attempt failed at src/mongo/shell/mongo.js:148
exception: connect failed
Any help is VERY APPRECIATED!!!! Thanks!!!
Thanks for the help everyone!
Turns out that it was an iptable conflict. Two rules listing the port open (which resulted in a closed port).
However, one of the comments by aka and another by manu2013 were problems that I would have run into, if not for the conflict.
So! Always remember to edit the /etc/mongod.conf file and set your bind_ip = 0.0.0.0 in order to make connections externally.
Also, make sure that you don't have conflicting rules in your iptable for the port mongo wants (see link on mongodb's site to set up your iptables properly).
Try the following:
sudo rm /var/lib/mongodb/mongod.lock
sudo service mongodb restart
These commands fixed the issue for me,
sudo rm /var/lib/mongodb/mongod.lock
sudo mongod --repair
sudo service mongod start
sudo service mongod status
If you are behind proxy, use:-
export http_proxy="http://username:password#company.com:port/"
export https_proxy="http://username:password#company.com:port/"
Reference: https://stackoverflow.com/a/24410282/4359237
For Ubuntu Server 15.04 and 16.04 you need execute only this command
sudo apt-get install --reinstall mongodb
I Didn't have a /data/db directory. I created one and gave a chmod 777 permission and it worked for me
For me, changing the ownership of /var/lib/mongodb and /tmp/mongodb-27017.sock to mongodb was the way to go.
Just do:
sudo chown -R mongodb:mongodb /var/lib/mongodb
and then:
sudo chown mongodb:mongodb /tmp/mongodb-27017.sock
and then start or restart the mongodb server:
sudo systemctl start mongod
or
sudo systemctl restart mongod
and check the status
sudo systemctl status mongod
One other option is to just repair your database like so (note: db0 directory should be pre-created first):
mongod --dbpath /var/lib/mongodb/ --repairpath /var/lib/mongodb/db0
This is also an acceptable option in production environments...
I also had the same issue.Make a directory in dbpath.In my case there wasn't a directory in /data/db .So i created one.Now its working.Make sure to give permission to that directory.
In my case previous version was 3.2. I have upgraded to 3.6 but data files was not compatible to new version so I removed all data files as it was not usable for me and its works.
You can check logs using /var/log/mongodb
I follow this tutorial's instructions for installation
How to Install MongoDB on Ubuntu 16.04
I had the same mistake. Finally, I found out that I needed to set the port number
The default port number for the mongo command is 27017
But the default port number in mongo.conf is 29999
This done the trick for me
sudo service mongod restart
Even though the port is open, MongoDB is currently only listening on the local address 127.0.0.1. To allow remote connections, add your server’s publicly-routable IP address to the mongod.conf file.
Open the MongoDB configuration file in your editor:
sudo nano /etc/mongodb.conf
Add your server’s IP address to the bindIP value:
...
logappend=true
bind_ip = 127.0.0.1,your_server_ip
#port = 27017
...
Note that now everybody who has the username and password can login to your DB and you want to avoid this by restrict the connection only for specific IP's. This can be done using Firewall (read about UFW service at Google). But in short this should be something like this:
sudo ufw allow from YOUR_IP to any port 27017

Resources