Hooking up into running heroku phoenix application - heroku

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

Related

Unable to get Mesos to run from tutorial: Setting up a Single Node Mesosphere Cluster

I have been following this tutorial to try and setup a single node mesosphere cluster from their
official tutorial:
http://mesosphere.com/docs/getting-started/developer/single-node-install/
I followed all the commands without any issues, and I also added the ports 5050 and 8080 to my security group. When I try to access the console for mesos/marathon, I get a "Internet Explorer cannot display the webpage" message.
They also recommend checking it the following way:
MASTER=$(mesos-resolve `cat /etc/mesos/zk`)
mesos-execute --master=$MASTER --name="cluster-test" --command="sleep 5"
But that comes up with an error:
WARNING: Logging before InitGoogleLogging() is written to STDERR
F0106 17:03:08.126703 20993 process.cpp:1561] Failed to initialize, gethostbyname2: Unknown host
*** Check failure stack trace: ***
I am not really sure how to troubleshoot this either, and there are not many tutorials I could find on how to install mesos on ubuntu.
I checked the contents of the zk file, seems to be the default value.
$ cat /etc/mesos/zk
zk://localhost:2181/mesos
I would really appreciate any clues on how to go about this one.
Edit: The process is definitely running too - just an fyi:
root 31545 8.5 5.9 187464 35604 ? Ssl 17:28 0:00 /usr/local/sbin/mesos-slave --master=zk://localhost:2181/mesos --log_dir=/var/log/mesos
root 31563 28.5 2.1 116304 12856 ? Rs 17:28 0:00 /usr/local/sbin/mesos-master --zk=zk://localhost:2181/mesos --port=5050 --log_dir=/var/log/mesos --quorum=1 --wo
Mesos uses gethostbyname2 to resolve hostnames to IPs. The first thing I would recommend, is to try "ping localhost" and "ping hostname", and verify that there are no strange settings in /etc/hosts. If you're doing a multi-node cluster, I'd recommend that hostname map to the public IP address (not 127.0.x.1).
If that doesn't help, you can try setting the --ip and --hostname flags when starting mesos-master and mesos-slave, to bypass the gethostbyname2 resolution. These can also be set by writing to the file-based parameters, e.g. /etc/mesos/mesos-master/ip
For additional troubleshooting, try running wget http://localhost:5050 (or curl -L) from the mesos master, to verify that it is locally visible. Also try wget http://<public_ip>:5050 to verify that the web server is up and serving to the public IP. Depending on how your (EC2?) node is setup, you may need to expose/forward the port, or connect to a VPN.
Thanks Adam. I ran the wget and curl commands, and nothing was actually listening on port 8080 or 5050. I did open those ports in the ec2. A simple reboot did the trick however, once I ssh'ed into the ec2 instance after the reboot, both mesos and marathon were running and both ports are now showing after I ran
netstat -ntln.

Can't access sinatra server from other computers

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

How do I start debugging a Sinatra app in production?

I have a simple Sinatra app. It takes a URL via a POST request, processes that URL and returns a code.
It works fine on my local machine through a Curl call:
curl --data-urlencode "path=PATH_HERE" localhost:4567/process
And it returns a JSON response.
However, once it's on production (EC2) I do a similar POST request:
curl --insecure --data-urlencode "path=PATH_HERE" https://faxattach.staging.myaidin.com/process
However, it doesn't return anything. The traffic is definitely going to the EC2 machine, which tcpdump confirms, but I'm not sure if it's actually hitting the Sinatra app.
How would I check if it is hitting the Sinatra app? The log files remain unchanged, checked using tail -f. And, if it's not hitting the app, how would I start investigating the reason?
Probably the problem is the port. By default HTTP requests go to port 80. You can run your app on that port to fix the problem with:
rackup -p 80
Your need to change the security policy and allow traffic to port 4567.
Or, as #ismael has suggested, you can run the Rack server on port 80. This would require root privileges and you might need to use sudo rackup -p 80 or rvmsudo rackup -p 80.

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.

Installing Membase from source

I am trying to build and install membase from source tarball. The steps I followed are:
Un-archive the tar membase-server_src-1.7.1.1.tar.gz
Issue make (from within the untarred folder)
Once done, I enter into directory install/bin and invoke the script membase-server.
This starts up the server with a message:
The maximum number of open files for the membase user is set too low.
It must be at least 10240. Normally this can be increased by adding
the following lines to /etc/security/limits.conf:
Tried updating limits.conf as suggested, but no luck it continues to pop up the same message and continues booting
Given that the server is started I tried accessing memcached over port 11211, but I get a connection refused message. Then figured out (netstat) that memcached is listening to 11210 and tried telneting to port 11210, unfortunately the connection is closed as soon as I issue the following commands
stats
set myvar 0 0 5
Note: I am not getting any output from the commands above {Yes: stats did not show anything but still I issued set.}
Could somebody help me build and install membase from source? Also why is memcached listening to 11210 instead of 11211?
It would be great if somebody could also give me a step-by-step guide which I can follow to build from source from Git repository (I have not used autoconf earlier).
P.S: I have tried installing from binaries (debian package) on the same machines and I am able to successfully install and telnet. Hence not sure why is build from source not working.
You can increase the number of file descriptors on your machine by using the ulimit command. Try doing (you might need to use sudo as well):
ulimit -n 10240
I personally have this set in my .bash_rc so that whenever I start my terminal it is always set for me.
Also, memcached listens on port 11210 by default for Membase. This is done because Moxi, the memcached proxy server, listens on port 11211. I'm also pretty sure that the memcached version used for Membase only listens for the binary protocol so you won't be able to successfully telnet to 11210 and have commands work correctly. Telneting to 11211 (moxi) should work though.

Resources