DEV Community

Segun Olaiya
Segun Olaiya

Posted on

Deploying a Laravel App on AWS App Runner

Deploying a containerized app gets easier everyday as cloud providers release new products. One of such products by AWS is AWS App Runner.

AWS App Runner is a fully managed container application service that lets you build, deploy, and run containerized web applications and API services without prior infrastructure or container experience.

Ever want to just deploy an app without the Kubernetes or complex networking overhead? Or have a couple of services to maintain without alot of configuration? - Try AWS App Runner. Read more Here

Following this tutorial

For ease of following this tutorial, I have created a default Laravel app with all the files referenced in this post. Click Here to view the public github repo.

Dockerizing Laravel

Let's start with a Docker file. In this post, I will be using php7.4. In the root of your Laravel application, create a Dockerfile. See example Here

Other deployment related files

If you look at the contents of the Dockerfile above, /app/deploy folder was referenced. This folder contains files for nginx, superiviser and a run script that would start the laravel app. Click here to copy the contents of this folder to your local Laravel app.

Build and run your image

To ensure your docker image works locally, run docker build . to build your image.

When this builds successfully, you can find your image when you execute docker images on your cli.

Image description

Since the docker image exposes port 80, you can test your image by running:

docker run -p 8000:80 <image id>

(Ensure you pass valid database credentials or modify .env.example with reachable database credentials)

Setting up AWS App Runner

Now let's setup AWS App Runner. First of, AWS App Runner has an automatic deployment option, what this means is that, once our docker repository changes, our app automatically deploys. This is one of the simplicity that makes this product easy to use.

AWS Elastic Container Registry

Since we want to automate the entire process, we would be pushing our image automatically to AWS Elastic Container Registry.

Login to AWS and search for Elastic Container Registry

Image description

If you don't have an existing repository for your app, go ahead and create one. I will be creating a repository called laravel-aws-app-runner

Image description

Take note of the URI, we would need it later.

Setting up Github Actions

For us to automatically build our images and push to ECR from Github we would be using Github Actions

Let's start by adding 2 secrets to our Github repo, AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY. These two values would be used by the actions to access AWS. Ensure you set your AWS credentials that has access to the ECR you just created.

Image description

In your repo, create a Github actions file /.github/production.yml just like this

Take note of the ECR_REPOSITORY key, update the value to the name of the repository you created in ECR.

The Github actions tries to checkout the code, login to AWS, build the image and then push it up to the ECR repository.

Note that it also runs only when there is changes to master, feel free to change this configuration if you want a different branch.

You may push an empty commit to master to trigger your actions if it has not already been triggered. On your Actions tab, you should see a successful Github Actions run.

Image description

Creating an AWS App Runner Service

Finally, we have our image pushed to ECR, a Github action to update the image when we merge to master, we can now create a service on App runner that would automatically listen for changes on ECR and update our App.

On AWS, search for AWS App Runner and click on Create Service

Image description

If AWS App runner is not available in your preferred region, you may consider using a different region where this product is available.

In the Source and Deployment Select Container Registry and Amazon ECR as the provider. Choose the correct repository in the list and the default tag is latest according to our Github actions configuration.

Image description

As you can see, it is actually possible to reference a different docker repository outside of AWS ECR.

In Deployment settings, select Automatic - This is very important, with automatic, when our ECR image changes, the service will automatically be deployed.

If you already have a service role, feel free to choose one of them, other than that you can simply select Create a new service role

Image description

Then click on Next.

On the Service settings, this is where we configure Environment variables, the CPU & RAM of the service, and the port exposed by the Docker image.

Image description

Add all the env and values for your service, set the port to 80 (Except the Docker file port has been updated). Feel free to change the virtual CPU to 2vCPU, for now i'll leave the default.

I generally leave the Auto Scaling, Health Check Security, Observability and Tags tabs with the default configuration from AWS, but if you are an experienced AWS user and want custom configuration, feel free to modify these tabs to what you want.

For networking, which is quite important for your service to have access to other resources on your VPC. Your incoming network traffic has to stay as public endpoint if not your service would not be available on the internet.

If you would like to change your outgoing access, feel free to do that, but for now, i'll leave both with the defaults.

One major reason you may change your outgoing access later is because of your database connections as it would most likely be behind a security group in a custom VPC.

Now that we have all the configurations (mostly all defaults 🙈) We can now go ahead to create & Deploy the service.

Image description

After successful deployment, you should have a running service as displayed above.

Handling failed deployment

Just incase your deployment fails, you can view the application logs in Cloudwatch to know what the issue is
Image description

Once you see the log and figure out what the issue is from the Image, you can delete the failed service and create a new service.

Automatic deployments

Now that we have a running service, every time you push to your master branch and Github actions run, the ECR image would be updated and AWS App runner will automatically deploy the app.

Custom Domains

Obviously you may want to add Custom domain to your service and not use the default AWS domain. You can do that on the Custom Domains tab. Simply follow the instructions.

Image description

Conclusion

Once you get a hang of creating services and setting up Github actions to update the ECR Images, you can pretty much do anything you like such as even having Staging environments.

AWS App runner is quite straightforward and eliminates setting up your own ServerLess environment from ground up. And since our applications are containerized, you can pretty much switch to another platform in the future if you have too.

Top comments (0)