Deploying PHP on Kubernetes: A Step-by-Step Practical Guide

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction: Why Deploy PHP in Kubernetes?

\n\n

Many developers still perceive PHP as a language for "classic" hosting with FTP and phpMyAdmin. However, in modern DevOps culture, PHP applications are increasingly run in containers, with their management falling on the shoulders of Kubernetes (K8s). This provides not only automatic scaling and fault tolerance, but also environment consistency across all stages — from development to production.

\n\n

In this guide, we will walk through how to prepare a PHP project for deployment in Kubernetes: from creating a Docker image to writing manifests and launching it in a cluster. You will learn how to make the container lightweight, how to properly configure php-fpm, and how to tie it all together with Nginx. Let's go!

\n\n

Step 1: Preparing the PHP Application and Docker Image

\n\n

Before uploading code to K8s, you need to package it into a Docker image. Let's consider a typical PHP project in pure PHP (without a framework) — a simple script that displays a greeting and phpinfo.

\n\n

1.1. Project Structure

\n\n

Let's create a minimal structure:

\n\n
my-php-app/\n├── src/\n│   └── index.php\n├── docker/\n│   ├── php.Dockerfile\n│   └── nginx.conf\n└── k8s/\n    ├── deployment.yaml\n    └── service.yaml\n
\n\n

1.2. PHP Application Code

\n\n

File src/index.php:

\n\n
<?php\necho "<h1>Hello, Kubernetes!</h1>";\necho "<p>PHP Version: " . phpversion() . "</p>";\necho "<p>Server: " . gethostname() . "</p>";\n?>\n
\n\n

1.3. Dockerfile for PHP-FPM

\n\n

Create docker/php.Dockerfile:

\n\n
FROM php:8.2-fpm-alpine\n\n# Install dependencies (if needed)\nRUN docker-php-ext-install pdo pdo_mysql\n\n# Copy application code\nCOPY ./src /var/www/html\n\n# Set permissions (important for FPM)\nRUN chown -R www-data:www-data /var/www/html\n\nWORKDIR /var/www/html\n\nEXPOSE 9000\nCMD ["php-fpm"]\n
\n\n

Why alpine? It gives an image size of ~30 MB instead of 200+ MB on Debian. This is critical for fast loading in the cluster.

\n\n

1.4. Nginx Configuration

\n\n

PHP-FPM cannot serve static files directly — a web server is needed. Create docker/nginx.conf:

\n\n
server {\n    listen 80;\n    server_name _;\n    root /var/www/html;\n\n    index index.php index.html;\n\n    location / {\n        try_files $uri $uri/ /index.php?$query_string;\n    }\n\n    location ~ \\.php$ {\n        fastcgi_pass 127.0.0.1:9000;\n        fastcgi_index index.php;\n        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;\n        include fastcgi_params;\n    }\n}\n
\n\n

In Kubernetes, we will run Nginx and PHP-FPM in the same Pod (as sidecar containers) or as separate services. For simplicity, we'll use one Pod with two containers.

\n\n

Step 2: Building and Publishing Images

\n\n

Let's build the PHP-FPM image and the Nginx image with our configuration. In a real project, you could use a single image by combining Nginx and PHP with supervisord, but we'll do it the "right" way — separate them.

\n\n

Building the PHP image:

\n
docker build -t my-php-app:latest -f docker/php.Dockerfile .\n
\n\n

Building the Nginx image:

\n

Create a separate Dockerfile for Nginx:

\n
FROM nginx:alpine\nCOPY docker/nginx.conf /etc/nginx/conf.d/default.conf\nCOPY ./src /var/www/html\n
\n\n
docker build -t my-nginx:latest -f docker/nginx.Dockerfile .\n
\n\n

Then upload the images to a registry (Docker Hub, GitLab Container Registry, etc.):

\n
docker tag my-php-app:latest your-registry/my-php-app:latest\ndocker push your-registry/my-php-app:latest\n
\n\n

Step 3: Kubernetes Manifests

\n\n

Now for the interesting part — let's describe how Kubernetes will run our application.

\n\n

3.1. Deployment (main manifest

Blogs

Book Recommendations