Introduction: Why Deploy PHP in Kubernetes?
PHP remains one of the most popular languages for web development. However, as the load and complexity of projects (Laravel, Symfony, Bitrix) grow, the traditional LAMP stack can no longer cope. Kubernetes (K8s) offers a solution: automatic scaling, fault tolerance, zero-downtime deployment, and configuration management.
In this guide, we will walk through the complete cycle of deploying a PHP application in Kubernetes in practice: from creating a Docker image to setting up Ingress. You will learn how to prepare manifests, manage environment variables, and ensure PHP-FPM works in the cluster.
1. Preparing the PHP Application and Docker Image
1.1. PHP Project Structure
For deployment, we need a minimal PHP application. Let's take a classic index.php:
<?php// index.phpecho "Hello from Kubernetes! PHP version: " . phpversion();Also, create a composer.json (if you are using a framework):
{ "require": { "php": "^8.1" }}1.2. Dockerfile for PHP-FPM
Key point: In Kubernetes, PHP runs via PHP-FPM, while Nginx serves static files. Let's create a Dockerfile:
FROM php:8.2-fpm-alpine
# Install necessary extensionsRUN docker-php-ext-install pdo_mysql mysqli opcache
# Copy application codeCOPY . /var/www/html
# Set permissionsRUN chown -R www-data:www-data /var/www/html
# PHP settingsCOPY php.ini /usr/local/etc/php/conf.d/custom.ini
WORKDIR /var/www/html
EXPOSE 9000CMD ["php-fpm"]For production, add opcache:
; php.iniopcache.enable=1opcache.memory_consumption=128opcache.max_accelerated_files=100001.3. Dockerfile for Nginx
Nginx will proxy requests to PHP-FPM:
FROM nginx:alpine
COPY nginx.conf /etc/nginx/conf.d/default.confCOPY public/ /var/www/html/public
EXPOSE 80Example nginx.conf:
server { listen 80; root /var/www/html/public; index index.php;
location / { try_files $uri $uri/ /index.php?$query_string; }
location ~ \\.php$ { fastcgi_pass php-service:9000; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; }}2. Creating Kubernetes Manifests
2.1. Namespace
Isolate our application:
apiVersion: v1kind: Namespacemetadata: name: php-app2.2. ConfigMap for Environment Variables
PHP applications often use environment variables (e.g., for database connection):
apiVersion: v1kind: ConfigMapmetadata: name: php-config namespace: php-appdata: APP_ENV: production APP_DEBUG: "false" DB_HOST: mysql-service2.3. Secret for Sensitive Data
Store passwords and keys in a Secret:
apiVersion: v1kind: Secretmetadata: name: php-secrets namespace: php-apptype: Opaquedata: DB_PASSWORD: cGFzc3dvcmQxMjM= # base64 "password123"2.4. Deployment for PHP-FPM
The main component — PHP-FPM:
apiVersion: apps/v1kind: Deploymentmetadata: name: php-deployment namespace: php-appspec: replicas: 2 selector: matchLabels: app: php-app template: metadata: labels: app: php-app spec: containers: - name: php-fpm image: my-registry/php-app:latest ports: - containerPort: 9000 envFrom: - configMapRef: name: php-config - secretRef: name: php-secrets resources: requests: memory: "128Mi" cpu: "250m" limits: memory: "256Mi