Allowing Access to Vagrant Instances from the Internet
aka: “how do I use Vagrant with ngrok”
- provides ability to spin up/down local development instances very quickly and consistently.
- the vagrant instances also run configuration management (in this case, Puppet) ensuring that the configuration is production-like
- tunnels ports from the public internet (typically ports 80 and 443) to a given port on your own host, allowing connectivity to development instances from other hosts and devices. An example would be connecting an iOS or Android device to a vagrant instance.
Problem: accessibility, efficiency and consistency
- The developers were running into problems connecting hosts (typically iPhones and Android devices) to their local vagrant development instances
- Although easy to use, ngrok configuration was performed manually and usage wasn’t consistent developer to developer
Solution: vagrant with foodshow plugin
I solved both of these problems using a the vagrant plugin vagrant-foodshow – this vagrant plugin modifies vagrant port forwarding so that the host port also becomes the destination port of an ngrok tunnel. As all of the developers share one vagrant file, this also had the benefit of automating ngrok configuration and ensuring consistency of ngrok use. A screenshot of the results are below:
Solution: the code
The Vagrantfile used to accomplish this below, and has also been checked into my snippets GitHub repository at https://github.com/colinbjohnson/snippets:
vagrantfile_api_version = "2" if Vagrant.has_plugin?('vagrant-foodshow') ngrok_enabled = true else ngrok_enabled = false end Vagrant.configure(vagrantfile_api_version) do |config| config.vm.network "private_network", ip: "192.168.2.2" if ngrok_enabled == true print "Ngrok enabled.\n" config.foodshow.enabled = true # using config.foodshow.subdomain will host your vagrant instance at the # given subdomain - for instance, you could host at my_subdomain.ngrok.com # instead of 94f3bdd.ngrok.com # config.foodshow.subdomain = 'my_subdomain' # config.foodshow.authtoken is required if using config.foodshow.subdomain # add your authtoken below # config.foodshow.authtoken = 'my_authtoken' config.vm.network :forwarded_port, guest: 80, host: 8080, ngrok_proto: "http+https" else $stderr.print "Ngrok not enabled.\n" end config.vm.box = "ubuntu/precise64" end
Two final notes:
- The above configuration exposes your vagrant instance to the public instance. If this is a concern, ngrok supports authentication to protect the destination service.
- My hope is to find time to create a private network shared amongst only the host OS, guest OS and the additional host, if it is an iOS or Android device.