Using Laravel Forge to Setup an AWS Server

I recently had the need to show a demo of a quick Laravel site I’m creating for a client and wanted to use Forge to provision a server on AWS. I personally use Linode to host a few older Wordpress & CakePHP sites and other Laravel sites I’ve worked on have been maintained by other agencies & developers so wanting to learn something new I gave Forge a whirl.

Signing Up

Creating an account was super simple, I opted for the $10/month plan. Everything comes with a 5 day free trial so you can have a play for free. Next I connected my AWS account using a public & secret key pair. (best to create a new IAM user specifically for Forge so that it has it’s own keys — more info here — or quickly generate a new root key if you’re testing everything. But please go back and read up on IAM users when you’ve time as using the root keys is considered bad practice)

I also connected my Github & Bitbucket accounts, the demo I wanted to show was in a private Bitbucket account so I did that first but if you have projects on Github connect that too or whichever you use.

Creating a New Server

I went for the smallest & cheapest possible server which turns out to be a t2.micro. I figured that it should be enough to power the smallest of demo projects and as I was only testing I didn’t want to waste cash (as I’m tight!).

If in the future you wanted to beef up the server, the awesomeness of AWS will allow you to simply stop the instance in the console, change the instance type to a t2.small/medium/large for example, then start it back up to benefit from the bigger server.

For simplicity I didn’t want a load balancer, happy with the default install of PHP 7 and I un-ticked the option to install MariaDB as I’ll be using MySQL.

Once you hit create Forge will bound off to create the server in AWS, took around 5 min in total to do everything. You’ll get feedback on Forge and also if you poke around the AWS console you’ll see the instance being created along with the attached Elastic Block Store.

You’ll be given an IP address of the new server and if you visit it all being well you’ll see the output of phpinfo() on your shiny new server!

Setting up the Project

The new server comes with a default site, which is currently the phpinfo page. I simply replaced that with my Bitbucket project by editing the site and installing the repository. Enter in the repository name, which branch, I ticked “Install Composer Dependencies” and finally clicked install.

Minor Hiccup

Here I hit my first snag in the server alerts section at the top of the page, I was getting a We were unable to install a project on your server error and looking into the details this cropped up when installing the dependencies via Composer:

HP Fatal error:  Uncaught ErrorException: proc_open(): fork failed - Cannot allocate memory in phar:///usr/local/bin/composer/vendor/symfony/console/Application.php:954

Luckily it also gave a link to additional info:

https://getcomposer.org/doc/articles/troubleshooting.md#proc-open-fork-failed-errors

As I had selected the cheapest server option it was running out of memory and Composer was failing. The server also didn’t have swap memory configured so when it ran out, it balked and fell over. In order to configure that you need to SSH into the AWS instance and do it manually. There’s a section in the FAQ on how to connect via SSH. Once done I ran the following commands to add the swap file:

/bin/dd if=/dev/zero of=/var/swap.1 bs=1M count=1024
/sbin/mkswap /var/swap.1
/sbin/swapon /var/swap.1

To check that everything’s OK hit the Deploy Now button and you **should** have things working as expected. Double check by viewing the latest deploy log.

Environment Variables

Next you need to edit the .env file (which currently doesn’t exist), click on the Environment tab then on Edit Environment button. It’ll be blank so copy the .env.example file contents from your local Laravel project and paste it in. I updated the APP_URL with the IP address of the EC2 instance and the database details that got emailed to me into DB_USERNAME, DB_PASSWORD & DB_DATABASE. Finally I had to generate a new APP_KEY by using the following artisan command when connected to the server via SSH:

php artisan key:generate

Quick Deploy

Under site details I enabled Quick Deploy so that when I committed a new change the site automatically gets updated on the EC2 server which is super handy. You can take a look at the deploy script via the Edit button and change it to suit your needs e.g. remove the migrate command or add something specific to your project. I left it as is.

Success

I mainly wrote this as a guide for future me and if you’ve been following along hopefully you have everything setup & working. AWS imo has a really steep learning curve and Forge is a nice, easy way to get a server up & running quickly — which is exactly what it sets out to achieve.

Future Changes

MySQL is a hungry memory monster, you can help reduce it by changing things but instead I would disable it on the server all together and use AWS RDS which offers a cheap MySQL option with automated backups and multi-zone fallback right off the bat. I’ll probably quickly document how todo that in a follow up post. (Edit: I went ahead and did that here)

Other Resources