Monday, 13 October 2025

Deploy a PHP Website on Kubernetes with Apache & MySQL (LAMP Stack)

Our course you can check :-   Udemy course  


Ques:-  

DevOps team want to deploy a PHP website on Kubernetes cluster. They are going to use Apache as a web server and Mysql for database. The team had already gathered the requirements and now they want to make this website live. Below you can find more details:

1) Create a config map php-config for php.ini with variables_order = "EGPCS" data.

2) Create a deployment named lamp-wp.

3) Create two containers under it. First container must be httpd-php-container using image webdevops/php-apache:alpine-3-php7 and second container must be mysql-container from image mysql:5.6. Mount php-config configmap in httpd container at /opt/docker/etc/php/php.ini location.

4) Create kubernetes generic secrets for mysql related values like myql root password, mysql user, mysql password, mysql host and mysql database. Set any values of your choice.

5) Add some environment variables for both containers:

a) MYSQL_ROOT_PASSWORD, MYSQL_DATABASE, MYSQL_USER, MYSQL_PASSWORD and MYSQL_HOST. Take their values from the secrets you created. Please make sure to use env field (do not use envFrom) to define the name-value pair of environment variables.

6) Create a node port type service lamp-service to expose the web application, nodePort must be 30008.

7) Create a service for mysql named mysql-service and its port must be 3306.

8) We already have /tmp/index.php file on jump_host server.

a) Copy this file into httpd container under Apache document root i.e /app and replace the dummy values for mysql related variables with the environment variables you have set for mysql related parameters. Please make sure you do not hard code the mysql related details in this file, you must use the environment variables to fetch those values.

b) You must be able to access this index.php on node port 30008 at the end, please note that you should see Connected successfully message while accessing this page.


Ans:-

Here is your combined Kubernetes YAML manifest for deploying a PHP website with Apache and MySQL:

This manifest includes:

  • A ConfigMap for php.ini
  • A Secret for MySQL credentials
  • A Deployment with two containers (Apache-PHP and MySQL)
  • Environment variables set using the env field
  • A NodePort service for the web app (port 30008)
  • A ClusterIP service for MySQL (port 3306)

---
#ConfigMap for php.ini
apiVersion: v1
kind: ConfigMap
metadata:
  name: php-config
  namespace: default
data:
  php.ini: |
    variables_order = "EGPCS"

---
#Secrets for MySQL
apiVersion: v1
kind: Secret
metadata:
  name: mysql-secrets
  namespace: default
type: Opaque
data:
  MYSQL_ROOT_PASSWORD: cGFzc3dvcmQ=         # base64 for "password"
  MYSQL_DATABASE: bXlzcWw=                  # base64 for "mysql"
  MYSQL_USER: dXNlcg==                      # base64 for "user"
  MYSQL_PASSWORD: dXNlcnBhc3M=              # base64 for "userpass"
  MYSQL_HOST: bXlzcWwtc2VydmljZQ==          # base64 for "mysql-service"

---
#Deployment with Two Containers
apiVersion: apps/v1
kind: Deployment
metadata:
  name: lamp-wp
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: lamp-app
  template:
    metadata:
      labels:
        app: lamp-app
    spec:
      containers:
      - name: httpd-php-container
        image: webdevops/php-apache:alpine-3-php7
        ports:
        - containerPort: 80
        volumeMounts:
        - name: php-config-volume
          mountPath: /opt/docker/etc/php/php.ini
          subPath: php.ini
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-secrets
              key: MYSQL_ROOT_PASSWORD
        - name: MYSQL_DATABASE
          valueFrom:
            secretKeyRef:
              name: mysql-secrets
              key: MYSQL_DATABASE
        - name: MYSQL_USER
          valueFrom:
            secretKeyRef:
              name: mysql-secrets
              key: MYSQL_USER
        - name: MYSQL_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-secrets
              key: MYSQL_PASSWORD
        - name: MYSQL_HOST
          valueFrom:
            secretKeyRef:
              name: mysql-secrets
              key: MYSQL_HOST
      - name: mysql-container
        image: mysql:5.6
        ports:
        - containerPort: 3306
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-secrets
              key: MYSQL_ROOT_PASSWORD
        - name: MYSQL_DATABASE
          valueFrom:
            secretKeyRef:
              name: mysql-secrets
              key: MYSQL_DATABASE
        - name: MYSQL_USER
          valueFrom:
            secretKeyRef:
              name: mysql-secrets
              key: MYSQL_USER
        - name: MYSQL_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-secrets
              key: MYSQL_PASSWORD
        - name: MYSQL_HOST
          valueFrom:
            secretKeyRef:
              name: mysql-secrets
              key: MYSQL_HOST
      volumes:
      - name: php-config-volume
        configMap:
          name: php-config

