When you're a small team, reliability and efficiency are key parts of keeping the gears turning. We have been using GitHub and Laravel Forge to deploy websites and web applications for a long time. This article is an overview of how you can use both of these tools together to deploy your projects out to your servers.
What is Laravel Forge?
Laravel Forge is a tool that helps you build and manage servers on various hosts (or your own) that's geared towards PHP based applications. That's the shortest answer I can come up with. We could write a whole article on Forge itself but for the purposes of this one, we'll keep it simple. Using Forge, you can create a new server that's primed for PHP based applications (not just Laravel) with a few clicks. At Flywheel we build a lot of sites using Wordpress and Laravel. Forge let's us create and, at a high level, manage VPS servers for these sites without having to get into the command line every time. If you want to read more about Forge you can check out their features page.
It’s an extreme time saver for our team.
Using Git and GitHub for development, staging, and production
We us git and GitHub for all of our code versioning. Again, we could probably write an entire novel on how we use Git and GitHub. The (very) short story is that we're able store and version all of our code so that multiple developers can work together and we keep everything in a manageable place. For every project we'll have a repository and branches within that repo that, when associated with a Forge server, control what code goes where and when.
Here's an example of a project repo
Let's say we're starting a new website for Jeff's Bounce House. Jeff rents out his bounce houses to adults so they can feel like a kid again after they hyper extend their knee while over-estimating their flexibility. We'll create a new repository called
jeffs-bounce-house in GitHub. Here are some tips on creating a new repo.
Branching your repository
Every team will have a different protocol for how they branch their projects. We stick to 3 primary branches.
Master - (auto deploys to production servers) This is the branch that goes out to production. The master branch should only be changed when a change is going to the live, production server.
Staging - (auto deploys to staging servers) This branch is our staging server branch. We'll often push incremental updates out to this branch that goes to a completely different server so that we can show Jeff what we've been working on.
Development - (local development only) The development branch is where (typically) the work gets done. Programmers are committing new code to the development branch regularly.
Again, every team is different and that’s OK.
As the project gets bigger and over time you'll realize that you may need a new branch for a specific feature or a larger change. That's how you should be using Git. Build features and new ideas on their own branch and merge when appropriate to deploy where necessary.
Setting up the server and site for Jeff’s Bounce House
When you create your first server in Forge you'll be able to add a new "site". A site, in Forge terms, is a virtual host for any new code base you want to run that can be associated with a domain name. Forge explains it this way "Think of sites as representing each "domain" on your server.” When creating a site Forge will ask you for details about what domain it should be associated to and some basic details about the site. Next, you'll need to enter where it should pull code from. We’ll use our new repository for
jeffs-bounce-house by entering the repository location and name. Lastly, you'll enter what branch you want to pull code from. In our case, we want the
Deployments on Laravel Forge
Forge comes with a deploy mechanism out of the box. When you click “Deploy” on your site’s application overview forge will run a “Deploy Script” that you are free to edit. What this deploy script does is allows you to write bash commands to deploy a site. Forge will run this as the
forge user on your server. Here’s an example.
git pull origin master
composer install --no-interaction --prefer-dist --optimize-autoloader
In this Deploy Script we are changing directories to the applications root, pulling new code from the
master branch, and then running
composer install with some flags to prevent interactions and optimize the autoloader. With just that we’ve created an easy, one click option to deploy Jeff’s site directly from our master branch in our GitHub repository. Every time you deploy, manually or automatically, Forge will run this script on the server.
Setting up Forge for automatic deployments
We're almost there! At this point you have:
- Created the ‘jeffs-bounce-house’ repository to GitHub
- Created the appropriate branches for the project
- Created and provisioned a new server using Forge
- Created your new site in the server you created.
- Set up your deploy script.
- Now the automation comes in. The easy part.
Now all you have to do is click “Enable Quick Deploy” and Forge will run your deploy script every time a new commit hits your
master branch. Seriously… That’s it.
How automatic deployments work
Forge uses GitHub’s webhooks to enable quick deploy. Any time an event happens on your branch, Forge will know about it and run your deploy script on the server. This means that you can do all of the heavy lifting in your
development branch, merge updates into the
staging branch and finally do a pull request into your
master branch to have it automatically sent out to your production server. No command line necessary.
Auto deployments aren’t for every project
Being able to send out update to the server by committing to a repository is nice… but it’s not perfect for every situation. You’ll still find yourself in the command line for some projects. If you know me, you know I hate the state of front-end build systems in 2018. If you have anything more than a basic build for a project you’ll quickly find your deploy script getting a bit more complicated. User experience may vary. Luckily, forge will let you know via email and through the web interface that the deployment failed.
Auto deployments with Forge, GitHub and Digital Ocean have saved us a ton of time for a lot of projects. Even though it’s not perfect, I would still recommend it as a deployment mechanism.
The programmer in me wants you to know that it’s not perfect for everybody and it’s not perfect for every scenario.
Co-founder & Lead Programmer
Matt is a co-founder, creative director, and programmer at Flywheel. He's made literally tens of people laugh in his lifetime and is always looking for the next problem to solve.