Your resource for web content, online publishing
and the distribution of digital products.

Kubernetes: deploy Laravel the easy way

DATE POSTED:October 18, 2018

Laravel is an excellent framework for developing PHP applications. Whether you need to prototype a new idea, develop an MVP (Minimum Viable Product) or release a full-fledged enterprise system, Laravel facilitates all of the development tasks and workflows.

How you deal with deploying the application is a different story. Vagrant is very good with setting up a local environment similar to a remote server. However, in production, you will most likely require more than just one web host and one database. You’ll probably have separate services for several requirements. You also need to have mechanisms in place to ensure that the application is always online and that the servers can efficiently balance the load.

In this article, I’ll explain how to deal with the simple requirement of running a Laravel application as a local Kubernetes set up.

Kubernetes, Why and What?

Kubernetes is an open-source system initially designed by Google to facilitate the management of containerised applications in a clustered environment. Some refer to it as an orchestration platform, and Kubernetes is not the only available platform of this type. Although, it does have a very high and fast adoption rate. Not to mention that it is quite easy to implement once you get used to it.

If you’re still wondering why someone can benefit from using Kubernetes, the answer is simple. Kubernetes makes it easier to set up and manage as many clusters as required across multiple projects.

Deploying a Laravel Application to Minikube

As I’ve afore-mentioned, I will be showing you how to deploy a straightforward and stateless Laravel application to Kubernetes. I aim to detail the steps involved in accomplishing this while explaining why specific actions are required. Furthermore, I will show you how to quickly scale the application and also make it available on a named host using an Ingress controller.

You can run Kubernetes on several cloud hosting providers such as Google Cloud Engine and Amazon Web Services. In this tutorial, you will run the application on Minikube, a tool that makes it easy to run Kubernetes locally.

Similar to Vagrant, Minikube is merely a Virtual Machine that contains a Kubernetes platform and Docker. You will need both to deploy your application as a Docker container and scale it to three instances using Kubernetes.

The application

I have prepared a simple Laravel application which you can clone from GitHub. It is nothing more than a fresh Laravel installation. Therefore you can follow this example using either the demo application or just create a new Laravel application. To use the demo application clone it in your project’s directory.

cd /to/your/working/directory git clone [email protected]:learnk8s/laravel-kubernetes-demo.git .


To follow with this demonstration, you will need the following installed on your local system:

1) Docker

2) Kubectl

3) Minikube

Are you having problems installing and running these applications on Windows? Check out the article Getting started with Docker and Kubernetes on Windows 10, for a step by step guide.

Docker image

Kubernetes deploys containerised applications, and therefore as a first step, you will need to build a Docker image of the demo application. Since this tutorial will be run locally on Minikube, you can just build a local Docker Image from the Dockerfile included in the example code.

FROM composer:1.6.5 as build
COPY . /app
RUN composer installFROM php:7.1.8-apache
COPY --from=build /app /app
COPY vhost.conf /etc/apache2/sites-available/000-default.conf
RUN chown -R www-data:www-data /app \
&& a2enmod rewrite

This Dockerfile is made of two parts:

  • The first part extends a PHP composer image so that you can install the application’s dependencies.
  • The second part creates a final Docker image with an Apache web server to serve the application.

Before you can test the Docker image, you will need to build it:

cd /to/your/project/directory
docker build -t yourname/laravel-kubernetes-demo .

Then run the application with:

docker run -ti \
-p 8080:80 \
-e APP_KEY=base64:cUPmwHx4LXa4Z25HhzFiWCf7TlQmSqnt98pnuiHmzgY= \

And the application should be available on http://localhost:8080.

With this setup, the container is generic and the APP_KEY is not hardcoded or shared.

Building the image within Minikube

cd /to/your/project/directory
eval $(minikube docker-env)
docker build -t yourname/laravel-kubernetes-demo .Don’t forget to execute the eval. Building the image within the virtual machine is necessary. You should run the command only once in the current terminal.

Deploying the image

Now that the application’s image is built and available in Minikube you can go ahead with deploying it.

I always start with making sure that kubectl is in the correct context. In this case, the context is Minikube. You can quickly switch context as follows:

kubectl config use-context minikube

then you can deploy the container image:

kubectl run laravel-kubernetes-demo \
--image=yourname/laravel-kubernetes-demo \
--port=80 \
--image-pull-policy=IfNotPresent \

The above command tells kubectl to run our demo application from the Docker image. The first parameter of the command simply asks kubectl to not pull the image from a registry such as Docker Hub if it exists locally which in this case it does. Do note that you still need to be logged on to Docker’s so that kubectl can check if the image is up to date.

You can check that a Pod is created for the application by running:

kubectl get pods

which should return a similar output to:

laravel-kubernetes-demo-7dbb9d6b48-q54wp 1/1 Running 0 18m

You can also use the Minikube GUI dashboard to monitor the cluster. The GUI also helps with visualising most of the discussed concepts. To view the dashboard, just run the following:

minikube dashboard

or to acquire the dashboard’s URL address:

minikube dashboard --url=true

Exposing a Service

So far you have created a deployment which is running the application’s container. A Pod running in the cluster has a dynamic IP. If you route the traffic directly to it using the IP, you may still need to update the routing table every time you restart the Pod. In fact, on every deployment or container restart, a new IP is assigned to the Pod. To avoid managing IP addresses manually, you need to use a Service. The Service acts as a load balancer for a set of Pods. So even if the IP address of a Pod changes, the service is always pointing to it. And since the Service always has the same IP, you won’t need to update anything manually.

You can create a service with:

kubectl expose deployment laravel-kubernetes-demo --type=NodePort --port=80

and provided all went well, you will see a confirmation similar to:

service "laravel-kubernetes-demo" exposed

Running the following command:

kubectl get services

will show you a list of running services. You can also view the running service under the “Services” navigation menu within the dashboard. A more exciting way to verify this deployment and the service exposure is obviously seeing the running application in the browser