Deploy a PHP Application on Kubernetes with Helm
Introduction
This guide walks you through the process of running an example PHP (PHP-FPM) application on a Kubernetes cluster. PHP-FPM (FastCGI Process Manager) is an alternative PHP FastCGI implementation with some additional features useful for sites of any size, especially busier sites. This guide will use PHP-FPM with Nginx. Doing so will allow us to set up more complex configuration and load balance to different PHP-FPM instances.
Kubernetes is the best way for running application deployments across clusters of hosts. This solution allows you to automate the deployment, the scaling and management of the application containers. To more easily deploy and manage the application containers in a Kubernetes cluster, you can use Helm charts. In the same way that a Dockerfile contains instructions on how to build images in running containers, the charts define how the application will be deployed in Kubernetes. They specify the objects definitions, services, dependencies, number of pods, and so on.
The first step is to obtain the application source code, Dockerfile and the docker-compose.yml file and use them as a starting point for creating a custom Helm chart to automate the application deployment in a Kubernetes cluster. Once the application is deployed and working, this guide also explores how to modify the source code for publishing a new application release and how to perform rolling updates in Kubernetes using the Helm CLI.
Assumptions and prerequisites
- You have basic knowledge of how to build Docker images.
- You have basic knowledge of Helm charts and how to create them.
- You have a Docker environment running.
- You have an account in a container registry (this tutorial assumes that you are using Docker Hub).
- You have Minikube installed in your local computer.
- You have a Kubernetes cluster running.
- You have the kubectl command line (kubectl CLI) installed.
- You have Helm v3.x installed.
To create your own application in PHP-FPM and deploy it on Kubernetes using Helm, you will typically follow these steps:
- Step 1: Obtain the application source code
- Step 2: Build the Docker image
- Step 3: Publish the Docker image
- Step 4: Create the Helm Chart
- Step 5: Deploy the example application in Kubernetes
- Step 6: Updating the source code and the Helm chart
Step 1: Obtain the application source code
To begin the process, ensure that you have access to the application source code. The application code for the current example is stored in a Git repository. Follow these steps to obtain the application source code:
Clone the repository. This will clone the sample repository and make it the current directory:
git clone https://github.com/bitnami/tutorials cd tutorials/phpfpm-k8s/
In the app-code folder you will see a file named phpminiadmin.php. This is a small PHP application for accessing and managing MySQL databases which we will use as an example application. Feel free to use any other PHP application instead.
The steps below must be performed within the tutorials/phpfpm-k8s/ folder.
Step 2: Build the Docker image
The source code already contains the Dockerfile and the docker-compose.yml file needed for this example. Replace the USERNAME placeholder in the app-code/docker-compose.yml file with your Docker ID. When you open the docker-compose.yml file, you can see how the services are defined for MariaDB, Nginx and our PHP-FPM application as well as the environment variables used for the database creation.
Build the image using the command below. Remember to replace the USERNAME placeholder with your Docker ID:
docker build . -t USERNAME/phpfpm-app:0.1.0
Run the docker-compose up command in order to create and start the containers:
docker-compose -f app-code/docker-compose.yml up
Check if the application is running correctly by entering http://localhost/phpminiadmin.php in your default browser.
To log in to the application, you must connect first to the database. Click the "advanced settings" link and enter the information below. Then, click "Apply".
- DB user name: mini
- Password: mini
- DB name: mini
- MySQL host: mariadb
- port: 3306

After logging in, you should see the default application page:

Check the images that have been created in your local repository by executing the command below:
docker images | grep -E 'fpm|mariadb|nginx'

