Deploying a Symfony Application on Google Cloud Run

Introduction

Google's Cloud Run is a powerful and modern tool when it comes to hosting your web applications. For years, I always have preferred Cloud Run to building my own VM or even using a Kubernetes cluster.

Cloud Run offers a lot of advantages. You can use your own Docker image when deploying applications. You can easily attach a Cloud SQL instance if your application requires an RDBMS. Auto-scaling is a piece of cake and much more.

In this article, I'll briefly explain where you should start if you're thinking about hosting your Symfony application on Google's Cloud Run.

Prerequisites

Before we deal with this topic, we must ensure that the following requirements are met.

  • You have registered with GCP and set up an active billing account. Without a billing account, you will probably not be able to deploy your Cloud Run application.
  • A running Symfony application. For this example, we assume that your application does not require an existing MySQL instance.
  • You have installed the gcloud SDK on your computer. I have already written an article about it, which I will link below.

Create a Docker repository in Artifact Registry

Before we can start creating the first Docker image, we need to create a new Artifact Registry into which we will push our images. Fortunately, this is a very straightforward task that can be done with just one command.

gcloud artifacts repositories create ${NAME} --repository-format=docker \
    --location=${LOCATION}

You can check here, which locations are available to choose or by executing the following command

gcloud artifacts locations list

 Check whether your repository has been successfully created

gcloud artifacts repositories list

We will store all our Docker images in this repository and later pass them on to our Cloud Run service so that it knows which Docker image to run.

Finally, we need to authenticate and configure Docker so that we can push our images to Google's Artifact Registry. Execute the following command

gcloud auth configure-docker ${LOCATION}-docker.pkg.dev
Remember that we use the same storage location for the auth command as when creating the registry.

Building the Docker image

We will create a Dockerfile in the root directory of your project and write down the necessary steps to deploy our application.

There are a variety of Docker images that are basic or specifically designed for Symfony applications. Maybe you already have your favorite Docker image that you use for your Symfony applications. I will do the example with my self-made Docker image that I use for my projects.

Insert the following code into your freshly created Dockerfile

FROM vundb/php-nginx:8.3

COPY . /var/www/html/

RUN rm -rf /var/www/html/vendor \
    && rm -rf /var/www/html/var \
    && mkdir -p /var/www/html/var/log \
    && mkdir -p /var/www/html/var/cache \
    && chown -R www-data:www-data /var/www/

WORKDIR /var/www/html
USER www-data
RUN composer install

USER root
EXPOSE 80

This code pulls the Docker image with PHP 8.3 and Nginx, which is configured to have the document root directory in /var/www/html/public. It is therefore not necessary to pass a custom site configuration.

All other steps are quite simple. Copy your project code, remove the existing vendor, logs and cache directories and run composer install to download the required dependencies.

Now it's time to create our Docker image. Execute the following command

docker build --platform linux/amd64 --no-cache \
    -t ${LOCATION}-docker.pkg.dev/${PROJECT}/symfony/symfony:latest
Replace LOCATION with the location you previously selected and PROJECT with our current project ID.

When building image is done successfully, we can finally push it to Google's Artifact Registry.

docker push ${LOCATION}-docker.pkg.dev/${PROJECT}/symfony/symfony:latest

Deploying to Cloud Run

Now that your image is ready and has been uploaded to Google's Artifact Registry, the next step is to deploy your application to a Cloud Run service.

Luckily, this step is very simple. Just execute the following command

gcloud run deploy symfony \
    --image ${LOCATION}-docker.pkg.dev/${PROJECT}/symfony/symfony:latest \
    --region ${REGION} \
    --port 80

You must pass at least two parameters, the image and the region. Use the same image name you used in the previous build step and select a region of your choice for the region. In our example, we also need to tell Cloud Run that our application is listening on port 80 by passing this information during deployment.

When you deploy your application for the first time, you will be asked if you want unauthenticated invocations for your service. Simply answer yes to this question, because you want everyone to be able to access your application.

Allow unauthenticated invocations to [symfony] (y/N)?  y

The very first deployment takes a few minutes as Google has to create a new service with a public URL etc.. All further deployments only take a few seconds.

When the deployment is complete, you will see an output like this. Use the URL to access your application.

Service [symfony] revision [symfony-00001-vr9] has been deployed and is serving 100 percent of traffic.
Service URL: https://symfony-u23lgjymra-ey.a.run.app

Conclusion

As you can see, deploying your Symfony application on Cloud Run is a no brainer. But there are more aspects that need to be mentioned. You can still attach a MySQL instance if you want to persist some data. You can also automate this process with Google Cloud Build, but that's a topic for another article.