Deploying a Laravel app in Kubernetes on Google Cloud

Introduction

In this tutorial, we will learn how to create a K8s cluster, deploy a fresh Laravel installation, and expose it publicly.

Kubernetes, also known as K8s, is an opensource system for production-grade container orchestration. The word Kubernetes originates from a Greek word which means helmsman or pilot. K8s is an abbreviation derived by replacing the eight letters “ubernete” with “8”. Modern application stacks usually are made up of a minimum of two to three services that interact with each other (web service, database service, and caching service), which run inside containers. Container orchestration, simply put, is organizing these respective containers together.

K8s is one of many container orchestration tools that allows users (software engineers or DevOps engineers) to effectively manage containers and group them into clusters. Why should I use Kubernetes? K8s make complicated concepts such as horizontal scaling, load balancing, automated rollouts and rollbacks as painless as writing a line of command. Companies currently taking advantage are Evernote, Intel, Shopify and many more.

Requirements

  • Must have a user account on GCP (Google Cloud Platform)
  • Must have a basic understanding of Google Cloud Platform
  • Must have kubectl installed on your local machine (latest version)
  • Must have a basic understanding of Kubernetes
  • Must have Composer installed on your local machine (version >= 1.8.0)
  • Must have PHP setup on your local machine (version >= 7.1.3)
  • Must have Google Cloud SDK installed (version >= 206.0.0)
  • Must have a basic understanding of Laravel
  • Must have Docker installed on your local machine (version >= 18.09.0)
  • Must have a basic understanding of Docker

Once you have the requirements listed above, we can proceed.

In the beginning

Before we get our hands dirty, we will head over to the K8s engine page to create an application or select one if you have already created one. We will then wait for the engine to enable all the related services, which will take a couple of minutes.

In this tutorial, we will be using our local shell with gcloud and kubectl installed. You can also use the cloud console which comes with the above-mentioned packages already installed.

To save yourself some keystrokes, you should run the following commands on your terminal:

1// remember to change PROJECT_ID to your desired project name
2    
3    $ gcloud config set project PROJECT_ID
4    $ export PROJECT_ID="$(gcloud config get-value project -q)"
5    $ gcloud config set compute/zone europe-west3-a

PRO TIP: You can click here to view a list of available compute zones.

With all that setup, we can proceed to build a Docker container for our Laravel application.

Building the application image

In this section, we will:

  • Download a fresh installation of Laravel (version 5.7).
  • Create a Dockerfile inside our project directory.
  • Run the docker build command.

Once we are done with this steps, we will test run our application locally before it is uploaded to GCR (Google Cloud Registry). These steps will be explained in detail as we go further.

Laravel installation

To install Laravel version 5.7 we will run the following command:

    composer create-project --prefer-dist laravel/laravel app "5.7.*"

This command creates and installs a legacy version of Laravel, by creating a new folder app in the correct directory where the command was run in.

When the installation is done, we’ll navigate into our project directory like so:

$ cd app/

The inside our project directory we’ll run our Laravel application like so:

$ php artisan serve

You should see an image like this in your browser when you click on the generated link.

laravel-kubernetes-google-demo-1

If you see that, you are ready to move on to the next section 👍🏼.

Dockerizing our application

In our application root directory, we are going to create a Dockerfile with the following contents. Open your terminal and run this command:

    $ touch Dockerfile

Insert the following content into the Dockerfile:

1FROM creativitykills/nginx-php-server:2.0.0
2    MAINTAINER Neo Ighodaro <neo@hotels.ng>
3    COPY . /var/www/
4    RUN chmod -Rf 777 /var/www/storage/

On the first line of our Dockerfile, we are pulling an nginx-php-server with a tag 2.0.0. The second line defines the maintainer with the third line moving our current project directory into the web directory /var/www of the nginx-php-server. On the fourth, line we are making the /var/www/storage/ directory readable, writable and executable.

