Skip to content

Expose Localhost Websites Publicly with ngrok

If you’re doing any web development work, I hope you have a local development environment running on your computer, and that you aren’t FTP’ing your code to the server and then loading the page each time to see if your change works. (I’ve seen people do this, it’s painful, and slow).  If you don’t have a local development environment setup, there are lots of options.  WordPress developers, check out DesktopServer, VVV, or Local by Flywheel as great options for getting up and running with a local development environment quickly.

When working with local development environments, you can typically only access your sites from localhost (your computer).  Accessing your sites from another computer on the same network, or from elsewhere not the Internet, is not possible.

There are many reasons you may want to do get temporary access to your local environment from the outside. I say temporary because your computer should not be used as a web server for many reasons including performance and security.  In my experience temporary local access is handy mostly for testing scenarios, such as:

  • Testing your sites from mobile devices
  • Testing your REST API endpoints from a remote application
  • Checking your code with an online validator like the W3C Validator (HTML) or Tenon.io (Accessibility)

So, how do we accomplish this?

Meet ngrok

ngrok (download ngrok here) is a utility that creates a secure tunnel between your localhost and the outside world.  It is available for Mac, Windows and Linux. Once you have it installed, you can easily open a tunnel from the command line.  

A simple HTTP tunnel w/ host name header

I use DesktopServer for most of my WordPress development.  If I was on my laptop, I’d access my sites a domain like example.dev.  To open a tunnel to this domain, I’d request an HTTP tunnel on port 80 with the host header for example.dev:

./ngrok http -host-header=example.dev 80

which would show you something like:

Screenshot of ngrok running in Terminal

What this means is that you can now access your site by going to http://968f7806.ngrok.io and https://968f7806.ngrok.io. Every time you launch ngrok, you’ll receive a different random address like this one. If you want to use custom hostnames, you need to purchase their Business or Pro plans.

Relaying REST Requests

While ngrok is running, you can go to http://localhost:4040 to see a web-based GUI of all the activity passing through your tunnel.

Screenshot of ngrok's web inspector GUI

You can see all the requests made through the tunnel. Even better, you can replay requests! This means that if, for example, you made a POST request to your REST API endpoint from a mobile app to your tunnel address, and something went wrong, you could adjust your code locally, and the push the identical request to the endpoint again by clicking on the “replay” button in the web GUI for that request. Handy!

Other Features

ngrok can do many other things, including allowing you to password protect your tunnel, setting up TLS certificates, forwarding wildcard domains, specifying with region (defaults to the USA) that the tunnels runs through, and more.

A Note on WordPress Development Sites with ngrok

UPDATE: If you’re using ngrok with WordPress, and you want your images, stylesheets, scripts, etc. to load properly, and to be able to navigate between pages, you’ll need to install an additional plugin so that it converts all your URLs to relative paths. There are two plugins that appear to do this, https://github.com/optimizamx/odt-relative-urls (thanks Robert Gillmer for pointing this out) and Relative URL

4 Comments

  1. The suggested plugin makes an additional request using file_get_contents!
    Not cool.

    There’s a better idea. Put this in your wp-config.php

    ob_start( ‘s_localhost_192’ );
    function s_localhost_192( $string ) {
    return str_replace( ‘http://localhost/’, ‘http://968f7806.ngrok.io/’, $string );
    }

    credit: https://core.trac.wordpress.org/ticket/17048

    I had a more complicated code I have used in the past but can’t find it now.

    • Slavi,

      The reason I wouldn’t do it that was is that the hostname you get for ngrok changes every time you launch it (unless you pay for a custom hostname with them). You’d constantly be changing that code to match. The extra file_get_contents() request isn’t great, but then again, you’re not using this in production, so it isn’t a huge deal.

  2. Have you looked at all at the new ngrok features in Vagrant 1.9.2?

    • Hey Chris – I haven’t looked into Vagrant 1.9.2 yet. I find at the moment I’m only loading Vagrant if I’m working on core with VVV. Most of my projects are in Docker containers right now. I’ll have to check it out though. Thanks!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.