Step 3: Publish the Docker image
Now that your Docker image is built and contains your application code, you can upload it into a public registry. This tutorial uses Docker Hub, but you can select one of your own choice such as:
To upload the image to Docker Hub, follow the steps below:
Log in to Docker Hub:
docker login
Push the image to your Docker Hub account. Replace the DOCKER_USERNAME placeholder with the username of your Docker Hub account and my-custom-app:latest with the name and the version of your Docker image:
docker push DOCKER_USERNAME/my-custom-app:latest
Confirm that you see the image in your Docker Hub repositories dashboard.
Step 4: Create the Helm chart
To create a brand new chart, you just need to run the helm create command. This creates a scaffold with sample files that you can modify to build your custom chart. For the current tutorial, we provide you with a ready-made Helm chart. If you examine the repository you just downloaded, there is a directory named helm-chart that already contains the files you need.
Move into the kubernetes directory by executing the command below:
cd ../kubernetes
List the files in the folder and open some of them to understand the structure of a Helm chart:
Chart.yaml: This file includes the metadata of the Helm chart like the version or the description.
requirements.yaml: This file specifies the requirements for deploying this chart - in this case, the MariaDB container.
values.yaml: This file declares variables to be passed into the templates. It is important to replace the USERNAME with your Docker ID, and also to check if the container name and version exist.
image: repository: USERNAME/phpfpm-app tag: 0.1.0
This file also defines the ports of the container images:
nginxService: name: nginx type: NodePort externalPort: 80 internalPort: 80 phpfpmService: name: phpfpm type: NodePort phpfpmPort: 9000
Change to the templates/ folder and check the files there:
NOTES.txt: This file contains the output to be printed after installation.
configMap.yaml: This file stores configuration data. It is used to save the Nginx configuration file:
config: nginx.conf: |- server { listen 0.0.0.0:80; root /app; location / { index index.html index.php; } location ~ \.php$ { fastcgi_pass phpfpm-php-app-phpfpm:9000; fastcgi_index index.php; include fastcgi.conf; } }
deployment.yaml: This is the manifest file for creating the Kubernetes deployment. In this example, it includes two containers, one for PHP-FPM and the other form Nginx. This file also configures the configMap for the Nginx configuration file:
volumes: - name: nginx-config configMap: name: {{ template "fullname" . }}
service.yaml and nginx-service.yaml: These are manifests for creating service endpoints for both containers.
Step 5: Deploy the example application in Kubernetes
Before performing the following steps, make sure you have a Kubernetes cluster running, and that Helm and Tiller are installed correctly. For detailed instructions, refer to our starter tutorial.
At this point, you have built a Docker image, published it in a container registry and created your custom Helm chart. It's now time to deploy the example PHP application on Kubernetes. Follow these instructions:
First, make sure that you are able to connect to your Kubernetes cluster by executing the command below:
kubectl cluster-info
Deploy the Helm chart with the helm install command. This will create three pods within the cluster, one for the Nginx service, another for the MariaDB service, and the third for the PHP-FPM application.
The database name, root password, and user credentials have been specified by adding the --set
options. If you don't add the chart name, one will be assigned automatically. DB_ROOTPASSWORD, DB_USERNAME, DB_USERPASSWORD, and DB_NAME are placeholders for the database root password, user credentials and database name respectively, remember to replace them with the right values.
helm install phpfpm . --set mariadb.mariadbRootPassword=DB_ROOTPASSWORD,mariadb.mariadbUser=DB_USERNAME,mariadb.mariadbPassword=DB_USERPASSWORD,mariadb.mariadbDatabase=DB_NAME
Once the chart has been installed, you will see a lot of useful information about the deployment. The application won't be available until database configuration is complete. Follow these instructions to check the database status:
Run the kubectl get pods command to get a list of running pods:
kubectl get pods

Check the logs of the application pod. APP-POD-NAME is a placeholder; remember to replace it with the right value.
kubectl logs -f APP-POD-NAME

- To get the application URL, copy and paste the commands shown in the "Notes" section included in the information displayed when you executed the helm install command, append /phpminiadmin.php or the name of your own application, and run the command.

If you are using Minikube, you can also check the application service to get the application's URL:
minikube service phpfpm-php-app-nginx --url
- Enter the resulting URL in your default browser to access the application.

Congratulations! Your PHP application has been successfully deployed on Kubernetes!
Step 6: Update the source code and the Helm chart
As a developer, you'll understand that your application may need new features or bug fixes in the future. To release a new Docker image, you only have to perform a few basic steps: change your application source code, rebuild and republish the image in your selected container registry. Once the new image release has been pushed to the registry, you need to update the Helm chart.
Follow these instructions to complete the application update process:
In the docker-compose/app directory, change the version number in version.php to 0.1.1. Save the file.
In the docker-compose/docker-compose.yml file change the version number to 0.1.1 and rebuild the image by running the docker-compose up command.
docker-compose up
Before performing the next step, make sure that you are logged in Docker Hub. Run the docker login command to access your account (if applicable).
Publish the new image following the same steps as in step 3 but using the new version number. Remember to replace the USERNAME placeholder with your Docker ID:
docker push USERNAME/phpfpm-app:0.1.1
Change to the kubernetes directory, where you have the Helm chart files. Edit the values.yaml file to replace the current image tag with the new one:
Run the helm upgrade command followed by the name of the chart. After that, you will see the information about the new deployment:
helm upgrade phpfpm .

See what revisions have been made to the chart by executing the helm history command:
helm history phpfpm .

- Enter the application URL from step 5 and append /version.php in your default browser. You should see the new welcome message:

Follow these steps every time you want to update your Docker image and Helm chart.
Useful links
To learn more about the topics discussed in this guide, use the links below: