Running a Symfony application on AWS Lambda (Part 2)

Navid Hosseini
3 min readApr 23, 2024
Photo by Rivage on Unsplash

Welcome back to the second part of my post about running a Symfony application on AWS Lambda! In the first part, I tried to describe the core functionalities of AWS Lambda, the compelling reasons for using Symfony with Lambda, the pros and cons of this approach, and a step-by-step guide to deploying a simple Symfony application on AWS Lambda.

In this part, I am gonna to describe serving assets in your Symfony App in the Lambda environment. When you use servers like Apache or Nginx, attaching assets to your pages seems simple and straightforward but when you use Lambda for serving your site, you should setup a CloudFront and put your app and assets behind it. First it sounds a little weird but it is not complicated especially with using Serverless.

Serving Assets

If you did the deployment section of the part 1 correctly, now your Symfony app has been deployed and you can reach the first page of the site by its API gateway URL. The first page is the default page of Symfony now and might be something like this:

This page seems fine because it does not have any asset which is attached to its HTML document. No image, no CSS or Javascript, font file and etc. So if your application is just a web service app that provides APIs, maybe it would be fine and enough. But if the request to your app will serve and return a HTML document with assets included, then you have a little more work to do to serve it decently in AWS Lambda. To aim this we can use CloudFront which acts as a CDN and also as a reverse proxy. So it can route requests to PHP and assets to the S3.

In the first I want to create a simple page with route /about that contains an image in it. Its action and twig template could be something like this:

  #[Route('/about', name: 'about')]
public function about(): Response
{
return $this->render('main/about.html.twig');
}
{% extends 'base.html.twig' %}

{% block title %}About{% endblock %}

{% block body %}

<div class="example-wrapper">
<h1>About</h1>

This is about page with a sample image <br>
<img width="80%" src="{{ asset('images/sample.jpeg') }}"/>
</div>
{% endblock %}

As you can see in the template file of the/about rout, one image has been attached that is located in the /public/image/sample.jpeg of my application.

If you deploy your app again and reach the /about page, you will find that the image could not be loaded in the page because its path is not a valid path in Lambda environment. Now we are going to solve this issue.

First you need to install the serverless-lift plugin on the serverless:

npm init
npm i
serverless plugin install -n serverless-lift

Then add the constructs section to the end of you serverless.yml file which defines your website assets in S3. you can add files and folders that needs to be served from S3 and map them like this:

constructs:
website:
type: server-side-website
assets:
'/images/*': public/images
# add here any file or directory that needs to be served from S3

Clear the app cache and deploy your app again:

./bin/console c:c --env=prod
serverless deploy

This deployment will create a cloudFront for your Lambda app which contains a new URL. This url would be printed in your terminal and it could be something like: `https://<cloud-front-unique-id>.cloudfront.net`. You can reach your website via this url and in the /about path, the image should be successfully shown in the about page. By this way you can attach any other assets like CSS/JS/Fonts files to your pages.

I hope you will find this part also useful and dont hesitate to reach me if you have any question or problem. The complete has been pushed to this repository.

--

--