Sunday, 19 October 2025

Deploy a Secure LEMP Stack on Kubernetes with Secrets, ConfigMaps & Environment Variables

Our course you can check :-   Udemy course  


Ques:-   

DevOps team want to deploy a static website on Kubernetes cluster. They are going to use Nginx, phpfpm and MySQL for the database. The team had already gathered the requirements and now they want to make this website live. Below you can find more details:

Create some secrets for MySQL.

Create a secret named mysql-root-pass with key/value pairs as below:

name: password

value: R00t

Create a secret named mysql-user-pass with key/value pairs as below:

name: username

value: kodekloud_sam

name: password

value: Rc5C9EyvbU

Create a secret named mysql-db-url with key/value pairs as below:

name: database

value: kodekloud_db5

Create a secret named mysql-host with key/value pairs as below:

name: host

value: mysql-service

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

Create a deployment named lemp-wp.

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

5) Add some environment variables for both containers:

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 lemp-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.

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

Copy this file into the nginx container under 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.


Ans:-

Here is your generated Kubernetes YAML manifest for deploying the LEMP stack with:

  • Secrets for MySQL credentials
  • A php-config ConfigMap
  • A lemp-wp Deployment with two containers (Nginx+PHP and MySQL)
  • Environment variables sourced from secrets
  • Services for both the web app and MySQL


raj@jumphost ~$ cat pod.yaml


---

apiVersion: v1

kind: Secret

metadata:

  name: mysql-root-pass

type: Opaque

stringData:

  password: R00t


---

apiVersion: v1

kind: Secret

metadata:

  name: mysql-user-pass

type: Opaque

stringData:

  username: kodekloud_sam

  password: Rc5C9EyvbU


---

apiVersion: v1

kind: Secret

metadata:

  name: mysql-db-url

type: Opaque

stringData:

  database: kodekloud_db5


---

apiVersion: v1

kind: Secret

metadata:

  name: mysql-host

type: Opaque

stringData:

  host: mysql-service


---

apiVersion: v1

kind: ConfigMap

metadata:

  name: php-config

data:

  php.ini: |

    variables_order = "EGPCS"


---

apiVersion: apps/v1

kind: Deployment

metadata:

  name: lemp-wp

spec:

  replicas: 1

  selector:

    matchLabels:

      app: lemp-wp

  template:

    metadata:

      labels:

        app: lemp-wp

    spec:

      containers:

        - name: nginx-php-container

          image: webdevops/php-nginx:alpine-3-php7

          volumeMounts:

            - name: php-config-volume

              mountPath: /opt/docker/etc/php/php.ini

              subPath: php.ini

            - name: app-volume

              mountPath: /app

          env:

            - name: MYSQL_ROOT_PASSWORD

              valueFrom:

                secretKeyRef:

                  name: mysql-root-pass

                  key: password

            - name: MYSQL_DATABASE

              valueFrom:

                secretKeyRef:

                  name: mysql-db-url

                  key: database

            - name: MYSQL_USER

              valueFrom:

                secretKeyRef:

                  name: mysql-user-pass

                  key: username

            - name: MYSQL_PASSWORD

              valueFrom:

                secretKeyRef:

                  name: mysql-user-pass

                  key: password

            - name: MYSQL_HOST

              valueFrom:

                secretKeyRef:

                  name: mysql-host

                  key: host

        - name: mysql-container

          image: mysql:5.6

          env:

            - name: MYSQL_ROOT_PASSWORD

              valueFrom:

                secretKeyRef:

                  name: mysql-root-pass

                  key: password

            - name: MYSQL_DATABASE

              valueFrom:

                secretKeyRef:

                  name: mysql-db-url

                  key: database

            - name: MYSQL_USER

              valueFrom:

                secretKeyRef:

                  name: mysql-user-pass

                  key: username

            - name: MYSQL_PASSWORD

              valueFrom:

                secretKeyRef:

                  name: mysql-user-pass

                  key: password

            - name: MYSQL_HOST

              valueFrom:

                secretKeyRef:

                  name: mysql-host

                  key: host

      volumes:

        - name: php-config-volume

          configMap:

            name: php-config

        - name: app-volume

          emptyDir: {}


---

apiVersion: v1

kind: Service

metadata:

  name: lemp-service

spec:

  type: NodePort

  selector:

    app: lemp-wp

  ports:

    - protocol: TCP

      port: 80

      targetPort: 80

      nodePort: 30008


---

apiVersion: v1

kind: Service

metadata:

  name: mysql-service

spec:

  selector:

    app: lemp-wp

  ports:

    - protocol: TCP

      port: 3306

      targetPort: 3306



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

secret/mysql-root-pass created

secret/mysql-user-pass created

secret/mysql-db-url created

secret/mysql-host created

configmap/php-config created

deployment.apps/lemp-wp created

service/lemp-service created

service/mysql-service created


raj@jumphost ~$ kubectl get all

NAME                           READY   STATUS              RESTARTS   AGE

pod/lemp-wp-7c544f45f5-zdwbs   2/2     Running              0          15s


NAME                    TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE

service/kubernetes      ClusterIP   10.96.0.1       <none>        443/TCP        14m

service/lemp-service    NodePort    10.96.206.255   <none>        80:30008/TCP   15s

service/mysql-service   ClusterIP   10.96.66.225    <none>        3306/TCP       15s


NAME                      READY   UP-TO-DATE   AVAILABLE   AGE

deployment.apps/lemp-wp   1/1     1            1           15s


NAME                                 DESIRED   CURRENT   READY   AGE

replicaset.apps/lemp-wp-7c544f45f5   1         1         1       15s


Manually modify index.php on your jump host: Replace hardcoded MySQL values with environment variable references like this:

raj@jumphost ~$ cd /tmp

raj@jumphost /tmp$ cat index2.php


<?php

$dbname = getenv("MYSQL_DATABASE");

$dbuser = getenv("MYSQL_USER");

$dbpass = getenv("MYSQL_PASSWORD");

$dbhost = getenv("MYSQL_HOST");


$connect = mysqli_connect($dbhost, $dbuser, $dbpass, $dbname);


if (!$connect) {

    die("Connection failed: " . mysqli_connect_error());

}


$test_query = "SHOW TABLES FROM $dbname";

$result = mysqli_query($connect, $test_query);


if (!$result) {

    die("Query failed: " . mysqli_error($connect));

}


echo "Connected successfully and query executed.";

?>


Copy the file into the running container:

raj@jumphost /tmp$ kubectl cp index2.php lemp-wp-7c544f45f5-zdwbs:/app -c nginx-php-container


raj@jumphost /tmp$ kubectl exec -it lemp-wp-7c544f45f5-zdwbs -c nginx-php-container -- bash


bash-4.3# cd /app

bash-4.3# pwd

/app

bash-4.3# ls

index2.php

bash-4.3# mv index2.php index.php

bash-4.3# ls

index.php

bash-4.3# 




Conclusion:-

In this hands-on DevOps tutorial, you'll learn how to deploy a secure LEMP stack (Linux, Nginx, MySQL, PHP) on a Kubernetes cluster. This course walks you through:

  • Creating and managing Kubernetes Secrets for MySQL credentials
  • Using ConfigMaps to configure PHP settings
  • Deploying a multi-container Deployment with Nginx, PHP-FPM, and MySQL
  • Injecting secrets into containers using environment variables
  • Mounting configuration files into containers
  • Exposing your static website using a NodePort service
  • Dynamically configuring your PHP application using environment variables

By the end of this video, you'll have a fully functional and secure LEMP-based static website running on Kubernetes — a must-have skill for any aspiring DevOps engineer.

No comments:

Post a Comment