Deploying Laravel Apps to AWS Elastic Beanstalk
Tags: php
Published: 2022-02-24 18:53:08

*This article was originally written by [Samson Omojola](https://www.honeybadger.io/blog/laravel-php-elastic-beanstalk/#authorDetails) on the [Honeybadger Developer Blog](https://www.honeybadger.io/blog/laravel-php-elastic-beanstalk/).*

In this article, we will go through the process of setting up an Elastic Beanstalk Environment, creating a new Laravel application, deploying the application to your Elastic Beanstalk Environment, and setting up a database for it.

## Prerequisites

To follow this guide, you should have the following:

- PHP, MySQL, and Apache installed on your computer. Xampp comes with all these, so if you don’t have them already, you can install [Xampp](https://www.apachefriends.org/download.html).
- [Laravel](https://laravel.com/docs/8.x) installed
- [Composer](https://getcomposer.org/doc/00-intro.md) installed

## Step 1 - Creating the Laravel Application to Be Deployed

Let’s create a new Laravel application with composer:

```bash
composer create-project --prefer-dist laravel/laravel appName
```

(‘appName’ should be changed to whatever you wish to name your app)

Next, navigate to the app’s directory:

```bash
cd appName
```

New Laravel applications always come with some boilerplate code, a skeleton app that you can build upon. Since this tutorial is focused on deployment, we won’t be making any changes to this app. To take a quick look at it, run php artisan serve and navigate to [http://localhost:8000](http://localhost:8000) in your browser.

We will be uploading our application to AWS as a zipped file, so navigate to your project directory and compress all the files and folders in it into one zipped file. You do not need to include your vendor folder since it is probably quite heavy and is not required for setup.

## Step 2 - Creating an Elastic Beanstalk Environment

To make use of Elastic Beanstalk (and other AWS services), you need to first [create an AWS account](https://portal.aws.amazon.com/billing/signup#/start).

![Sign up for AWS](https://www.honeybadger.io/images/blog/posts/laravel-php-elastic-beanstalk/Screenshot170.png)
_Sign up for AWS_

After signing up, you’ll be redirected to the AWS console, where all AWS services are listed. Select Elastic Beanstalk from the list of options.

![List of AWS services](https://www.honeybadger.io/images/blog/posts/laravel-php-elastic-beanstalk/Screenshot171.png)
_List of AWS services_

Next, click on the Create Application button.

![Create Application](https://www.honeybadger.io/images/blog/posts/laravel-php-elastic-beanstalk/Screenshot172.png)
_Create Application_

You’ll be redirected to a form on which you will supply the details of your application. The application name can be whatever you want.

![Form for Application](https://www.honeybadger.io/images/blog/posts/laravel-php-elastic-beanstalk/Screenshot174.png)
_Form for Application_

Tags help you categorize your applications, which is especially helpful if you have a lot of applications on Elastic Beanstalk. They usually provide useful information about the application you are trying to deploy, such as whether it’s for development or production. You can add as many as 50 tags.

From the dropdown list for **Platform**, select PHP.

Under the **Application Code** section, select **Upload your code**.

Under **Source code origin**, select **Local file** and click on **Choose file**.

## Step 3 - Deploying Your Application

Once the Zip file has been uploaded successfully, click on the **Create Application** button at the bottom of the page to deploy your application.

![Upload Zip file](https://www.honeybadger.io/images/blog/posts/laravel-php-elastic-beanstalk/Screenshot175.png)
_Upload Zip file_

The setup will take a few minutes to complete.

Once complete, you’ll be redirected to a dashboard with some details about your application. To run your deployed app, click on the URL on the top-left side of the dashboard. It should look something like this:

`Test2-env.eba-znpzdznf.us-east-2.elasticbeanstalk.com`

![Application Dashboard](https://www.honeybadger.io/images/blog/posts/laravel-php-elastic-beanstalk/Screenshot176.png)
_Application Dashboard_

When the page loads, you should get a 403 error saying you do not have permission to access the server.

![403 Forbidden Error](https://www.honeybadger.io/images/blog/posts/laravel-php-elastic-beanstalk/Screenshot177.png)
_403 Forbidden Error_

This is because, by default, Elastic Beanstalk searches for the starting point of your application in the root directory of your project. Since Laravel keeps this file (index.php) inside the public folder in your root directory, we will need to point Elastic Beanstalk to the right directory. To confirm that index.php is really inside the public folder, add `/public` to the URL of your deployed app. The URL to run on your browser now should look something like this:

`Test2-env.eba-znpzdznf.us-east-2.elasticbeanstalk.com/public`

![Running application from public folder](https://www.honeybadger.io/images/blog/posts/laravel-php-elastic-beanstalk/Screenshot178.png)
_Running application from public folder_

We can make the application load from the root directory. On the left navigation pane, click on **Configuration**. To the left side of the **Software** category, click the **Edit** button. Scroll down to **Document root**, enter "/public" into the textbox, and click **Apply**. Now if you run the URL of the root directory, you should see your deployed app.

## Step 4 - Adding an RDS Database Instance to Your Environment

To add a database to your application, navigate to the left pane of your application dashboard and click on **Configuration**, scroll down to **database**, and click on the **Edit** button.

![Create an RDS Database Instance](https://www.honeybadger.io/images/blog/posts/laravel-php-elastic-beanstalk/Screenshot180.png)
_Create an RDS Database Instance_

You’ll be taken to a page requesting some information about the database you are trying to create. By default, the values for **Engine**, **Instance class**, and **Availability** should be **mysql**, **db.t2.micro**, and **Low (one AZ)**, respectively. You can leave these values as they are. A username and password will be required for accessing the database. You can use any details you prefer. Under **Retention**, there are two options. The **Create Snapshot** option will save a snapshot of your database when you terminate your environment, and you will incur some charges for this. Select **Delete** to avoid being charged. Finally, click **Apply** to proceed with the setup.

![Set up a new database](https://www.honeybadger.io/images/blog/posts/laravel-php-elastic-beanstalk/Screenshot179.png)
_Set up a new database_

It will take a couple of minutes to set up. To view the database, go to the left navigation pane and click on **Configuration**. On the Configuration page, scroll down to **database** and click on the endpoint link.

![The RDS Database](https://www.honeybadger.io/images/blog/posts/laravel-php-elastic-beanstalk/Screenshot181.png)
_The RDS Database_

Now that we have our database set up, we need to connect it to our application. We’ll do this by adding environment variables from Elastic Beanstalk to the source code of our application.

In the root directory of your Laravel project, locate your **config** folder, navigate to it and open the file named **database.php**. This is where Laravel searches for the details of the database it will use. Scroll down to the **mysql** section and update it with the database details from Elastic Beanstalk.

When you create a database instance in Elastic Beanstalk, it creates these credentials and automatically saves them in the following variables:

```RDS_HOSTNAME: Your database endpoint (e.g., aa1i0kb7mgpszyv.ctvm5tbj0wtl.us-east-2.rds.amazonaws.com:3306)
RDS_PORT: 3306
RDS_DB_NAME: ebdb
RDS_USERNAME: Whatever you supplied when creating the database.
RDS_PASSWORD: Whatever you supplied when creating the database.
```

After adding the above variables to your **database.php** file, it should look like this:

```php
...
    'connections' => [

        'sqlite' => [
            'driver' => 'sqlite',
            'database' => env('DB_DATABASE', database_path('database.sqlite')),
            'prefix' => '',
        ],

        'mysql' => [
            'driver' => 'mysql',
            'host' => env('RDS_HOSTNAME', '127.0.0.1'),
            'port' => env('RDS_PORT', '3306'),
            'database' => env('RDS_DB_NAME', 'forge'),
            'username' => env('RDS_USERNAME', 'forge'),
            'password' => env('RDS_PASSWORD', ''),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'strict' => true,
            'engine' => null,
        ],
...
```

Our application and our database are now connected.

## Step 5 – Updating Your Application

Now that we’ve made some changes to our code, this is the perfect time to address how to update our application on Elastic Beanstalk. During development, you’ll often want to replace what you have on Elastic Beanstalk with the latest source code so that you can test the updates you’ve made.
To update your application, zip the latest source code just like last time and head to your application dashboard. On the left navigation pane, click on **Environments** and select your app’s environment from the list. Next, click on the **Upload and deploy** button in the middle of the page.
Click on **Choose file** and upload the zipped file of your latest source code. Under **Version label**, you can add a version to help you keep track (e.g., version 2).
Finally, click on **Deploy** to update your application.

![Upload and deploy your application](https://www.honeybadger.io/images/blog/posts/laravel-php-elastic-beanstalk/Screenshot182.png)
_Upload and deploy your application_

Once it’s done, refresh the page to load the updated version with your database details.

## Automated Deployment

Manually pushing your code to production every time you make a change can become monotonous and time consuming. For most companies, every second counts, and this (grossly inefficient) manual method can increase operational costs. Thankfully, with continuous deployment, code changes can be pushed to production automatically, making the process of releasing software faster and more efficient, saving companies lots of time and money.

There are several ways to implement continuous deployment, one of which I’ll show you below.

Here are the tools you’ll need:

[AWS CodeCommit](https://aws.amazon.com/codecommit/) will provide the repository for storing our Laravel code.

[AWS CodePipeline](https://aws.amazon.com/codepipeline/)provides the pipeline through which changes in your Laravel code are automatically pushed to production (from the repository on CodeCommit to Elastic Beanstalk).

In other words, AWS CodePipeline detects changes in your AWS CodeCommit repository automatically and updates your live app in Elastic Beanstalk.

We can connect the Elastic Beanstalk environment we created above to our pipeline so that subsequent changes to our code can be deployed there.

## Step 1 – Hosting Our Code on AWS CodeCommit

First, let’s host the code to be connected to our pipeline on AWS CodeCommit (Github and Amazon S3 can also be used with AWS CodePipeline). Open the [AWS CodeCommit dashboard](https://console.aws.amazon.com/codecommit).

Click on **Create Repository**. The repository name can be whatever you want. I’ll name mine **LaravelRepo**. Click on **Create**.

Next, let’s add our code to the new repository. Click on the **SSH tab** (ensure that you are logged in as an IAM user).
![Click on the SSH tab](https://www.honeybadger.io/images/blog/posts/laravel-php-elastic-beanstalk/Screenshot197.png)
_Click on the SSH tab_

Select your operating system from the options and follow the instructions for cloning the repository you just created.
The instructions for the different operating systems are similar to each other and easy to follow. I’m on a Windows system, so I’ll outline the process for Windows below.
If you don’t already have an SSH key, you’ll need to follow steps 1 through 3.

We want to set up an SSH connection between our system and AWS CodeCommit. It will allow us push code from the former to the latter.

Fire up Git Bash and run the following command:

```bash
ssh-keygen
```

You’ll be prompted to enter the name of the file in which you want to save the key (any name will do just fine). This file will be created for you.

You’ll need to create a new password (or passphrase). Note that because of the sensitive nature of passwords, it doesn’t show up in the terminal as you type on your keyboard.

Two files are created in your **drive/Users/user-name/.ssh/** directory with the name you provided earlier: a private key file and public key file with a **.pub** extension.

Open the .pub file in a text editor and copy its contents.

Next, open [your IAM dashboard](https://console.aws.amazon.com/iam/), navigate to the pane on the left side, and click on **Users**.

You’ll be shown a list of users you’ve created. Select your IAM user from the list.
![Select your IAM user from the list](https://www.honeybadger.io/images/blog/posts/laravel-php-elastic-beanstalk/Screenshot198.png)
_Select your IAM user from the list_

Select the **Security Credentials** tab and click on the **Upload SSH public key** button.
![Select the Security Credentials tab](https://www.honeybadger.io/images/blog/posts/laravel-php-elastic-beanstalk/Screenshot199.png)
_Select the Security Credentials tab_

![Upload SSH public key](https://www.honeybadger.io/images/blog/posts/laravel-php-elastic-beanstalk/Screenshot201.png)
_Upload SSH public key_

Paste the key you copied earlier into the text box and click on **Upload**.

Now we need to create a config file on our system to help us connect to AWS CodeCommit. We’ll be adding our SSH Key ID to this file, so be sure to copy it to the page you are currently on.

Open `~/.ssh/config` in your test editor and add lines like these:

```bash
Host git-codecommit.*.amazonaws.com
  User APKAEIBAERJR2EXAMPLE
  IdentityFile ~/.ssh/laravel_codecommit
```

Replace the value of **User** above with the SSH key ID that you copied and change **laravel_codecommit** to the name of the file holding your private key.

Name the file **config** and save it without an extension. On Windows, you can save a file without an extension by wrapping its name with double quotes before clicking on Save.

You can test the configuration you just created by running the following command:

```bash
ssh git-codecommit.us-east-2.amazonaws.com
```

When prompted to confirm the connection, simply respond with **yes**.

### Pushing Local Code to the Remote Repository

Right now, our Laravel code is on our local environment, so we need to add the URL of our CodeCommit repository to our code and push.

To get the URL of your CodeCommit repository, open [your CodeCommit dashboard](https://console.aws.amazon.com/codesuite/codecommit/home) and select the Laravel repository from the list displayed. Under **Clone URL**, select the SSH option.
![Under Clone URL, select the SSH option](https://www.honeybadger.io/images/blog/posts/laravel-php-elastic-beanstalk/Screenshot202.png)
_Under Clone URL, select the SSH option_

Now that you have the SSH URL, you can add it to your local repo by opening Git Bash in the directory where your code files are located. Next, run `git remote add origin` and paste the SSH URL you just copied. The command should look like this:

```bash
git remote add origin ssh://git-codecommit.us-east-2.amazonaws.com/v1/repos/LaravelRepo
```

Next, add the project files to the repository:

```bash
git add .
```

Commit:

```bash
git commit -m “initial commit”
```

And finally, push:

```bash
git push origin master
```

## Step 2 – Creating Your Pipeline

As mentioned earlier, CodePipeline will connect our CodeCommit repository with our Elastic Beanstalk (deployment) environment.

Open the [CodePipeline console](http://console.aws.amazon.com/codepipeline).

Click on **Create Pipeline**.
![Create Pipeline](https://www.honeybadger.io/images/blog/posts/laravel-php-elastic-beanstalk/Screenshot203.png)
_Create Pipeline_

If you are making use of CodePipeline for the first time, you’ll be shown an introductory page. Click on **Get Started**.

Under **Pipeline Settings**, give your new pipeline a name. I’ll name mine **LaravelPipeline**.
![Pipeline Settings](https://www.honeybadger.io/images/blog/posts/laravel-php-elastic-beanstalk/Screenshot204.png)
_Pipeline Settings_

If you do not have an existing service role, you can select the option to create a new one. Give the new service role a name and check the box asking you to allow CodePipeline to create a new service role.

To proceed with your setup, click on **Next**.

The **Add Source** page is where we point AWS CodePipeline to the source repository we created earlier.
![Add Source](https://www.honeybadger.io/images/blog/posts/laravel-php-elastic-beanstalk/Screenshot205.png)
_Add Source_

Click the dropdown list for **Source provider** and select AWS Code Commit.

Under **Repository name**, select the name of the repository you created for your Laravel project.

Under **Branch name**, select **master**.

Amazon CloudWatch Events is the recommended option to help you detect code changes to your source code and start your pipeline, so you can leave this option selected.

**Output artifact format** is the format in which CodePipeline outputs your project for deployment. You can leave the default selected option as it is.

Click **Next** to proceed to the next stage.

The other two steps are optional. You only have to pick one. We can skip the build step and proceed to setting up the deployment process. Click on **Skip build stage**.
![Skip build stage](https://www.honeybadger.io/images/blog/posts/laravel-php-elastic-beanstalk/Screenshot207.png)
_Skip build stage_

On the deployment stage page, select AWS Elastic Beanstalk from the **Deploy provider** dropdown.
![Add deploy stage](https://www.honeybadger.io/images/blog/posts/laravel-php-elastic-beanstalk/Screenshot208.png)
_Add deploy stage_

Under **Region**, select the appropriate option for your AWS services.

Next, select the name of the AWS Elastic Beanstalk application that you created earlier.

Finally, select the name of the environment you created for your AWS Elastic Beanstalk application.

Click on the **Next** button to proceed.

On the Review page, go through the details and ensure that they are all correct. If you’d like to change something, you can click on **Previous**. If not, click on **Create pipeline** to finalize the process.
![Review page](https://www.honeybadger.io/images/blog/posts/laravel-php-elastic-beanstalk/Screenshot209.png)
_Review page_

At this point, your pipeline moves through the stages you created, and your app eventually gets deployed.
![Success](https://www.honeybadger.io/images/blog/posts/laravel-php-elastic-beanstalk/Screenshot210.png)
_Success_

The URL that points to the website you just deployed can be found on your AWS Elastic Beanstalk dashboard.

Navigate to the pane on the left and click on **Environments**. Select the environment you added to your pipeline. The URL should look something like this:

```bash
Test3-env.eba-znpzdznf.us-east-2.elasticbeanstalk.com
```

## Step 3 – Updating Your Code

Websites in production often need to be updated. To update your Laravel app, you can make changes to your local code and push them to production:

```bash
git add .
git commit -m “update”
git push origin master
```

After the pipeline runs successfully, reload the website URL to see changes.

## Conclusion

You’ve made it to the end of the tutorial! We successfully created a Laravel application, deployed it to Elastic Beanstalk, created a database for it, and updated it. We also learned how to set up continuous deployment using AWS CodeCommit and AWS CodePipeline.
To learn more about Laravel, check out its [documentation](https://laravel.com/docs/8.x).