Accessing Homestead From Beyond Your LAN

by Mike Classic on July 7, 2017

Let's learn how to add more network interfaces to your Homestead box.

I wrote this article before I realized that adding more network interfaces to Homestead was already documented. D'oh!

My article goes a little more in depth, so I'll publish anyway.

If you are into Laravel, you've probably used or at least heard of Laravel Homestead. It's a Vagrant box using Ubuntu, pre-configured for Laravel. You remember Vagrant, don't you? That thing that everyone was using before Docker?

I am developing a mobile app that accesses a Laravel codebase via API endpoints. In order to test this mobile app on the go, I wanted to access my dev environment on the go. Of course, I could set up a small dev box on Digital Ocean or something, but I settled on trying to access my local dev environment through NAT and port forwarding, however this was posing problems as it was timing out, unable to connect. Even when my phone was on the same LAN via wireless.

It was easy to access my host IP or even guest IP when accessing the site via my local machine, but still was unable to access it through another device on my LAN. After some troubleshooting, I discovered that by default, Homestead uses two network interfaces through my VirtualBox provider.

Due to how the interfaces are set up by default, I was unable to connect to Homestead from a device other than the local host machine.

Research & Details

Before I present the solution, I'll explain the research I did in case you were interested.

I went into the Homestead repo, and found the file scripts/homestead.rb. Here, I found some code that looked for a networks key in Homestead.yaml.

# Configure Additional Networks
if settings.has_key?("networks")
  settings["networks"].each do |network|
    config.vm.network network["type"], ip: network["ip"], bridge: network["bridge"] ||= nil
  end
end

What this Ruby file is doing in this code snippet is checking to see if Homestead.yaml has a two-dimensional array called networks. If it does, it looks for certain keys in each entry of this array to pull their values and use them as parameters in the actual Vagrant config file that it's building.

Because this is a PHP-centric blog, you are most likely familiar with PHP dev, so let's write an example in PHP.

$networks = [
    [
        'type' => 'public_network',
        'ip' => '192.168.0.99',
        'bridge' => 'Local Area Network Connection'
    ],
    [
        /* ... */
    ],
];

If the network type you choose is public_network, then a third parameter added to that array entry called bridge should be added. The value for this key should be the name of the network adapter which is attached to the network to which this new network interface should belong.

For example, in Windows (gasp!), one might have a network adapter called Local Area Connection. This would mean the bridge value should be "Local Area Connection".

In OS X, one might use a network called en1: Wi-Fi (AirPort).

Solution

From reading the code above, I figured out the structure and parameters that needed to be built in your Homestead.yaml file.

Windows:

networks:
    - type: "public_network"
      ip: "192.168.0.101"
      bridge: "Local Area Connection"

Mac OS X:

networks:
    - type: "public_network"
      ip: "192.168.0.103"
      bridge: "en1: Wi-Fi (AirPort)"

public_network creates a bridged adapter in VirtualBox. This means a virtual network interface attached directly to the LAN physically connected to the host machine. In other words, an interface that directly connects to the host network.

One vagrant up or vagrant reload later, and we should be off to the races.