Deploying Laravel Projects to Kubernetes
Future-proof Laravel deployments with Kubernetes and DevSpace.

No Kubernetes Cluster? No Problem.
This tutorial works with any Kubernetes cluster (minikube, GKE, AKS, EKS etc.) but if you are new to Kubernetes and want to explore how to deploy your Laravel application before setting up a cluster, you can simply use the free tier of DevSpace Cloud — we are providing free Kubernetes namespaces in fully managed clusters to get you started as quickly as possible. If you are more familiar with Kubernetes, you can, of course, use your own cluster or switch to it whenever you like.
Portability is one of the biggest strengths of Kubernetes.
Prerequisites
Before we get started, make sure you have Docker installed and you marked the hard drive containing your working directory as Shared Drive.
1. Create a Laravel Project
If you already have a Laravel project, you can skip this step.
Before creating a Laravel project, let’s define a variable with the directory that we want our Laravel project to be located in:
PROJECT_DIR=/c/Users/[username]/my-laravel-project # win (git-bash)
PROJECT_DIR=/home/[username]/my-laravel-project # mac, linux (bash)
Make sure you have sufficient (write) permissions for the directory and that you are using the correct syntax.
If you are using Docker Toolbox, you must use a directory inside your home directory (e.g. C:/Users/[username]/my-laravel-project).
To create a Laravel project, we can simply run the following Docker command:
mkdir $PROJECT_DIR docker run --rm -v /$PROJECT_DIR:/app composer/composer create-project --prefer-dist laravel/laravel . cd $PROJECT_DIR
Running this command can take quite a while. Sometimes it looks like it’s hanging but it just takes some time to set up a powerful framework such as Laravel. So, be patient and make sure you wait until the command successfully terminates.
If you are on Windows, you can run this command using
git-bash
.If you see the error “Drive has not been shared”, make sure you mark the hard drive containing your working directory as Shared Drive.
Now, you should be inside the root directory of your new Laravel project. Three simple commands left and our Laravel project is ready to be deployed to Kubernetes.
Copy .env.example
Inside the Laravel project, we can find a file called .env.example
. You need to copy this file to .env
:
cp .env.example .env
Create Encryption Key
Laravel needs a secure application key to encrypt data, so we need to create this key before deploying the project:
docker run --rm -v /$PROJECT_DIR:/app --entrypoint="//usr/local/bin/php" composer/composer artisan key:generate
As you can see, we also run this command via Docker, so we don’t need PHP or anything else on our local development machine.
Optimize
The last step to get our new Laravel project ready is to run the artisan optimize
command:
docker run --rm -v /$PROJECT_DIR:/app --entrypoint="//usr/local/bin/php" composer/composer artisan optimize
2. Containerize Project
Alright. Now, we are ready to containerize our Laravel project. We are using DevSpace, an open-source development tool for Kubernetes, for containerizing and deploying our Laravel project, so let’s install DevSpace. The easiest option to install DevSpace is to run the following npm
command:
npm install -g devspace
For other install options, take a look at the DevSpace GitHub page.
After installing DevSpace, run the following command inside your Laravel project directory:
devspace init
DevSpace will ask a couple of questions that are pretty easy to answer. If you are not sure about a question, just use the answer that is selected by default and press Enter
.
Make sure you select
php
as language. Because Laravel has apackage.json
and quite a few Javascript files, DevSpace detects the language asjavascript
. Make sure, you change that and selectphp
using theUP/DOWN
arrow keys on your keyboard before hittingEnter
.When DevSpace shows you a warning that the application is listening on port 80 which is a privileged port, just hit
Enter
, so DevSpace will use 8080 to show your Laravel project on localhost.
After DevSpace containerized our project, we will find a Dockerfile
inside the project directory. To make this Dockerfile working for Laravel, we need to add the following lines at the end of the Dockerfile:
ENV APACHE_DOCUMENT_ROOT=/var/www/html/public RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf RUN sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf
That’s it! Our project is now fully containerized and ready to be deployed to Kubernetes.
3. Choose Kubernetes Cluster
Now, we need to decide to which Kubernetes cluster we want to deploy our Laravel project. As mentioned in the beginning, DevSpace sponsors free Kubernetes namespaces. So, if you don’t have a Kubernetes cluster, you can run the following command to create a hosted Kubernetes namespace directly from the command-line:
devspace create space tutorial-laravel
After running this command, DevSpace sets up a so-called kube-context that allows you to access this namespace with any Kubernetes tool such as kubectl or helm.
If you already have a Kubernetes cluster, you can skip the above command and instead make sure that you are in the right kube-context that is pointing to your cluster. To tell DevSpace to use your own cluster, you can run the following command to let DevSpace know which namespace to use:
devspace use namespace [YOUR_NAMESPACE]
DevSpace will automatically create the namespace before deploying the project if it does not exist yet.
4. Start Development
Before deploying in “production-like” mode, I want to show you how you can iteratively test your application inside a Kubernetes cluster. To do that, simply run:
devspace dev
This command will build a Docker image based on our Dockerfile, push this Docker image to a Docker registry (e.g. Docker Hub) and then deploy our Laravel project to the Kubernetes cluster. But instead of stopping there, this development command will also stream the logs of our application and then open the application on localhost (via so-called port-forwarding). That means that the Laravel project is running inside a container which runs in a Kubernetes cluster but we can still access the application via localhost
in the browser as long as devspace dev
is still running.
If everything starts as it should be, DevSpace will show the Apache logs and shortly after, the browser will open with your Laravel site on localhost:8080
showing this getting started page:

