Can't access sinatra server from other computers - ruby

I am running a sinatra server with shotgun that returns a hello world when request GET in the root (typical tutorial) and works perfectly in my computer. I could only access it from localhost:9393 and then i run it with -o 0.0.0.0 and could access it as IP:9393 but still only from the computer where the server was running.
How can i access the server from other computers? already tried bind 0.0.0.0 and environment production.
Thanks in advance.

A bit more information is needed, like the OS that you are running and if you have made sure that any local firewalls are not blocking your traffic. I see that you marked this with the "Shotgun" tag which tells me that you are running on a *nix system as Shotgun uses forks and windows doesn't support them.
Check your iptables and see if you got anything in there. :)
iptables -nvL -t nat --line-numbers
iptables -nvL --line-numbers

Related

MongoDB no suitable servers found

I'm having trouble connecting to a replica set.
[MongoDB\Driver\Exception\ConnectionTimeoutException]
No suitable servers found (`serverSelectionTryOnce` set):
[Server closed connection. calling ismaster on 'a.mongodb.net:27017']
[Server closed connection. calling ismaster on 'b.mongodb.net:27017']
[Server closed connection. calling ismaster on 'c.mongodb.net:27017']
I however, can connect using MongoChef
Switching any localhost references to 127.0.0.1 helped me. There is a difference between localhost and 127.0.0.1
See: localhost vs. 127.0.0.1
MongoDB can be set to run on a UNIX socket or TCP/IP
If all else fails, what I've found that works most consistently across all situations is the following:
In your hosts file, make sure you have a name assigned to the IP address you want to use (other than 127.0.0.1).
192.168.0.101 coolname
or
192.168.0.101 coolname.somedomain.com
In mongodb.conf:
bind_ip = 192.168.0.101
Restart Mongo
NOTE1: When accessing mongo from the command line, you now have to specify the host.
mongo --host=coolname
NOTE2: You'll also have to change any references to either localhost or 127.0.0.1 to your new name.
$client = new MongoDB\Client("mongodb://coolname:27017");
I had the same error in a docker based setup:
container1: nginx listening on port 80
container2: php-fpm listening on port 9000
container3: mongodb listening on port 27017
nginx forwarding php to php-fpm
Trying to access mongodb from php gave this error.
In the mongodb Dockerfile, the culprit was:
CMD ["mongod", "--bind_ip", "127.0.0.1"]
Needed to change it to:
CMD ["mongod", "--bind_ip", "0.0.0.0"]
And the error went away. Hope this helps somebody.
The IP address of your home network may have changed, which would lead to MongoDB locking you out.
I solved this problem for myself by going to MongoDB Atlas and changing which IP address is allowed to connect to my data. Originally, I'd set it up to only allow connections from my home network. But my home network IP address changed, and I started getting the same error message as you.
To check if this is the same issue with you, go to MongoDB Atlas, go into your project, and click "Network Access" on the left hand side of the screen. That's where you're able to update your IP address. It shows you what IP address(es) it's allowing in. To find out what your current IP address is, go to whatismyipaddress.com and update MongoDB if it's different.
In my case, I am temporarily coding PHP from Windows7 against MongoDB on my VPS running Linux Debian 9. The PHP will be eventually running in the same Linux box to provide an API to the MongoDB data.
BTW, it does not appear this local composer install is doing me any good, it's pure ugliness. My PHP after the fix below works without the require line require_once 'C:\Users\<Windows User Name>\vendor\autoload.php'.
My fix is different than the accepted answer which to me did not make sense.
I did not have to touch any hosts file
So edit your /etc/mongod.conf with your target machine's IP and restart with sudo systemctl restart mongod that's it
I don't know what to blame
PHP and MongoDB sites for the terrible documentation skimpy and incomplete PHP examples, or...
MongoDB installation on Linux failing to mention this bindIP.
My startup experience with MongoDB is so far very negative given all the changes that have occurred nothing matches what I expected from the videos I watched. I can't seem to find any that reflect what I am going thru like
$DB_CONNECTION_STRING="mongodb://user:password#164.152.09.84:27017"
$m = new MongoDB\Driver\Manager( $DB_CONNECTION_STRING )
instead of
$m = new MongoClient()
Hope this helps someone
PS. Always say NO to semicolons, camelCAsE and anything case-sensitive... absurdity at its best.

Hooking up into running heroku phoenix application

