Making Ngrok Work With Pow and Apache (Exposing Localhost Domains to the Internet)
OK. I am really happy with my recent endeavour to try out Pow
and making it work alongside Apache. What this means is that, on my macbook pro,
I can simply run
powder link inside a rack-based application, and then, use
http://<appname>.dev to connect to this application. For legacy (non-rack)
based application, I can simply create a directory in a specificied location,
and that directory will be served by Apache at:
for this implementation/workflow can be found in this post.
Now, this works really nicely. But, I wanted a way to access these sites easily on the public internet, lets say, to showcase the current work to a client, etc. This is where ngrok comes in. It allows us to establish a tunnel that forwards a port on our machine and make it available on the public internet. This post walks through the steps I took to make it play nicely and really smoothly with Apache and Pow.
ngrok is pretty easy. We need to download a zip file, unzip it and
move the executable inside it to a directory in our
$PATH. Assuming that
/usr/local/bin is in our
$PATH, we can do something like this:
1 2 3 4 5
ngrok is ready to serve our localhost on the public internet. Running:
ngrok 80 should provide us with a unique URL, which we can access to view our
localhost site, i.e.
I wanted to view my Pow based domains over the internet, and this is fairly easy to do. With our current Pow setup, it is still easier.
If you have reached this post while searching to make ngrok work with apache or pow, please read that article, before you proceed further. Instructions in this post assume that Pow and Apache are setup in a particular manner, and may not work in your case.
Alright, we need to reinstall Pow to let it know what mischief we are upto.
We can run the following commands to uninstall Pow, add an environment variable
to our Pow configuration file, and then, reinstall Pow. This particular
environment variable tells Pow to resolve DNS for
*.ngrok.com on our local
machine, but not serve them.
1 2 3
That is all we need to make Pow serve our local Pow site, e.g.
the internet, provided this application is being forwarded on
hostname. In order to achieve this, we can run
ngrok, like this:
Note that, as per our current Pow configuration, Pow is running on port 88, and
that is what we need to specify here. Great. So, we can now access our local
myapp.dev Pow based site on the internet by visiting
ngrok allows us to expose our Apache
VirtualHost domains over
the internet by adding the public hostname of the application as a
inside the appropriate
In my case, I am using the following
VirtualHost directive (which allows me
to simply create a directory named
myapp inside the path specified by the
VirtualDocumentRoot, and access it on
1 2 3 4 5
ngrok to serve all
*.lab local sites on the internet. Therefore, we
ServerAlias with the value
*.lab.ngrok.com to this
This works because, when a request to
*.lab.ngrok.com is made on the internet,
ngrok will forward it to our machine, which will read the hostname to be
*.lab.ngrok.com, which is where Apache kicks in and tries to serve it, using
the above directive. Nice, and simple :)
So, our directive should look like this, now:
1 2 3 4 5
To make this all work, we need
ngrok to serve the site correctly. Assuming
that we want to access
myapp.lab, we will need to issue a command like this:
Voila, we can now access our Apache
VirtualHost domains on the internet, as
To sum it up, with the above changes, and the following sites that work on our local machine:
my-pow-app.dev: pow based application
my-apache-app.lab: apache based application
We can issue the following two commands (in separate tabs):
1 2 3 4 5
Further Improvement to Workflow
I created this handly little shell snippet to easily serve up a local domain on
the internet using
ngrok (and, optionally, with HTTP Basic Authentication):
1 2 3 4 5 6 7 8 9 10 11 12 13 14
I am pretty sure that the above function can be further improved, but it works. It empowers me to issue a simplified command to serve any local domain.
To best realize the power of this little snippet, we need to add the following one-line functions (after the above function) in our shell configuration:
Now, to serve up a Pow based site, e.g.
myapp.dev, we can simply run:
And, to serve up an Apache based site, e.g.
myapp.lab, we can simply run:
Not only that, we can, also, add HTTP Basic Authentication while serving up a local site, by simply passing two more parameters for username and password, like this:
Now, when we visit
http://myapp.lab.ngrok.com, we will be greeted with a HTTP
Basic Authentication before we are allowed accessed to our local site.
Nice and really useful :)