Additionally, when we run devspace dev
, DevSpace will also watch for file changes on the local filesystem within our project directory. That means that whenever you change a file, DevSpace will update our Laravel deployment directly inside Kubernetes.
Try it out:
- Change the following file:
resources/views/welcome.blade.php
- Reload the browser and see your changes directly taking effect.
Pretty fast, right?
Tip: Define PHP Shortcut Command
Because we are running commands such as php artisan ...
very often when working with Laravel, it makes sense to create a little shortcut to make it easier to execute these commands directly inside our Kubernetes containers. Add the following lines to the end of of devspace.yaml
:
commands:
- name: php
command: devspace enter php
devspace.yaml
is the configuration file for DevSpace and let's you define how your application should be deployed and developed using Kubernetes. It is pretty powerful and allows a lot of customization.
After adding the above lines and saving the devspace.yaml
, you can now run php artisan ...
commands within Kubernetes like this:devspace run php artisan ...
Instead of artisan
, you could also run any other PHP command, as long as it starts with devspace run php
.
Try it yourself and run:
devspace run php artisan optimize
Extra: Add MySQL Database
Before continuing with this step, make sure you end the
devspace dev
command usingCTRL+C
.
Most Laravel projects need a database, so I will show you how to add a Kubernetes-based mysql
database to your project. Everything that DevSpace deploys to Kubernetes is defined within the devspace.yaml
, so let's change this file to add a MySQL database. Right under the line containing deployments:
, add the following:
- name: database
helm:
chart:
name: stable/mysql
values:
mysqlDatabase: "homestead"
mysqlUser: "homestead"
mysqlRootPassword: ${DB_ROOT_PASSWORD}
mysqlPassword: ${DB_PASSWORD}
We are defining
homestead
as username and database name because that is the default for Laravel projects. The password for the usersroot
andhomestead
are defined as a DevSpace variables. The next time, we will deploy the project with DevSpace, DevSpace will ask us to provide a value for each one of these variables.
After adding this MySQL deployment to our configuration, we also need to tell the Laravel deployment how to access the database. To do this, we need to add the following lines:
env:
- name: DB_HOST
value: database-mysql
- name: DB_PASSWORD
value: ${DB_PASSWORD}
So our final deployments
section in devspace.yaml
will look like this:
deployments:
- name: database
helm:
chart:
name: stable/mysql
values:
mysqlDatabase: "homestead"
mysqlUser: "homestead"
mysqlRootPassword: ${DB_ROOT_PASSWORD}
mysqlPassword: ${DB_PASSWORD}
- name: my-laravel-project # this line may be different for you
helm:
componentChart: true
values:
containers:
# this line may be different for you
- image: dscr.io/${DEVSPACE_USERNAME}/mylaravelproject
env:
- name: DB_HOST
value: database-mysql
- name: DB_PASSWORD
value: ${DB_PASSWORD}
service:
ports:
- port: 80
Now, we can deploy this project again and DevSpace will add the MySQL to our Laravel app. So, let’s run:
devspace dev
The first time you run
devspace dev
after this change, DevSpace will ask you to define a database password that is used for the variableDB_PASSWORD
.DevSpace will only show the logs of our Laravel project but not of the MySQL because the database is using a standard Docker image which is not built by DevSpace during the deployment process.
Before we continue, make sure your MySQL database is up and running. You can do that by checking the logs. So, either close devspace dev
after you see the Apache logs or open another terminal and run the following command to stream the logs of the MySQL database:
devspace logs -f
When you see one of the following log lines, then the MySQL server is ready:
# Option 1:
2019-10-16T03:46:32.089655Z 0 [Note] mysqld: ready for connections.# Option 2:
MySQL init process done. Ready for start up.
It might take a while when starting the MySQL server for the very first time.
After the database is ready, run the following command to initialize the data for our Laravel application inside the MySQL database:
devspace run php artisan migrate
You should see an output like this one:
Migration table created successfully. Migrating: 2014_10_12_000000_create_users_table Migrated: 2014_10_12_000000_create_users_table Migrating: 2014_10_12_100000_create_password_resets_table Migrated: 2014_10_12_100000_create_password_resets_table
Extra: Add Auth
To add authentication for our Laravel project, you can simply run the following command:
devspace run php artisan make:auth
Before you run this command, make sure you added the MySQL database and initialized the data for it.
After running the artisan make:auth
command, you should see an output like this one:
Authentication scaffolding generated successfully.
For more info on how to configure your Laravel authentication, take a look at the official documentation: https://laravel.com/docs/5.8/authentication#introduction