With our Dockerfile inside our application directory, we will run the following command to dockerize our Laravel App.

docker build -t gcr.io/${PROJECT_ID}/laravel_k8_app:v1 .

Where ${PROJECT_ID} is our project id defined at the beginning of this article. This line is going to build an image of our Laravel application with a v1 tag.

Test running our image

If you run the command docker images you’ll see something along the lines of:

laravel-kubernetes-google-docker-images

You should see an image which looks like the image name you defined in the image above. After confirming our image was built, we’ll take our image for a spin locally by running the following command:

docker run -p 43211:80 gcr.io/${PROJECT_ID}/laravel_k8_app:v1

When you visit this URL http://0.0.0.0:43211 you should see something familiar like so:

laravel-kubernetes-google-demo-2

Yay! our application works in Docker, next step will be to upload our image to GCR.

Pushing our image to GCR

Google Cloud Registry is a private Docker container registry that runs on the Google cloud platform.

Pushing our image to GCR is as easy as running two commands. First one to authenticate the Docker CLI (command line interface) tool to the container registry.

gcloud auth configure-docker

This command only needs to be run once. We’ll then push our image to the registry like so:

docker push gcr.io/${PROJECT_ID}/laravel_k8_app:v1

And that’s it! Our image has been uploaded to GCR. In the coming section, we’ll create a Kubernetes cluster on GKE (Google Kubernetes Engine) and deploy our Laravel application app on it.

Deploying our Laravel application

If you’re reading this section, you’ve either travelled far or strolled down here, either way, it is good to have you here. As stated above, we’ll be creating a K8s cluster and deploying our container (our Laravel app) on it.

Before we continue, let’s briefly talk about what Laravel is. Laravel is a super fast PHP framework for web artisans. Performance should be a key feature to be considered when building applications. Deploying a Laravel application in K8s is going to give our application an edge over other applications running on bare metal when it comes to performance (deployment, scaling, load balancing, logging and monitoring) and flexibility.

Creating a Kubernetes cluster on GKE

What is a Kubernetes container cluster? A K8s container cluster basically contains a band of Google Compute VM instances which are called nodes. These nodes run the Kubernetes processes necessary to make them part of a cluster. Simply put, you deploy your applications to clusters, your applications run on nodes or the nodes run your applications. Either way, your applications run in a K8s cluster which is made up of nodes.

Creating a K8s cluster is as simple as running a simple command:

gcloud container clusters create laravel-k8-cluster --num-nodes=4

This command creates a cluster named laravel-k8-cluster with four nodes. Give it some minutes, when it is done, you should see something along the lines of:

laravel-kubernetes-google-create-clusters

Deploying our app

To deploy our app onto our cluster we will run a simple command like so:

kubectl run laravel-k8-web --image=gcr.io/${PROJECT_ID}/laravel_k8_app:v1 --port 80

This command creates a deployment with a name laravel-k8-web and runs our image pointing to the internal port of the container, which in this case is port 80. If successful, you should get a success message along the lines of “deployment.apps laravel-k8-web created”.

To expose our application to the outside world (that is, the internet) we’ll run the following command:

kubectl expose deployment laravel-k8-web --type=LoadBalancer --name=laravel-k8-web-svc

This command exposes the deployment laravel-k8-web we created earlier and spins up a LoadBalancer with a service name laravel-k8-web-svc. If successful, you should get a success message along the lines of “service laravel-k8-web-svc exposed

To get an “outside world” link to our application, we’ll run the following command.

kubectl get services laravel-k8-web-svc

When this command runs, just below the EXTERNAL-IP section we should see our outside world link. If you see the <pending tag, give it a minute and try the command again.

If you navigate to the IP provided on a web browser, you will see this:

laravel-kubernetes-google-demo-3

Congrats! you just deployed a Laravel application to Kubernetes 🎉

Conclusion

In this tutorial, we have learned what Kubernetes is, why we need to use it and what it means to deploy a Laravel application in a K8s cluster.