Courses

Laravel Project PROCESS: From Start to Finish

Deploy to Staging Server: AWS and Laravel Forge

Summary of this lesson:
- Setting up AWS and Laravel Forge
- Configuring deployment scripts
- Setting up queue workers
- Preparing staging environment

The final step in this section is to actually show something to the client, so we need to deploy our project somewhere online.

At this point, we don't need a domain name, the goal is to allow the client to see the progress and click around.


Where/How We Will Deploy

We will deploy our project on a new AWS EC2 server instance, created via Laravel Forge.

Why AWS? For this specific course, I chose AWS over Digital Ocean or other providers, because it's the most useful in practice: AWS is a required skill in many Laravel job descriptions, so it would be beneficial for you to learn how to use it.

Why Laravel Forge? This one is debatable, but Forge is one of the fastest way to get from zero to a working server, without ever touching Terminal. If you want to save some money and have more time, you can build a server manually and configure it for Laravel projects, we have a separate course Deploy Laravel Project to AWS EC2: Step-By-Step

Notice: at the time of writing this, Laravel Cloud isn't officially released yet. Maybe will need to rewrite this in 2025.


Deployment: Create Server

To start, you need to create an account on AWS and on Laravel Forge, both will require credit cards. Unfortunately, there's no free option here.

On Laravel Forge, you need to add your AWS credentials, and then press Create Server. Select AWS in the list:

In here, we need to configure our server information: the most important things are:

  • Name: so you would recognize it later in the list
  • Server Size: t3.small is fine, at the moment price is $0.0208/hour, which is around $15/month. You may try a smaller size but with risk that it may not have enough resources.

Press Create Server. Then a Pop-Up will open up with Server Credentials. Save them somewhere safe!

After that, your server should be preparing:

Wait until this process is completed. You'll know as soon as you will see this page:


Creating a (Web)Site from GitHub on New Server

From here, for our testing purposes - we will click on default site and install a Git Repository: we need to fill in the LaravelDaily/linksletter in the Repository input field (beforehand you have to set up GitHub credentials in Laravel Forge) and select dev as a branch.

Once we fill our Repository and select a branch (in our case dev) - we should see it setting up:

Wait until it installs and shows a page like this:

Great, the server is ready and with our code pulled down from GitHub! Every server gets a public IP address automatically, so that will be the URL we will give to client. Without any domains, for now. It's just for testing, at the moment.

Now, we should be able to visit our public IP address and see the Laravel website:

But as if we visit Log In page, we see the error:

So, our project was deployed with errors. We need to modify the default Laravel Forge deployment script.


Forge Deployment Script

Open up Deployments in the sidebar and look for Deployment Script:

Default script looks like this:

cd /home/forge/default
git pull origin $FORGE_SITE_BRANCH
 
$FORGE_COMPOSER install --no-dev --no-interaction --prefer-dist --optimize-autoloader
 
( flock -w 10 9 || exit 1
echo 'Restarting FPM...'; sudo -S service $FORGE_PHP_FPM reload ) 9>/tmp/fpmlock
 
if [ -f artisan ]; then
$FORGE_PHP artisan migrate --force
fi

But it's lacking a lot of things. For example, npm commands. So let's fix that, also adding php artisan down and php artisan up to put the application in maintenance mode while deploying.

cd /home/forge/default
 
if [ -f artisan ]; then
$FORGE_PHP artisan down
fi
 
git pull origin $FORGE_SITE_BRANCH
$FORGE_COMPOSER install --no-dev --no-interaction --prefer-dist --optimize-autoloader
 
npm install
npm run build
 
rm -rf /node_modules
 
if [ -f artisan ]; then
$FORGE_PHP artisan cache:clear
$FORGE_PHP artisan view:clear
$FORGE_PHP artisan route:cache
$FORGE_PHP artisan config:cache
$FORGE_PHP artisan view:cache
fi
 
( flock -w 10 9 || exit 1
echo 'Restarting FPM...'; sudo -S service $FORGE_PHP_FPM reload ) 9>/tmp/fpmlock
 
if [ -f artisan ]; then
$FORGE_PHP artisan migrate --force
$FORGE_PHP artisan up
fi

Once we are done, hit Update and then Deploy Now. This should make another deployment with our new script.