5. Deploy Project
Now, you know how to run devspace dev
and develop a Laravel project using Kubernetes. When you're ready to deploy your project in a more production-like fashion and make it available on a public domain, you can run the following command:
devspace deploy
In contrast to
devspace dev
,devspace deploy
terminates after deploying the project.
If you want to access the deployed project, you can run the following command:
devspace open
DevSpace will ask you if you want to access the Laravel application using port-forwarding (e.g. via localhost just like when running
devspace dev
) or if it should make the project accessible on a public URL.
Congrats, now your application is running inside a Kubernetes cluster!
Tip: Use a separate namespace for development and production. You can run the command
devspace use space [name]
for DevSpace Cloud ordevspace use namespace [namespace]
for your own clusters to switch between namespaces. After running one of these command, just rundevspace dev
to develop the project ordevspace deploy
to deploy the project just as you have done it during the tutorial.
Next: Optimize for Production
Of course, our “production-like” deployment still needs some fine-tuning. At the moment, there is no optimization for automatic scaling, caching etc. — but this tutorial is already pretty long and I want to make sure you are familiar with the basics first. In my next article, I will show you how to add a high available Redis cluster for caching and how to optimize your MySQL database and your Dockerfile for automated scaling using Kubernetes.
Subscribe below to receive an email when this article will be online.
If this is helpful to you or you have any questions or ideas what might be interesting to blog about next, reach out via twitter @LukasGentele or email: lg AT devspace.cloud
Looking forward to hearing from you!
Originally published at https://devspace.cloud.