---
#NodePort Service for Apache
apiVersion: v1
kind: Service
metadata:
  name: lamp-service
  namespace: default
spec:
  type: NodePort
  selector:
    app: lamp-app
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
    nodePort: 30008


---
#ClusterIP Service for MySQL
apiVersion: v1
kind: Service
metadata:
  name: mysql-service
  namespace: default
spec:
  selector:
    app: lamp-app
  ports:
  - protocol: TCP
    port: 3306
    targetPort: 3306


raj@jumphost ~$ echo cGFzc3dvcmQ= | base64 --decode
password

raj@jumphost ~$ kubectl get apply -f pod.yaml

raj@jumphost ~$ kubectl get all
NAME                           READY   STATUS    RESTARTS   AGE
pod/lamp-wp-85c6bdc6f9-5fpwh   2/2     Running   0          15m

NAME                    TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
service/kubernetes      ClusterIP   10.96.0.1       <none>        443/TCP        55m
service/lamp-service    NodePort    10.96.102.161   <none>        80:30008/TCP   15m
service/mysql-service   ClusterIP   10.96.232.74    <none>        3306/TCP       15m

NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/lamp-wp   1/1     1            1           15m

NAME                                 DESIRED   CURRENT   READY   AGE
replicaset.apps/lamp-wp-85c6bdc6f9   1         1         1       15m

raj@jumphost ~$ kubectl get cm
NAME               DATA   AGE
kube-root-ca.crt   1      55m
php-config         1      15m

raj@jumphost ~$ kubectl get Secret
NAME            TYPE     DATA   AGE
mysql-secrets   Opaque   5      16m

raj@jumphost ~$ kubectl cp /tmp/index.php <pod-name>:/app -c httpd-php-container

raj@jumphost ~$ kubectl exec -it lamp-wp-85c6bdc6f9-5fpwh -c httpd-php-container -- bash
bash-4.3# cd /app/
bash-4.3# cat index.php 
<?php
$host = getenv('MYSQL_HOST');
$db = getenv('MYSQL_DATABASE');
$user = getenv('MYSQL_USER');
$pass = getenv('MYSQL_PASSWORD');

$conn = new mysqli($host, $user, $pass, $db);

if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}
echo "Connected successfully";
?>
bash-4.3# 


After applying all manifests and copying the file, access the app via:

http://<NodeIP>:30008/index.php

You should see:
Connected successfully


Conclusion:-


In this hands-on tutorial, you'll learn how to deploy a complete PHP-based web application on a Kubernetes cluster using the LAMP stack (Linux, Apache, MySQL, PHP). This course walks you through:

  • Creating a ConfigMap for PHP configuration (php.ini)
  • Setting up Kubernetes Secrets for MySQL credentials
  • Deploying a multi-container pod with Apache-PHP and MySQL
  • Mounting configuration files and injecting environment variables securely
  • Exposing the application using NodePort and MySQL via ClusterIP
  • Copying and configuring index.php to dynamically connect to MySQL using environment variables

By the end of this video, you'll be able to deploy and access a live PHP website on Kubernetes with proper configuration and security practices.



No comments:

Post a Comment