Once it is done - we can try to load the page:

And it works! Because we compiled our assets, there is no more 500 | Server error on our screen.

From here, every time you want to deploy the latest changes from dev branch, you can just go to the Forge page and click "Deploy now". Or, you can even specify that deployment would happen automatically, as soon as you push changes to dev directly or via merged Pull Request.


Queues

The final thing: setting up Queues. Remember, we had a queued Job in our application. This is another thing where Forge can help. So let's setup a Queue worker:

Visit Queue in the sidebar:

Change connection to database since for now we are using the database driver.

Everything else remains the same for our default page. Press Create.

This should load a page that looks like this:

That's our active queue worker!


At this stage, we are done and the application is ready for our development needs. We can send the IP to the client and wait for their feedback!

That's it for the current section of this course so far. We're currently working on the next sections, hoping to release them by mid-December. Come back soon!

Previous: Second "Issues" CRUD: Repeating the Processes
avatar

"Wow, I really like this approach!

That said, as a solo worker, it does add quite a bit of extra effort for me.

However, when sharing it with another developer or the client, it would come across as highly professional."

avatar
You can use Markdown
avatar

Wow, how detailed! Appreciate, and already waiting for the next part! To be honest, the most interesting part for me it was lesson 9. I should really deepen my knowledge in this field :-)

avatar
You can use Markdown
avatar

Hi!

Really thanks for the course, really needed and original at the same time.

I would like to propose two question for following Parts:

1.- Imagine we are talking of a pay web service... how to scale in users? Imagine we have a basic functional version, after probing it with our friends and family, how we start inviting people to use it? maybe first with invitation codes, later every user has some invitation codes to resend other users... and finally completely open the app. It can be interesting to understand how to manage this part, how to control the number of users, the size of the server, the step between "free access to beta testers" to a "paywall"... well... sumarizing: how to scale in profesional way from zero to alpha...

2.- Everythings works perfect. No update or refactor needed... then how often to perform a "composer update"? (maybe it is quite silly question... however I always ask myself...)

avatar

Hi,

  1. This is really a unique workflow that has multiple ways of dealing it. But in short, it's as simple as having a table with invitations and accepting that on the registration form. Of course, with multiple checks to see how many users are already in the system. But in any case, this is really niche and not a very wide-spread requirement, so we won't cover that, sorry. As for "free beta" to paid users - you can simply assign a "free plan" with access to everything to beta users. Then, once live - cancel it.
  2. Running composer update should be done as needed. But that "as needed" is dependant on your time. If you want, you can run it each day (given that you have a good test suite) - that should not cause any issues. Major updates on the other hand can be tricky and should be planned in advance :) But again, no set times on how often. We tend to run minor updates every few months (or sooner if there was a security path) and major updates - when new Laravel versions come out.

ps. For servers - that's a really hard topic to answer. Some applications can run with 5000 daily users on 5$ DO VPS, but others can't handle 50 users on the same VPS. So for the server we recommend you to track it's monitoring and see if there are spikes of load that are near 100%. If that's the case - upgrade the server :)

avatar

Ok, Thanks for the reply, I understood.

avatar
You can use Markdown
avatar

Hi Polivas & Team - As a self-taught, solo, full-stack developer/founder, this course is exactly why I am a Premium member. My site started as bespoke PHP 5 codebase and is now Laravel 11 TALL stack with Livewire 3, deployed through Vapor running on AWS Lambda with GitHub backups using PhpStorm as my IDE, and supports over a thousand users. I’m confident that I’m doing the right things and am equally confident that I’m still NOT doing things right. My ignorance far surpasses my knowledge but trial-and-error has permitted me to build a tool that provides value and depth. I have followed you for many years because of your generous support of the Laravel community and these outstanding courses which simultaneously improve my knowledge-base and provide a constant challenge to level-up my professional skills. Thank you for your consistently great work and I'm looking forward to the release of the next two modules!

😍 2
avatar

Hi! Thank you for the kind words!

It is often that we have to do "trial and error" approach to many things, but that's the way to learn! And that's why we love spreading our trials (and sometimes errors :) ).

ps. Impressive update from php 5 to the latest stuff!

avatar

Aww, thank you for the nice words, glad to be a part of your journey!

avatar
You can use Markdown
avatar
You can use Markdown