Manage custom VM with Laravel Forge

Connecting Laravel Forge to an internal Ubuntu server for server management

Jordon Brill
dotdev

--

I had a legacy php application that I wanted to move to a newer version of php. This application is not built on Laravel but rather is a conglomerate of a bunch of different php scripts and pieces of different frameworks. We recently deployed a Laravel-based application to a server running on AWS via Laravel Forge and Laravel Envoyer and fell in love with the service. We were completely up and running in about 10 minutes and it was great.

This case, however, was a bit outside of the typical scenario since it was not a Laravel application and Forge wasn’t going to be creating the server on one of the built-in services that Forge has an integration with (Linode, DigitalOcean, and AWS). Here is how I connected Laravel Forge to a custom VM running on our internal corporate network.

Building a standard Ubuntu server

I started by downloading a copy of Ubuntu Server 16.04 LTS from www.ubuntu.com/download/server. On our corporate network we run both VMWare and Microsoft Hyper-V as hypervisors and setting up an Ubuntu VM on either of these works fine. You could even do this on a less elegant hypervisor as proof of concept. I installed Ubuntu on a vm and assigned the machine an IP address. I added ssh-server so I could ssh into the machine and then tested the connection locally from another machine on the same network. Without much difficulty, I was able to ssh into the server. Regardless of your setup, what you really need is a copy of Ubuntu Server running as a VM.

Connecting virtual machine to Forge

Once I had my Ubuntu box up and running, I logged into my Forge account and selected Custom VPS. You will need a public IP address so Forge can connect to your server to manage it. In our case, we have a bunch of static IPs assigned to the fiber optic lines that service our building so I chose one that was not yet in use and entered it into Forge as the IP address.

Once Forge is given the necessary information and the appropriate configuration options are selected, click Create Server and it will give you a command to run while ssh’d into the server.

Once the server is created, you will be prompted with a script to run on the server as root. The script will look something like this:

wget -O forge.sh https://forge.laravel.com/servers/SERVER_ID/vps?forge_token=TOKEN_TOKEN_TOKEN_TOKEN_TOKEN; bash forge.sh

At this point, Forge has still not talked to your server. Basically, this is a command that is going to download the provisioning script from Forge’s website into this forge.sh script and then run it through bash. This script enables the magic of Forge — downloading all of the necessary software and setting up the forge user that forge will use to manage the server.

NOTE: You are trusting this script is secure. Blindly running scripts on your server like this is usually not a great idea, however, this is a script customized especially for this purpose and I’m pretty confident Taylor wouldn’t be doing anything malicious through this script so I trust it.

A Gotcha…

Forge needs this to be ran as the root account. I’ve tried it using other accounts without success. However, Ubuntu 16.04 LTS doesn’t come with the root account enabled. To enable the root account, you must setup a password for it and enable it. I would highly recommend disabling the root account once the provisioning has completed.

Back to the deployment…

Once all of the software had installed (took about 10–15 minutes for the script to run, provision the software, and complete its configuration), it was time to see if Forge would connect to my server. Forge gives you a little connection button that you can use to validate it can talk to your machine.

I clicked refresh on the connection and… nothing.

Don’t forget to open SSH ports in firewall…

Earlier when we assigned an IP address to this server, you may have thought about how Forge would access that IP address and how traffic would route to that server. This is where your networking skills will need to come in. I started by pointing the external IP address (for example, 123.45.67.8) to the internal IP address (for example, 10.0.1.50). This tells the firewall to route traffic from the external IP address to the server behind the firewall (our Ubuntu server).

I didn’t want to route just any traffic, however, so I started by just opening up the SSH port (22). Since I didn’t want to open port 22 up to the entire world, I just opened it up to Forge’s two public IP addresses. As of this writing, the IP’s are 45.44.200.205 and 104.236.229.125. I contacted Taylor Otwell (creator of Laravel Forge) directly, and these are the IP’s he gave me.

Once these ports were opened, Forge was able to successfully connect to the machine and properly manage the server. I could issue reboot commands, edit nginx config files, etc. I even had to download and enable some extra php extensions and this was a cinch.

Timing and final thoughts

I would say the provisioning of the server took about 15–20 minutes and then a few more minutes to finalize the firewall rules.

So why would someone want to deploy a server on their own hardware or on a custom VM?

In our case, we needed to setup some Ubuntu servers inside our corporate firewall for a number of internal applications we were building. These applications needed to be behind our firewall without access from external networks, but I didn’t want to manage these servers myself. The idea of a Forge-managed server was exactly what I wanted and the Forge UI handles 99% of anything we would ever need to do on the server.

By connecting Forge to this Ubuntu VM, we were able to accomplish the security requirements of our organization while still having the awesome flexibility of using Forge to provision and manage our server.

--

--

Writer for

Christian, Husband, Father, and Director of Information Systems. I help businesses run efficiently through effective custom technology solutions.