Previous night I was tinkering with Elixir running code on my both machines at home, but when I woke up, I asked myself Can I actually do the same using heroku run command?
I think theoretically it should be entirely possible if setup properly. Obviously heroku run iex --sname name executes and gives me access to shell (without functioning backspace which is irritating) but i haven't accessed my app yet.
Each time I executed the command it gave me different machine. I guess it's how Heroku achieve sandbox. I also was trying to find a way to determine address of my app's machine but haven't got any luck yet.
Can I actually connect with the dyno running the code to evaluate expressions on it like you would do iex -S mix phoenix.server locally ?
Unfortunately it's not possible.
To interconnect Erlang VM nodes you'd need EPMD port (4369) to be open.
Heroku doesn't allow opening custom ports so it's not possible.
In case You'd want to establish a connection between your Phoenix server and Elixir node You'd have to:
Two nodes on the same machine:
Start Phoenix using iex --name phoenix#127.0.0.1 -S mix phoenix.server
Start iex --name other_node#127.0.0.1
Establish a connection using Node.ping from other_node:
iex(other_node#127.0.0.1)1> Node.ping(:'phoenix#127.0.0.1')
(should return :pong not :pang)
Two nodes on different machines
Start Phoenix using some external address
iex --name phoenix#195.20.2.2 --cookie someword -S mix phoenix.server
Start second node
iex --name other_node#195.20.2.10 --cookie someword
Establish a connection using Node.ping from other_node:
iex(other_node#195.20.2.10)1> Node.ping(:'phoenix#195.20.2.2')
(should return :pong not :pang)
Both nodes should contact each other on the addresses they usually see each other on the network. (Full external IP when different networks, 192.168.X.X when in the same local network, 127.0.0.1 when on the same machine)
If they're on different machines they also must have set the same cookie value, because by default it takes automatically generated cookie in your home directory. You can check it out by running:
cat ~/.erlang.cookie
What's last you've got to make sure that your EPMD port 4369 is open, because Erlang VM uses it for internode data exchange.
As a sidenote if you will leave it open make sure to make your cookie as private as possible, because if someone knows it, he can have absolute power over your machine.
When you execute heroku run it will start a new one-off dyno which is a temporary instance that is deprovisioned when you finish the heroku run session. This dyno is not a web dyno and cannot receive inbound HTTP requests through Heroku's routing layer.
From the docs:
One-off dynos can never receive HTTP traffic, since the routers only route traffic to dynos named web.N.
https://devcenter.heroku.com/articles/one-off-dynos#formation-dynos-vs-one-off-dynos
If you want your phoenix application to receive HTTP requests you will have to set it up to run on a web dyno.
It has been a while since you've asked the question, but someone might find this answer valuable, though.
As of 2021 Heroku allows forwarding multiple ports, which allows to remsh into a running ErlangVM node. It depends on how you deploy your application, but in general, you will need to:
Give your node a name and a cookie (i.e. --name "myapp#127.0.0.1" --cookie "secret")
Tell exactly which port a node should bind to, so you know which pot to forward (i.e. --erl "-kernel inet_dist_listen_min 9000 -kernel inet_dist_listen_max 9000")
Forward EPMD and Node ports by running heroku ps:forward 9001:4369,9000
Remsh into your node: ERL_EPMD_PORT=9001 iex --cookie "secret" --name console#127.0.0.1 --remsh "myapp#127.0.0.1"
Eventually you should start your server with something like this (if you are still using Mix tool): MIX_ENV=prod elixir --name "myapp#127.0.0.1" --cookie "secret" --erl "-kernel inet_dist_listen_min 9000 -kernel inet_dist_listen_max 9000" -S mix phx.server --no-halt
If you are using Releases, most of the setup has already been done for you by the Elixir team.
To verify that EPMD port has been forwarded correctly, try running epmd -port 9001 -names. The output should be:
epmd: up and running on port 4369 with data:
name myapp#127.0.0.1 at port 9000
You may follow my notes on how I do it for Dockerized releases (there is a bit more hustle): https://paveltyk.medium.com/elixir-remote-shell-to-a-dockerized-release-on-heroku-cc6b1196c6ad

Cannot access sinatra app on AWS Windows from remote machine

I have a simple sinatra app running on an AWS windows instance. Running the application from the localhost works fine (i.e. http://localhost:4567), but I am unable to run it remotely.
My AWS windows instance is available to me from remote as I am able to connect to it using RDP.
After reading some other similar issues, I have already applied the following:
My AWS security group is opened for port 4567 (I actually also opened it for any inbound connection just to see if that will solve the issue - it didn't)
I tried running: ruby my_sinatra_app.rb -o 0.0.0.0
I tried running: ruby my_sinatra_app.rb -e production
I tried adding to the application itself the following code: set :bind, '0.0.0.0'
I am still unable to run the application remotely. Any idea?
I was able to solve my issue, so for the sake of completeness I am publishing the answer.
This wasn't a Sinatra issue, but an AWS issue (maybe not really an issue, more like my misunderstanding). I was under the impression that updating the AWS security group for opening the 4567 port will do the trick.
However, it turns out that I needed also to open the port on the Windows Firewall on my Windows AWS instance. After opening the port on the Windows Firewall I was able to remotely connect to my Sinatra app.

How to control where Meteor runs

I'm installing Meteor (framework) on my AWS EC2 (micro) instance and followed the instructions and after creating a test project I ran meteor on that directory giving me the expected
[[[[[ /var/www/html/meteortest ]]]]]
Running on: http://localhost:3000/
But I can't navigate to my server's localhost in my browser to see the hello world example project. Is there a way I can make meteor work on something like :
http://mydomain.com/meteortest/
or
http://mydomain.com/meteortest:3000
The way that Meteor sets the ROOT URL is by using an environment variable called ROOT_URL:
http://docs.meteor.com/#meteor_absoluteurl
So you could run your Meteor instance like so: ROOT_URL="http://mydomain.com/" meteor --port 80
However, if you want to have the meteor instance served from a folder (like http://mydomain.com/meteortest), you will have to use nginx to forward ports (see Tyr's example) but replace the line:
location / {
with:
location /meteortest {
and change your ROOT_URL appropriately. If you still can't access your domain from outside, you may have not set your security groups properly for EC2. You have to open up port 80. More information on how to do this can be here: http://docs.amazonwebservices.com/AWSEC2/latest/UserGuide/using-network-security.html
You can setup nginx to proxy port 3000 to your domain. Something like:
server {
listen 80;
server_name meteortest.mydomain.com;
access_log /var/log/nginx/meteortest.access.log;
error_log /var/log/nginx/tmeteortest.error.log;
location / {
proxy_pass http://localhost:3000;
include /etc/nginx/proxy_params;
}
}
Please see http://wiki.nginx.org/HttpProxyModule for more information.
However, running meteor on port 3000 is a development environment. If you want to use it in production, please run "meteor bundle", and then follow the README inside the generated tarball.
I think the problem is that port 3000 is likely blocked by amazon's firewall. You could look at opening it up, try Tyr's solution, or try just running meteor with
meteor --port 80
You may need root permissions (i.e. sudo) to do this.
Running directly on port 80 would require root privileges, which you don't really want your web server to run as -- starting it as root and deescalating to a regular user is possible, but not really ideal as well, as you may find that a programming bug at some time forgets to deescalate privs and you will not see any errors from that.
In many cases, I don't really want/need to run a load balancer to use multiple core, especially if I'm runnning on AWS single core t1 or t2 instance types, which I just scale out as I need them -- hence the best advice I have seen is to simply use the Linux kernels ability to do port forwarding, mapping port 80 to port 3000, like this
$ sudo iptables -A PREROUTING -t nat -i eth0 -p tcp \
--dport 80 -j REDIRECT --to-port 3000
Nice and easy and nothing else to do -- and super efficient at the same time as no extra processes are involved in serving the requests.

cannot start sinatra process - eventmachine "no acceptor"

I have a Sinatra app that I run as a daemon, using Apache port-forwarding to mediate between port 80 and port 7655. This has been working fine in the past. Today, not so well. I cannot figure out why.
Problem: sudo ruby my_process.rb returns:
/var/lib/gems/1.9.1/gems/eventmachine-1.0.0/lib/eventmachine.rb:526:in `start_tcp_server': no acceptor (port is in use or requires root privileges) (RuntimeError)
Tried: updating all system packages, updating all gems. No help (except for the more clear error message from eventmachine).
When I run sudo lsof -i :7655 I get nothing back. When I run sudo ps aux I don't see any Ruby processes at all. Which I find highly irregular, given the nature of the error message!
So is there something I'm missing in finding out why the port is unavailable?
Also:
Tried changing ports, nothing. I wonder if it is related to "localhost"? When I ping localhost I get all dropped packets. That doesn't seem normal.
Turns out these two lines in the main Sinatra script provided the most information:
set bind: "localhost"
set port: 7655
The problem was with localhost. The loopback interface was not properly configured. ifconfig showed the lo interface, but it hadn't been assigned the IP 127.0.0.1. To resolve, ran the following commands in the shell (on an Ubuntu Linux system):
ifdown lo
ifup lo
When you close term sometime you forget to stop [CTRL+C] the actual server, just run the following command to kill all ruby process like sinatra, and run-it again
killall ruby
You can see your actual ruby process by running
ps -ef | grep ruby

Resources