<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Thu Kha Kyawe</title>
    <description>The latest articles on DEV Community by Thu Kha Kyawe (@thukhakyawe_cloud).</description>
    <link>https://dev.to/thukhakyawe_cloud</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3601335%2Fd44a63a0-36bb-4c80-a1f0-1d55fd8ccc1c.png</url>
      <title>DEV Community: Thu Kha Kyawe</title>
      <link>https://dev.to/thukhakyawe_cloud</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/thukhakyawe_cloud"/>
    <language>en</language>
    <item>
      <title>7.Kubernetes LEMP Setup</title>
      <dc:creator>Thu Kha Kyawe</dc:creator>
      <pubDate>Fri, 24 Jul 2026 15:14:35 +0000</pubDate>
      <link>https://dev.to/thukhakyawe_cloud/7kubernetes-lemp-setup-41g3</link>
      <guid>https://dev.to/thukhakyawe_cloud/7kubernetes-lemp-setup-41g3</guid>
      <description>&lt;h1&gt;
  
  
  Lab Information
&lt;/h1&gt;

&lt;p&gt;The Nautilus 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:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create some secrets for MySQL.

Create a secret named mysql-root-pass wih key/value pairs as below:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;name: password&lt;br&gt;
value: R00t&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create a secret named mysql-user-pass with key/value pairs as below:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;name: username&lt;br&gt;
value: kodekloud_cap&lt;/p&gt;

&lt;p&gt;name: password&lt;br&gt;
value: Rc5C9EyvbU&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create a secret named mysql-db-url with key/value pairs as below:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;name: database&lt;br&gt;
value: kodekloud_db8&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create a secret named mysql-host with key/value pairs as below:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;name: host&lt;br&gt;
value: mysql-service&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;5) Add some environment variables for both containers:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;6) Create a node port type service lemp-service to expose the web application, nodePort must be 30008.&lt;/p&gt;

&lt;p&gt;7) Create a service for mysql named mysql-service and its port must be 3306.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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.

    Once done, you must be able to access this website using Website button on the top bar, please note that you should see Connected successfully message while accessing this page.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Note: The kubectl on jump_host has been configured to work with the kubernetes cluster.&lt;/p&gt;


&lt;h1&gt;
  
  
  Lab Solutions
&lt;/h1&gt;
&lt;h1&gt;
  
  
  Step 1: Create Secrets using YAML files
&lt;/h1&gt;
&lt;h3&gt;
  
  
  Create yaml file by using &lt;code&gt;vi&lt;/code&gt; commands
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;mysql-root-pass-secret.yaml
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: v1
kind: Secret
metadata:
  name: mysql-root-pass
type: Opaque
data:
  password: UjAwdA==  # R00t base64 encoded
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;mysql-user-pass-secret.yaml
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: v1
kind: Secret
metadata:
  name: mysql-user-pass
type: Opaque
data:
  username: a29kZWtsb3VkX2NhcA==  # kodekloud_cap base64 encoded
  password: UmM1QzlFeXZiVQ==       # Rc5C9EyvbU base64 encoded
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;mysql-db-url-secret.yaml
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: v1
kind: Secret
metadata:
  name: mysql-db-url
type: Opaque
data:
  database: a29kZWtsb3VkX2RiOA==  # kodekloud_db8 base64 encoded
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;mysql-host-secret.yaml
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: v1
kind: Secret
metadata:
  name: mysql-host
type: Opaque
data:
  host: bXlzcWwtc2VydmljZQ==  # mysql-service base64 encoded
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Apply the secrets:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl apply -f mysql-root-pass-secret.yaml
kubectl apply -f mysql-user-pass-secret.yaml
kubectl apply -f mysql-db-url-secret.yaml
kubectl apply -f mysql-host-secret.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frzkggun9eui4gnzwrdzg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frzkggun9eui4gnzwrdzg.png" alt=" " width="509" height="233"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 2: Create ConfigMap using YAML file
&lt;/h1&gt;

&lt;p&gt;php-config-configmap.yaml&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: v1
kind: ConfigMap
metadata:
  name: php-config
data:
  php.ini: |
    variables_order = "EGPCS"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply the configmap:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl apply -f php-config-configmap.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F838x8titd1qsfi0pplhi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F838x8titd1qsfi0pplhi.png" alt=" " width="497" height="63"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 3: Create the Deployment
&lt;/h1&gt;

&lt;p&gt;lemp-wp-deployment.yaml&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: apps/v1
kind: Deployment
metadata:
  name: lemp-wp
spec:
  selector:
    matchLabels:
      app: lemp-wp
  template:
    metadata:
      labels:
        app: lemp-wp
    spec:
      containers:
      # Nginx-PHP container
      - name: nginx-php-container
        image: webdevops/php-nginx:alpine-3-php7
        volumeMounts:
        - name: php-config
          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

      # MySQL container
      - 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

      volumes:
      - name: php-config
        configMap:
          name: php-config
      - name: app-volume
        emptyDir: {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply the deployment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl apply -f lemp-wp-deployment.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkujf89in71kqhm7nozo5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkujf89in71kqhm7nozo5.png" alt=" " width="497" height="63"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 4: Create Services
&lt;/h1&gt;

&lt;p&gt;services.yaml&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply the services:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl apply -f services.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6rwqoya4t2o2tmlj0wkw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6rwqoya4t2o2tmlj0wkw.png" alt=" " width="415" height="79"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 5: Copy and Modify index.php
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat /tmp/index.php 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F28eqdsl1p2wo2zlngfsi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F28eqdsl1p2wo2zlngfsi.png" alt=" " width="799" height="321"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo chmod 777 /tmp/index.php   **Password:** `mjolnir123
vi index.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn5n4fxh7n5wm34vb4uzb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn5n4fxh7n5wm34vb4uzb.png" alt=" " width="557" height="199"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?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());
}
echo "Connected successfully";
?&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy the file to the container:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Get the pod name
POD_NAME=$(kubectl get pods -l app=lemp-wp -o jsonpath='{.items[0].metadata.name}')

# Copy the modified file
kubectl cp /tmp/index.php $POD_NAME:/app -c nginx-php-container
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxhlw9utcnobbred817cn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxhlw9utcnobbred817cn.png" alt=" " width="800" height="60"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 6: Verify Resources
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl get secret mysql-root-pass mysql-user-pass mysql-db-url mysql-host
kubectl get configmap php-config
kubectl get deploy lemp-wp
kubectl get pod -l app=lemp-wp
kubectl get svc lemp-service mysql-service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn5p3zbwed31qat8q40a7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn5p3zbwed31qat8q40a7.png" alt=" " width="738" height="119"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft7j3ye2t71x5ddd7dp5k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft7j3ye2t71x5ddd7dp5k.png" alt=" " width="738" height="119"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgqe3olpuhdgib3h33cmm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgqe3olpuhdgib3h33cmm.png" alt=" " width="406" height="61"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnx7z5c98vqrh7b0shooc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnx7z5c98vqrh7b0shooc.png" alt=" " width="406" height="61"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbpet4hhc29yiwze20hc0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbpet4hhc29yiwze20hc0.png" alt=" " width="644" height="82"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 7: Verify Application Accessibility
&lt;/h1&gt;

&lt;p&gt;Access the Application:&lt;/p&gt;

&lt;p&gt;Click the Website button in the lab interface.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fumze90hq2sh8qnu3ginc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fumze90hq2sh8qnu3ginc.png" alt=" " width="644" height="82"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Resources &amp;amp; Next Steps&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  📦 Full Code Repository: &lt;a href="https://github.com/thukhakyawe/100-Days-Of-DevOps-KodeKloud-Challenges-Solutions" rel="noopener noreferrer"&gt;KodeKloud Learning Labs&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💬 Join Discussion: &lt;a href="https://dev.to/thukhakyawe_cloud"&gt;DEV Community&lt;/a&gt; - Share your thoughts and questions
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💼 Let's Connect: &lt;a href="https://www.linkedin.com/in/thukhakyawe/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; - I'd love to connect with you
&lt;/h5&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Credits&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • All labs are from: &lt;a href="https://kodekloud.com/" rel="noopener noreferrer"&gt;KodeKloud&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • I sincerely appreciate your provision of these valuable resources.
&lt;/h5&gt;




</description>
      <category>kodekloud</category>
      <category>kubernetes</category>
    </item>
    <item>
      <title>6.Environment Variables in Kubernetes</title>
      <dc:creator>Thu Kha Kyawe</dc:creator>
      <pubDate>Fri, 24 Jul 2026 15:02:09 +0000</pubDate>
      <link>https://dev.to/thukhakyawe_cloud/6environment-variables-in-kubernetes-2bda</link>
      <guid>https://dev.to/thukhakyawe_cloud/6environment-variables-in-kubernetes-2bda</guid>
      <description>&lt;h1&gt;
  
  
  Lab Information
&lt;/h1&gt;

&lt;p&gt;There are a number of parameters that are used by the applications. We need to define these as environment variables, so that we can use them as needed within different configs. Below is a scenario which needs to be configured on Kubernetes cluster. Please find below more details about the same.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create a pod named envars.

Container name should be fieldref-container, use image busybox preferable latest tag, use command 'sh', '-c' and args should be
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;'while true; do&lt;br&gt;
      echo -en '/n';&lt;br&gt;
                                  printenv NODE_NAME POD_NAME;&lt;br&gt;
                                  printenv POD_IP POD_SERVICE_ACCOUNT;&lt;br&gt;
              sleep 10;&lt;br&gt;
         done;'&lt;/p&gt;

&lt;p&gt;(Note: please take care of indentations)&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Define Four environment variables as mentioned below:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;a.) The first env should be named as NODE_NAME, set valueFrom fieldref and fieldPath should be spec.nodeName.&lt;/p&gt;

&lt;p&gt;b.) The second env should be named as POD_NAME, set valueFrom fieldref and fieldPath should be metadata.name.&lt;/p&gt;

&lt;p&gt;c.) The third env should be named as POD_IP, set valueFrom fieldref and fieldPath should be status.podIP.&lt;/p&gt;

&lt;p&gt;d.) The fourth env should be named as POD_SERVICE_ACCOUNT, set valueFrom fieldref and fieldPath shoulbe be spec.serviceAccountName.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Set restart policy to Never.

To check the output, exec into the pod and use printenv command.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Note: The kubectl utility on jump_host has been configured to work with the kubernetes cluster.&lt;/p&gt;


&lt;h1&gt;
  
  
  Lab Solutions
&lt;/h1&gt;
&lt;h1&gt;
  
  
  Step 1: Create the Pod Configuration
&lt;/h1&gt;

&lt;p&gt;Create a file named envars-pod.yaml:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: v1
kind: Pod
metadata:
  name: envars
spec:
  containers:
  - name: fieldref-container
    image: busybox:latest
    command: 
      - 'sh'
      - '-c'
    args:
      - |
        while true; do
          echo -en '\n';
          printenv NODE_NAME POD_NAME;
          printenv POD_IP POD_SERVICE_ACCOUNT;
          sleep 10;
        done;
    env:
    - name: NODE_NAME
      valueFrom:
        fieldRef:
          fieldPath: spec.nodeName
    - name: POD_NAME
      valueFrom:
        fieldRef:
          fieldPath: metadata.name
    - name: POD_IP
      valueFrom:
        fieldRef:
          fieldPath: status.podIP
    - name: POD_SERVICE_ACCOUNT
      valueFrom:
        fieldRef:
          fieldPath: spec.serviceAccountName
  restartPolicy: Never
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Step 2: Apply the Pod Configuration
&lt;/h1&gt;

&lt;p&gt;Deploy the pod to the Kubernetes cluster:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl apply -f envars-pod.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7bcds5bejvuefczip4pk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7bcds5bejvuefczip4pk.png" alt=" " width="425" height="98"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 3: Verify the Pod is Running
&lt;/h1&gt;

&lt;p&gt;Check the pod status:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl get pods
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6skesx7xb3f4m5w1vwp7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6skesx7xb3f4m5w1vwp7.png" alt=" " width="359" height="68"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 4: Check the Pod Logs
&lt;/h1&gt;

&lt;p&gt;Since the container is running a continuous loop that prints environment variables, you can check the logs to see the output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl logs envars
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fo64ccupiicp3yfad70b7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fo64ccupiicp3yfad70b7.png" alt=" " width="336" height="121"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 5: Exec into the Pod and Verify Environment Variables
&lt;/h1&gt;

&lt;p&gt;Execute into the pod to manually check the environment variables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl exec -it envars -- /bin/sh

#Once inside the container, run:
printenv

#Exit the container:
exit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjcgh3dx2jyjdx850rgqx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjcgh3dx2jyjdx850rgqx.png" alt=" " width="577" height="409"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 6: Detailed Verification
&lt;/h1&gt;

&lt;p&gt;Let's verify all components are correctly configured:&lt;br&gt;
Check pod details:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl describe pod envars
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;thor@jumphost ~$ kubectl describe pod envars
Name:             envars
Namespace:        default
Priority:         0
Service Account:  default
Node:             kodekloud-control-plane/172.17.0.2
Start Time:       Tue, 04 Nov 2025 10:37:43 +0000
Labels:           &amp;lt;none&amp;gt;
Annotations:      &amp;lt;none&amp;gt;
Status:           Running
IP:               10.244.0.5
IPs:
  IP:  10.244.0.5
Containers:
  fieldref-container:
    Container ID:  containerd://5c07316533aab139456369be9719d5d5bf8b25850aa7123700ee6e0af29277d4
    Image:         busybox:latest
    Image ID:      docker.io/library/busybox@sha256:e3652a00a2fabd16ce889f0aa32c38eec347b997e73bd09e69c962ec7f8732ee
    Port:          &amp;lt;none&amp;gt;
    Host Port:     &amp;lt;none&amp;gt;
    Command:
      sh
      -c
    Args:
      while true; do
        echo -en '\n';
        printenv NODE_NAME POD_NAME;
        printenv POD_IP POD_SERVICE_ACCOUNT;
        sleep 10;
      done;

    State:          Running
      Started:      Tue, 04 Nov 2025 10:37:44 +0000
    Ready:          True
    Restart Count:  0
    Environment:
      NODE_NAME:             (v1:spec.nodeName)
      POD_NAME:             envars (v1:metadata.name)
      POD_IP:                (v1:status.podIP)
      POD_SERVICE_ACCOUNT:   (v1:spec.serviceAccountName)
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-mvs4m (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:
  kube-api-access-mvs4m:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       &amp;lt;nil&amp;gt;
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              &amp;lt;none&amp;gt;
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type    Reason     Age    From               Message
  ----    ------     ----   ----               -------
  Normal  Scheduled  3m20s  default-scheduler  Successfully assigned default/envars to kodekloud-control-plane
  Normal  Pulling    3m19s  kubelet            Pulling image "busybox:latest"
  Normal  Pulled     3m19s  kubelet            Successfully pulled image "busybox:latest" in 315.653926ms (315.66919ms including waiting)
  Normal  Created    3m19s  kubelet            Created container fieldref-container
  Normal  Started    3m19s  kubelet            Started container fieldref-container
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check the environment variables in the pod spec:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl get pod envars -o yaml | grep -A 20 "env:"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv10pwxbqza3h2mghg5cr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv10pwxbqza3h2mghg5cr.png" alt=" " width="565" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 7: Understanding the Field References
&lt;/h1&gt;

&lt;p&gt;The environment variables are set using Downward API field references:&lt;/p&gt;

&lt;p&gt;NODE_NAME: spec.nodeName - Gets the name of the node where the pod is running&lt;/p&gt;

&lt;p&gt;POD_NAME: metadata.name - Gets the name of the pod (envars)&lt;/p&gt;

&lt;p&gt;POD_IP: status.podIP - Gets the IP address assigned to the pod&lt;/p&gt;

&lt;p&gt;POD_SERVICE_ACCOUNT: spec.serviceAccountName - Gets the service account name (defaults to default)&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 8: Continuous Monitoring
&lt;/h1&gt;

&lt;p&gt;To watch the logs in real-time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl logs envars -f
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Press Ctrl+C to exit the log view.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fimuue8cfevexkhkddbqq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fimuue8cfevexkhkddbqq.png" alt=" " width="343" height="120"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Resources &amp;amp; Next Steps&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  📦 Full Code Repository: &lt;a href="https://github.com/thukhakyawe/100-Days-Of-DevOps-KodeKloud-Challenges-Solutions" rel="noopener noreferrer"&gt;KodeKloud Learning Labs&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💬 Join Discussion: &lt;a href="https://dev.to/thukhakyawe_cloud"&gt;DEV Community&lt;/a&gt; - Share your thoughts and questions
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💼 Let's Connect: &lt;a href="https://www.linkedin.com/in/thukhakyawe/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; - I'd love to connect with you
&lt;/h5&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Credits&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • All labs are from: &lt;a href="https://kodekloud.com/" rel="noopener noreferrer"&gt;KodeKloud&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • I sincerely appreciate your provision of these valuable resources.
&lt;/h5&gt;




</description>
      <category>kubernetes</category>
      <category>kodekloud</category>
    </item>
    <item>
      <title>5.Manage Secrets in Kubernetes</title>
      <dc:creator>Thu Kha Kyawe</dc:creator>
      <pubDate>Fri, 24 Jul 2026 14:57:04 +0000</pubDate>
      <link>https://dev.to/thukhakyawe_cloud/5manage-secrets-in-kubernetes-1gl3</link>
      <guid>https://dev.to/thukhakyawe_cloud/5manage-secrets-in-kubernetes-1gl3</guid>
      <description>&lt;h1&gt;
  
  
  Lab Information
&lt;/h1&gt;

&lt;p&gt;The Nautilus DevOps team is working to deploy some tools in Kubernetes cluster. Some of the tools are licence based so that licence information needs to be stored securely within Kubernetes cluster. Therefore, the team wants to utilize Kubernetes secrets to store those secrets. Below you can find more details about the requirements:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;We already have a secret key file official.txt under /opt location on jump host. Create a generic secret named official, it should contain the password/license-number present in official.txt file.

Also create a pod named secret-devops.

Configure pod's spec as container name should be secret-container-devops, image should be fedora with latest tag (remember to mention the tag with image). Use sleep command for container so that it remains in running state. Consume the created secret and mount it under /opt/demo within the container.

To verify you can exec into the container secret-container-devops, to check the secret key under the mounted path /opt/demo. Before hitting the Check button please make sure pod/pods are in running state, also validation can take some time to complete so keep patience.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Note: The kubectl utility on jump_host has been configured to work with the kubernetes cluster.&lt;/p&gt;




&lt;h1&gt;
  
  
  Lab Solutions
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Step 1: Check the Secret Key File
&lt;/h1&gt;

&lt;p&gt;First, let's verify the content of the official.txt file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat /opt/official.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will show you the password/license-number that needs to be stored as a secret.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 2: Create the Kubernetes Secret
&lt;/h1&gt;

&lt;p&gt;Create a generic secret named official from the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl create secret generic official --from-file=official=/opt/official.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8zpa9qhukdue2g4sl9rj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8zpa9qhukdue2g4sl9rj.png" alt=" " width="795" height="119"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 3: Verify the Secret was Created
&lt;/h1&gt;

&lt;p&gt;Check if the secret was created successfully:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl get secrets
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpju2m83fx6m1pfdgi2xc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpju2m83fx6m1pfdgi2xc.png" alt=" " width="315" height="65"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To see more details:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl describe secret official
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdcbrogugzy0hjh6x2pid.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdcbrogugzy0hjh6x2pid.png" alt=" " width="417" height="212"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 4: Create the Pod Configuration
&lt;/h1&gt;

&lt;p&gt;Create a file named secret-devops.yaml:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: v1
kind: Pod
metadata:
  name: secret-devops
spec:
  containers:
  - name: secret-container-devops
    image: fedora:latest
    command: ["/bin/bash", "-c", "sleep infinity"]
    volumeMounts:
    - name: secret-volume
      mountPath: /opt/demo
      readOnly: true
  volumes:
  - name: secret-volume
    secret:
      secretName: official
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Step 5: Deploy the Pod
&lt;/h1&gt;

&lt;p&gt;Apply the pod configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl apply -f secret-devops.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F44u4dud5y9ocgo8fjw9v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F44u4dud5y9ocgo8fjw9v.png" alt=" " width="433" height="59"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 6: Verify the Pod is Running
&lt;/h1&gt;

&lt;p&gt;Check the pod status:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl get pods
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3dikcbhverrvmwrs8tpo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3dikcbhverrvmwrs8tpo.png" alt=" " width="404" height="65"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 7: Verify the Secret is Mounted Correctly
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Once the pod is running, execute into the container to verify the secret:
kubectl exec -it secret-devops -- /bin/bash


# Inside the container, check the mounted secret:
ls -la /opt/demo/

# You should see the secret file. Then check its content:
cat /opt/demo/official

# Exit the container:
exit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhg7cxnzvta0rokviar28.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhg7cxnzvta0rokviar28.png" alt=" " width="677" height="235"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Resources &amp;amp; Next Steps&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  📦 Full Code Repository: &lt;a href="https://github.com/thukhakyawe/100-Days-Of-DevOps-KodeKloud-Challenges-Solutions" rel="noopener noreferrer"&gt;KodeKloud Learning Labs&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💬 Join Discussion: &lt;a href="https://dev.to/thukhakyawe_cloud"&gt;DEV Community&lt;/a&gt; - Share your thoughts and questions
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💼 Let's Connect: &lt;a href="https://www.linkedin.com/in/thukhakyawe/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; - I'd love to connect with you
&lt;/h5&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Credits&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • All labs are from: &lt;a href="https://kodekloud.com/" rel="noopener noreferrer"&gt;KodeKloud&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • I sincerely appreciate your provision of these valuable resources.
&lt;/h5&gt;




</description>
      <category>kodekloud</category>
      <category>kubernetes</category>
    </item>
    <item>
      <title>4.Persistent Volumes in Kubernetes</title>
      <dc:creator>Thu Kha Kyawe</dc:creator>
      <pubDate>Fri, 24 Jul 2026 14:52:15 +0000</pubDate>
      <link>https://dev.to/thukhakyawe_cloud/4persistent-volumes-in-kubernetes-4gg4</link>
      <guid>https://dev.to/thukhakyawe_cloud/4persistent-volumes-in-kubernetes-4gg4</guid>
      <description>&lt;h1&gt;
  
  
  Lab Information
&lt;/h1&gt;

&lt;p&gt;The Nautilus DevOps team is working on a Kubernetes template to deploy a web application on the cluster. There are some requirements to create/use persistent volumes to store the application code, and the template needs to be designed accordingly. Please find more details below:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create a PersistentVolume named as pv-devops. Configure the spec as storage class should be manual, set capacity to 5Gi, set access mode to ReadWriteOnce, volume type should be hostPath and set path to /mnt/sysops (this directory is already created, you might not be able to access it directly, so you need not to worry about it).

Create a PersistentVolumeClaim named as pvc-devops. Configure the spec as storage class should be manual, request 1Gi of the storage, set access mode to ReadWriteOnce.

Create a pod named as pod-devops, mount the persistent volume you created with claim name pvc-devops at document root of the web server, the container within the pod should be named as container-devops using image httpd with latest tag only (remember to mention the tag i.e httpd:latest).

Create a node port type service named web-devops using node port 30008 to expose the web server running within the pod.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Note: The kubectl utility on jump_host has been configured to work with the kubernetes cluster.&lt;/p&gt;




&lt;h1&gt;
  
  
  Lab Solutions
&lt;/h1&gt;

&lt;p&gt;Step 2: Create Configuration File&lt;br&gt;
Create a file named devops-deployment.yaml:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Define PersistentVolume for storage
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-devops
spec:
  storageClassName: "manual"
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: /mnt/sysops
---
# Define PersistentVolumeClaim to request storage
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-devops
spec:
  storageClassName: "manual"
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
---
# Define Pod with Apache web server
apiVersion: v1
kind: Pod
metadata:
  name: pod-devops
  labels:
    app: web-devops
spec:
  containers:
    - name: container-devops
      image: httpd:latest
      volumeMounts:
        - mountPath: /usr/local/apache2/htdocs
          name: web-storage
  volumes:
    - name: web-storage
      persistentVolumeClaim:
        claimName: pvc-devops
---
# Define NodePort service to expose the web server
apiVersion: v1
kind: Service
metadata:
  name: web-devops
spec:
  type: NodePort
  selector:
    app: web-devops
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 30008
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Step 2: Apply Configuration
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl apply -f devops-deployment.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8tf35pgaxbgh0tg10851.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8tf35pgaxbgh0tg10851.png" alt=" " width="490" height="98"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 3: Verify PersistentVolume and Claim
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl get pv pv-devops 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verification: Confirm the PersistentVolume is bound to pvc-datacenter.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl get pvc pvc-devops 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjfov9l5xed7ozr8iqtxs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjfov9l5xed7ozr8iqtxs.png" alt=" " width="798" height="123"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 4: Verify Pod
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl get pod pod-devops
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fiaolhoa68vi8kii8pqwh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fiaolhoa68vi8kii8pqwh.png" alt=" " width="405" height="68"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 5: Verify Service
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl get svc web-devops
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyoep0u8g7bp79180snal.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyoep0u8g7bp79180snal.png" alt=" " width="597" height="63"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Verification: Confirm the service uses NodePort 30008.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 6: Verify Application Accessibility
&lt;/h1&gt;

&lt;p&gt;Access the Application:&lt;/p&gt;

&lt;p&gt;Click on the App or Website button in the lab interface.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3zn97cumg2afphbhoqp9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3zn97cumg2afphbhoqp9.png" alt=" " width="800" height="51"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Resources &amp;amp; Next Steps&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  📦 Full Code Repository: &lt;a href="https://github.com/thukhakyawe/100-Days-Of-DevOps-KodeKloud-Challenges-Solutions" rel="noopener noreferrer"&gt;KodeKloud Learning Labs&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💬 Join Discussion: &lt;a href="https://dev.to/thukhakyawe_cloud"&gt;DEV Community&lt;/a&gt; - Share your thoughts and questions
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💼 Let's Connect: &lt;a href="https://www.linkedin.com/in/thukhakyawe/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; - I'd love to connect with you
&lt;/h5&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Credits&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • All labs are from: &lt;a href="https://kodekloud.com/" rel="noopener noreferrer"&gt;KodeKloud&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • I sincerely appreciate your provision of these valuable resources.
&lt;/h5&gt;




</description>
      <category>kubernetes</category>
      <category>kodekloud</category>
    </item>
    <item>
      <title>3.Init Containers in Kubernetes</title>
      <dc:creator>Thu Kha Kyawe</dc:creator>
      <pubDate>Thu, 23 Jul 2026 14:54:45 +0000</pubDate>
      <link>https://dev.to/thukhakyawe_cloud/3init-containers-in-kubernetes-3c84</link>
      <guid>https://dev.to/thukhakyawe_cloud/3init-containers-in-kubernetes-3c84</guid>
      <description>&lt;h1&gt;
  
  
  Lab Information
&lt;/h1&gt;

&lt;p&gt;There are some applications that need to be deployed on Kubernetes cluster and these apps have some pre-requisites where some configurations need to be changed before deploying the app container. Some of these changes cannot be made inside the images so the DevOps team has come up with a solution to use init containers to perform these tasks during deployment. Below is a sample scenario that the team is going to test first.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create a Deployment named as ic-deploy-devops.

Configure spec as replicas should be 1, labels app should be ic-devops, template's metadata lables app should be the same ic-devops.

The initContainers should be named as ic-msg-devops, use image fedora with latest tag and use command '/bin/bash', '-c' and 'echo Init Done - Welcome to xFusionCorp Industries &amp;gt; /ic/blog'. The volume mount should be named as ic-volume-devops and mount path should be /ic.

Main container should be named as ic-main-devops, use image fedora with latest tag and use command '/bin/bash', '-c' and 'while true; do cat /ic/blog; sleep 5; done'. The volume mount should be named as ic-volume-devops and mount path should be /ic.

Volume to be named as ic-volume-devops and it should be an emptyDir type.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Note: The kubectl utility on jump_host has been configured to work with the kubernetes cluster.&lt;/p&gt;




&lt;h1&gt;
  
  
  Lab Solutions
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Step 1: Create the Deployment YAML File
&lt;/h1&gt;

&lt;p&gt;Create a file named ic-deploy-devops.yaml with the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: apps/v1
kind: Deployment
metadata:
  name: ic-deploy-devops
spec:
  replicas: 1
  selector:
    matchLabels:
      app: ic-devops
  template:
    metadata:
      labels:
        app: ic-devops
    spec:
      initContainers:
      - name: ic-msg-devops
        image: fedora:latest
        command: ['/bin/bash', '-c', 'echo Init Done - Welcome to xFusionCorp Industries &amp;gt; /ic/blog']
        volumeMounts:
        - name: ic-volume-devops
          mountPath: /ic
      containers:
      - name: ic-main-devops
        image: fedora:latest
        command: ['/bin/bash', '-c', 'while true; do cat /ic/blog; sleep 5; done']
        volumeMounts:
        - name: ic-volume-devops
          mountPath: /ic
      volumes:
      - name: ic-volume-devops
        emptyDir: {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Step 2: Apply the Deployment
&lt;/h1&gt;

&lt;p&gt;Deploy the configuration to your Kubernetes cluster:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl apply -f ic-deploy-devops.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F55zyybhve7rl8xdo8icq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F55zyybhve7rl8xdo8icq.png" alt=" " width="473" height="96"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 3: Verify the Deployment
&lt;/h1&gt;

&lt;p&gt;Check if the deployment was created successfully:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl get deployment ic-deploy-devops
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkgor58w01j253oo717f3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkgor58w01j253oo717f3.png" alt=" " width="464" height="64"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 4: Check the Pod Status
&lt;/h1&gt;

&lt;p&gt;Monitor the pod creation and init container execution:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl get pods -l app=ic-devops
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flvowqfre3ja41ri68g6g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flvowqfre3ja41ri68g6g.png" alt=" " width="563" height="64"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 5: Verify Init Container Execution
&lt;/h1&gt;

&lt;p&gt;Check the init container logs to ensure it ran successfully:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Get the pod name first
POD_NAME=$(kubectl get pods -l app=ic-devops -o jsonpath='{.items[0].metadata.name}')

# Check init container logs
kubectl logs $POD_NAME -c ic-msg-devops
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Step 6: Verify Main Container Operation
&lt;/h1&gt;

&lt;p&gt;Check the main container logs to see the continuous output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl logs $POD_NAME -c ic-main-devops
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqu8jhtf0vl3eix6gbzvh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqu8jhtf0vl3eix6gbzvh.png" alt=" " width="498" height="44"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The main container should be printing the message every 5 seconds.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 7: Detailed Verification
&lt;/h1&gt;

&lt;p&gt;Let's verify all components are correctly configured:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Check the deployment details:
kubectl describe deployment ic-deploy-devops

# Check the pod details:
kubectl describe pod $POD_NAME

# Verify the volume mount:
kubectl exec $POD_NAME -c ic-main-devops -- ls -la /ic/

# Check the file content directly:
kubectl exec $POD_NAME -c ic-main-devops -- cat /ic/blog
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;thor@jumphost ~$ kubectl describe deployment ic-deploy-devops
Name:                   ic-deploy-devops
Namespace:              default
CreationTimestamp:      Fri, 31 Oct 2025 13:43:39 +0000
Labels:                 &amp;lt;none&amp;gt;
Annotations:            deployment.kubernetes.io/revision: 1
Selector:               app=ic-devops
Replicas:               1 desired | 1 updated | 1 total | 1 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  app=ic-devops
  Init Containers:
   ic-msg-devops:
    Image:      fedora:latest
    Port:       &amp;lt;none&amp;gt;
    Host Port:  &amp;lt;none&amp;gt;
    Command:
      /bin/bash
      -c
      echo Init Done - Welcome to xFusionCorp Industries &amp;gt; /ic/blog
    Environment:  &amp;lt;none&amp;gt;
    Mounts:
      /ic from ic-volume-devops (rw)
  Containers:
   ic-main-devops:
    Image:      fedora:latest
    Port:       &amp;lt;none&amp;gt;
    Host Port:  &amp;lt;none&amp;gt;
    Command:
      /bin/bash
      -c
      while true; do cat /ic/blog; sleep 5; done
    Environment:  &amp;lt;none&amp;gt;
    Mounts:
      /ic from ic-volume-devops (rw)
  Volumes:
   ic-volume-devops:
    Type:          EmptyDir (a temporary directory that shares a pod's lifetime)
    Medium:        
    SizeLimit:     &amp;lt;unset&amp;gt;
  Node-Selectors:  &amp;lt;none&amp;gt;
  Tolerations:     &amp;lt;none&amp;gt;
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  &amp;lt;none&amp;gt;
NewReplicaSet:   ic-deploy-devops-68789fbb69 (1/1 replicas created)
Events:
  Type    Reason             Age    From                   Message
  ----    ------             ----   ----                   -------
  Normal  ScalingReplicaSet  3m55s  deployment-controller  Scaled up replica set ic-deploy-devops-68789fbb69 to 1
thor@jumphost ~$ kubectl describe pod $POD_NAME
Name:             ic-deploy-devops-68789fbb69-n46fh
Namespace:        default
Priority:         0
Service Account:  default
Node:             kodekloud-control-plane/172.17.0.2
Start Time:       Fri, 31 Oct 2025 13:43:39 +0000
Labels:           app=ic-devops
                  pod-template-hash=68789fbb69
Annotations:      &amp;lt;none&amp;gt;
Status:           Running
IP:               10.244.0.5
IPs:
  IP:           10.244.0.5
Controlled By:  ReplicaSet/ic-deploy-devops-68789fbb69
Init Containers:
  ic-msg-devops:
    Container ID:  containerd://fda2d6a406793fce4784b97fbd48e04fc4562a26b6153f877bedff8460ffa44e
    Image:         fedora:latest
    Image ID:      docker.io/library/fedora@sha256:aa7befe5cfd1f0e062728c16453cd1c479d4134c7b85eac00172f3025ab0d522
    Port:          &amp;lt;none&amp;gt;
    Host Port:     &amp;lt;none&amp;gt;
    Command:
      /bin/bash
      -c
      echo Init Done - Welcome to xFusionCorp Industries &amp;gt; /ic/blog
    State:          Terminated
      Reason:       Completed
      Exit Code:    0
      Started:      Fri, 31 Oct 2025 13:43:46 +0000
      Finished:     Fri, 31 Oct 2025 13:43:46 +0000
    Ready:          True
    Restart Count:  0
    Environment:    &amp;lt;none&amp;gt;
    Mounts:
      /ic from ic-volume-devops (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-mqkwp (ro)
Containers:
  ic-main-devops:
    Container ID:  containerd://dbc7396b61602a895278a5ebf5eb61bc231ef702bd607c39237866dd6c5a5b5a
    Image:         fedora:latest
    Image ID:      docker.io/library/fedora@sha256:aa7befe5cfd1f0e062728c16453cd1c479d4134c7b85eac00172f3025ab0d522
    Port:          &amp;lt;none&amp;gt;
    Host Port:     &amp;lt;none&amp;gt;
    Command:
      /bin/bash
      -c
      while true; do cat /ic/blog; sleep 5; done
    State:          Running
      Started:      Fri, 31 Oct 2025 13:43:47 +0000
    Ready:          True
    Restart Count:  0
    Environment:    &amp;lt;none&amp;gt;
    Mounts:
      /ic from ic-volume-devops (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-mqkwp (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:
  ic-volume-devops:
    Type:       EmptyDir (a temporary directory that shares a pod's lifetime)
    Medium:     
    SizeLimit:  &amp;lt;unset&amp;gt;
  kube-api-access-mqkwp:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       &amp;lt;nil&amp;gt;
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              &amp;lt;none&amp;gt;
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type    Reason     Age    From               Message
  ----    ------     ----   ----               -------
  Normal  Scheduled  4m3s   default-scheduler  Successfully assigned default/ic-deploy-devops-68789fbb69-n46fh to kodekloud-control-plane
  Normal  Pulling    4m2s   kubelet            Pulling image "fedora:latest"
  Normal  Pulled     3m57s  kubelet            Successfully pulled image "fedora:latest" in 5.558670958s (5.558686183s including waiting)
  Normal  Created    3m57s  kubelet            Created container ic-msg-devops
  Normal  Started    3m56s  kubelet            Started container ic-msg-devops
  Normal  Pulling    3m56s  kubelet            Pulling image "fedora:latest"
  Normal  Pulled     3m55s  kubelet            Successfully pulled image "fedora:latest" in 144.822007ms (144.841997ms including waiting)
  Normal  Created    3m55s  kubelet            Created container ic-main-devops
  Normal  Started    3m55s  kubelet            Started container ic-main-devops
thor@jumphost ~$ kubectl exec $POD_NAME -c ic-main-devops -- ls -la /ic/
total 12
drwxrwxrwx 2 root root 4096 Oct 31 13:43 .
drwxr-xr-x 1 root root 4096 Oct 31 13:43 ..
-rw-r--r-- 1 root root   46 Oct 31 13:43 blog
thor@jumphost ~$ kubectl exec $POD_NAME -c ic-main-devops -- cat /ic/blog
Init Done - Welcome to xFusionCorp Industries
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Step 8: Continuous Monitoring
&lt;/h1&gt;

&lt;p&gt;To see the real-time output from the main container:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl logs $POD_NAME -c ic-main-devops -f
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Press Ctrl+C to exit the continuous log view.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr0zz68kil0ybmi9tj5fo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr0zz68kil0ybmi9tj5fo.png" alt=" " width="511" height="48"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Explanation of the Solution&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Init Container (ic-msg-devops):

Runs before the main container starts

Creates a file /ic/blog with the welcome message

Uses the shared volume ic-volume-devops

Main Container (ic-main-devops):

Starts after the init container completes successfully

Reads the file created by the init container every 5 seconds

Shares the same volume mount

Volume (ic-volume-devops):

emptyDir type creates a temporary directory that survives container restarts

Shared between init container and main container

Data persists for the lifetime of the pod

Workflow:

Init container writes message to file → Init container completes → Main container starts → Main container reads file repeatedly
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h5&gt;
  
  
  &lt;strong&gt;Resources &amp;amp; Next Steps&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  📦 Full Code Repository: &lt;a href="https://github.com/thukhakyawe/100-Days-Of-DevOps-KodeKloud-Challenges-Solutions" rel="noopener noreferrer"&gt;KodeKloud Learning Labs&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💬 Join Discussion: &lt;a href="https://dev.to/thukhakyawe_cloud"&gt;DEV Community&lt;/a&gt; - Share your thoughts and questions
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💼 Let's Connect: &lt;a href="https://www.linkedin.com/in/thukhakyawe/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; - I'd love to connect with you
&lt;/h5&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Credits&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • All labs are from: &lt;a href="https://kodekloud.com/" rel="noopener noreferrer"&gt;KodeKloud&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • I sincerely appreciate your provision of these valuable resources.
&lt;/h5&gt;




</description>
      <category>kubernetes</category>
      <category>kodekloud</category>
    </item>
    <item>
      <title>2.Deploy Lamp Stack on Kubernetes Cluster</title>
      <dc:creator>Thu Kha Kyawe</dc:creator>
      <pubDate>Thu, 23 Jul 2026 14:51:19 +0000</pubDate>
      <link>https://dev.to/thukhakyawe_cloud/2deploy-lamp-stack-on-kubernetes-cluster-487f</link>
      <guid>https://dev.to/thukhakyawe_cloud/2deploy-lamp-stack-on-kubernetes-cluster-487f</guid>
      <description>&lt;h1&gt;
  
  
  Lab Information
&lt;/h1&gt;

&lt;p&gt;The Nautilus 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:&lt;/p&gt;

&lt;p&gt;1) Create a config map php-config for php.ini with variables_order = "EGPCS" data.&lt;/p&gt;

&lt;p&gt;2) Create a deployment named lamp-wp.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;5) Add some environment variables for both containers:&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;6) Create a node port type service lamp-service to expose the web application, nodePort must be 30008.&lt;/p&gt;

&lt;p&gt;7) Create a service for mysql named mysql-service and its port must be 3306.&lt;/p&gt;

&lt;p&gt;8) We already have /tmp/index.php file on jump_host server.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Note:&lt;/p&gt;

&lt;p&gt;The kubectl utility on jump_host has been configured to work with the kubernetes cluster.&lt;/p&gt;




&lt;h1&gt;
  
  
  Lab Solutions
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Step 1: Create the ConfigMap for php.ini
&lt;/h1&gt;

&lt;p&gt;First, create the php-config ConfigMap with the required php.ini setting:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl create configmap php-config &lt;span class="nt"&gt;--from-literal&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;php.ini&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'variables_order = "EGPCS"'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the ConfigMap was created:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get configmap php-config &lt;span class="nt"&gt;-o&lt;/span&gt; yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhakktmszm399gcrmdjtc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhakktmszm399gcrmdjtc.png" alt=" " width="799" height="244"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ဋ Step 2: Create MySQL Secrets&lt;/p&gt;

&lt;p&gt;Create a generic secret for MySQL credentials:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl create secret generic mysql-secrets &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--from-literal&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;mysql-root-password&lt;span class="o"&gt;=&lt;/span&gt;rootpass123 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--from-literal&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;mysql-user&lt;span class="o"&gt;=&lt;/span&gt;wpuser &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--from-literal&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;mysql-password&lt;span class="o"&gt;=&lt;/span&gt;wppass123 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--from-literal&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;mysql-database&lt;span class="o"&gt;=&lt;/span&gt;wordpress &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--from-literal&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;mysql-host&lt;span class="o"&gt;=&lt;/span&gt;mysql-service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the secret:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get secret mysql-secrets &lt;span class="nt"&gt;-o&lt;/span&gt; yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd5kbxm3aqkb8mwvvl74f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd5kbxm3aqkb8mwvvl74f.png" alt=" " width="507" height="307"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 3: Create the Deployment
&lt;/h1&gt;

&lt;p&gt;Create a file named lamp-wp-deployment.yaml:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;lamp-wp&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;lamp-wp&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;lamp-wp&lt;/span&gt;
    &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;httpd-php-container&lt;/span&gt;
        &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;webdevops/php-apache:alpine-3-php7&lt;/span&gt;
        &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;containerPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
        &lt;span class="na"&gt;volumeMounts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;php-config&lt;/span&gt;
          &lt;span class="na"&gt;mountPath&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/opt/docker/etc/php/php.ini&lt;/span&gt;
          &lt;span class="na"&gt;subPath&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;php.ini&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;app-volume&lt;/span&gt;
          &lt;span class="na"&gt;mountPath&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/app&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;MYSQL_ROOT_PASSWORD&lt;/span&gt;
          &lt;span class="na"&gt;valueFrom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;secretKeyRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-secrets&lt;/span&gt;
              &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-root-password&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;MYSQL_DATABASE&lt;/span&gt;
          &lt;span class="na"&gt;valueFrom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;secretKeyRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-secrets&lt;/span&gt;
              &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-database&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;MYSQL_USER&lt;/span&gt;
          &lt;span class="na"&gt;valueFrom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;secretKeyRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-secrets&lt;/span&gt;
              &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-user&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;MYSQL_PASSWORD&lt;/span&gt;
          &lt;span class="na"&gt;valueFrom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;secretKeyRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-secrets&lt;/span&gt;
              &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-password&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;MYSQL_HOST&lt;/span&gt;
          &lt;span class="na"&gt;valueFrom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;secretKeyRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-secrets&lt;/span&gt;
              &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-host&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-container&lt;/span&gt;
        &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql:5.6&lt;/span&gt;
        &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;containerPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3306&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;MYSQL_ROOT_PASSWORD&lt;/span&gt;
          &lt;span class="na"&gt;valueFrom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;secretKeyRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-secrets&lt;/span&gt;
              &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-root-password&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;MYSQL_DATABASE&lt;/span&gt;
          &lt;span class="na"&gt;valueFrom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;secretKeyRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-secrets&lt;/span&gt;
              &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-database&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;MYSQL_USER&lt;/span&gt;
          &lt;span class="na"&gt;valueFrom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;secretKeyRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-secrets&lt;/span&gt;
              &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-user&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;MYSQL_PASSWORD&lt;/span&gt;
          &lt;span class="na"&gt;valueFrom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;secretKeyRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-secrets&lt;/span&gt;
              &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-password&lt;/span&gt;
      &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;php-config&lt;/span&gt;
        &lt;span class="na"&gt;configMap&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;php-config&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;app-volume&lt;/span&gt;
        &lt;span class="na"&gt;emptyDir&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply the deployment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; lamp-wp-deployment.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fze9412j0al7b6kr5rck0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fze9412j0al7b6kr5rck0.png" alt=" " width="497" height="63"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 4: Create the Services
&lt;/h1&gt;

&lt;p&gt;Create a file named services.yaml:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Service&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;lamp-service&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;NodePort&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;lamp-wp&lt;/span&gt;
  &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;protocol&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;TCP&lt;/span&gt;
      &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
      &lt;span class="na"&gt;targetPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
      &lt;span class="na"&gt;nodePort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;30008&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Service&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-service&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;lamp-wp&lt;/span&gt;
  &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;protocol&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;TCP&lt;/span&gt;
      &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3306&lt;/span&gt;
      &lt;span class="na"&gt;targetPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3306&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply the services:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; services.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv9f9vrph5e04fq5jvhu2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv9f9vrph5e04fq5jvhu2.png" alt=" " width="407" height="78"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 5: Prepare and Copy index.php
&lt;/h1&gt;

&lt;p&gt;First, let's check the original index.php file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; /tmp/index.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F47w3ozu41fm2gpi2lba3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F47w3ozu41fm2gpi2lba3.png" alt=" " width="798" height="315"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, let's update modified version that uses environment variables. Create a new file /tmp/index-modified.php:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="nv"&gt;$servername&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"MYSQL_HOST"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"MYSQL_USER"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"MYSQL_PASSWORD"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$dbname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"MYSQL_DATABASE"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Create connection&lt;/span&gt;
&lt;span class="nv"&gt;$conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;mysqli&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$servername&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$dbname&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Check connection&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$conn&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;connect_error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;die&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Connection failed: "&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$conn&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;connect_error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Connected successfully"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If permission issues occur, fix them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo chmod &lt;/span&gt;777 /tmp/index.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Password: &lt;code&gt;mjolnir123&lt;/code&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 6: Copy index.php to Apache Container
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nb"&gt;cp&lt;/span&gt; /tmp/index.php lamp-wp-7ccc97bf65-6nhv6:/app/index.php &lt;span class="nt"&gt;-c&lt;/span&gt; httpd-php-container
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Explanation of Commands:

    Command 1: POD=$(kubectl get pod -l app=lamp-app -o jsonpath='{.items[0].metadata.name}')
        Purpose: Retrieves the name of the first pod with the label app=lamp-app and stores it in the POD variable.
        Details:
            kubectl get pod: Lists pods in the current namespace.
            -l app=lamp-app: Filters pods with the label app=lamp-app, matching the deployment's selector.
            -o jsonpath='{.items[0].metadata.name}': Extracts the name of the first pod using JSONPath.
            POD=$(): Stores the pod name (e.g., lamp-wp-5f7b8d4c5-xyz12) in the POD variable.
        Why Needed: Pod names are dynamically generated by Kubernetes, so this command dynamically retrieves the correct pod name for the file copy operation.

    Command 2: kubectl cp /tmp/index.php $POD:/app -c httpd-php-container
        Purpose: Copies the index.php file from the jump host's /tmp directory to the /app directory in the httpd-php-container of the specified pod.
        Details:
            kubectl cp: Copies files between the local filesystem and a container.
            /tmp/index.php: Source file on the jump host.
            $POD:/app: Destination path, where $POD is the pod name and /app is the Apache document root.
            -c httpd-php-container: Specifies the target container within the pod (since the pod has both httpd-php-container and mysql-container).
        Why Needed: The index.php file contains the PHP code for the website, which must be placed in the Apache document root to make the application functional.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Step 7: Verify Deployment and Services
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get configmap php-config
kubectl get secret mysql-secrets
kubectl get deploy lamp-wp
kubectl get pods
kubectl get svc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F45zr5uz0csvorkr5ltub.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F45zr5uz0csvorkr5ltub.png" alt=" " width="800" height="353"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 8: Verify Application Accessibility
&lt;/h1&gt;

&lt;p&gt;Access the Application:&lt;/p&gt;

&lt;p&gt;Click on the App button in the lab interface.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm6bww0yy3vgen7o5pi63.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm6bww0yy3vgen7o5pi63.png" alt=" " width="799" height="70"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Resources &amp;amp; Next Steps&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  📦 Full Code Repository: &lt;a href="https://github.com/thukhakyawe/100-Days-Of-DevOps-KodeKloud-Challenges-Solutions" rel="noopener noreferrer"&gt;KodeKloud Learning Labs&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💬 Join Discussion: &lt;a href="https://dev.to/thukhakyawe_cloud"&gt;DEV Community&lt;/a&gt; - Share your thoughts and questions
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💼 Let's Connect: &lt;a href="https://www.linkedin.com/in/thukhakyawe/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; - I'd love to connect with you
&lt;/h5&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Credits&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • All labs are from: &lt;a href="https://kodekloud.com/" rel="noopener noreferrer"&gt;KodeKloud&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • I sincerely appreciate your provision of these valuable resources.
&lt;/h5&gt;




</description>
      <category>kubernetes</category>
      <category>kodekloud</category>
    </item>
    <item>
      <title>1.Deploy Apache Web Server on Kubernetes Cluster</title>
      <dc:creator>Thu Kha Kyawe</dc:creator>
      <pubDate>Thu, 23 Jul 2026 14:51:02 +0000</pubDate>
      <link>https://dev.to/thukhakyawe_cloud/1deploy-apache-web-server-on-kubernetes-cluster-4bk7</link>
      <guid>https://dev.to/thukhakyawe_cloud/1deploy-apache-web-server-on-kubernetes-cluster-4bk7</guid>
      <description>&lt;h1&gt;
  
  
  Lab Information
&lt;/h1&gt;

&lt;p&gt;There is an application that needs to be deployed on Kubernetes cluster under Apache web server. The Nautilus application development team has asked the DevOps team to deploy it. We need to develop a template as per requirements mentioned below:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create a namespace named as httpd-namespace-devops.

Create a deployment named as httpd-deployment-devops under newly created namespace. For the deployment use httpd image with latest tag only and remember to mention the tag i.e httpd:latest, and make sure replica counts are 2.

Create a service named as httpd-service-devops under same namespace to expose the deployment, nodePort should be 30004.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Note: The kubectl utility on jump_host has been configured to work with the kubernetes cluster.&lt;/p&gt;




&lt;h1&gt;
  
  
  Lab Solutions
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Step 1: Create the Namespace
&lt;/h1&gt;

&lt;p&gt;First, let's create the required namespace:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl create namespace httpd-namespace-devops
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the namespace was created:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get namespaces
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Step 2: Create the Deployment
&lt;/h1&gt;

&lt;p&gt;Create a YAML file for the deployment. Let's create a file called httpd-deployment.yaml:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;cat &amp;gt; httpd-deployment.yaml &amp;lt;&amp;lt; EOF&lt;/span&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;httpd-deployment-devops&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;httpd-namespace-devops&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;httpd-app&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;httpd-app&lt;/span&gt;
    &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;httpd-container&lt;/span&gt;
        &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;httpd:latest&lt;/span&gt;
        &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;containerPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
&lt;span class="s"&gt;EOF&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply the deployment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; httpd-deployment.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5mw8jwoaluo1jast43u3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5mw8jwoaluo1jast43u3.png" alt=" " width="540" height="656"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 3: Create the Service
&lt;/h1&gt;

&lt;p&gt;Create a YAML file for the service. Let's create a file called httpd-service.yaml:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;cat &amp;gt; httpd-service.yaml &amp;lt;&amp;lt; EOF&lt;/span&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Service&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;httpd-service-devops&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;httpd-namespace-devops&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;NodePort&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;httpd-app&lt;/span&gt;
  &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;protocol&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;TCP&lt;/span&gt;
      &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
      &lt;span class="na"&gt;targetPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
      &lt;span class="na"&gt;nodePort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;30004&lt;/span&gt;
&lt;span class="s"&gt;EOF&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply the service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; httpd-service.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkhueeoomsq5rzjzrf3l9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkhueeoomsq5rzjzrf3l9.png" alt=" " width="468" height="345"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 4: Verify All Resources
&lt;/h1&gt;

&lt;p&gt;Let's verify everything was created correctly:&lt;/p&gt;

&lt;p&gt;Check the deployments:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get deployment &lt;span class="nt"&gt;-n&lt;/span&gt; httpd-namespace-devops
kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; httpd-namespace-devops
kubectl get service &lt;span class="nt"&gt;-n&lt;/span&gt; httpd-namespace-devops
kubectl get all &lt;span class="nt"&gt;-n&lt;/span&gt; httpd-namespace-devops
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhwt0eywm68jvp7e3xpmw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhwt0eywm68jvp7e3xpmw.png" alt=" " width="743" height="442"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Resources &amp;amp; Next Steps&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  📦 Full Code Repository: &lt;a href="https://github.com/thukhakyawe/100-Days-Of-DevOps-KodeKloud-Challenges-Solutions" rel="noopener noreferrer"&gt;KodeKloud Learning Labs&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💬 Join Discussion: &lt;a href="https://dev.to/thukhakyawe_cloud"&gt;DEV Community&lt;/a&gt; - Share your thoughts and questions
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💼 Let's Connect: &lt;a href="https://www.linkedin.com/in/thukhakyawe/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; - I'd love to connect with you
&lt;/h5&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Credits&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • All labs are from: &lt;a href="https://kodekloud.com/" rel="noopener noreferrer"&gt;KodeKloud&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • I sincerely appreciate your provision of these valuable resources.
&lt;/h5&gt;




</description>
      <category>kubernetes</category>
      <category>kodekloud</category>
    </item>
    <item>
      <title>Day 19: Complete a Production DVC Pipeline with SeaweedFS Remote</title>
      <dc:creator>Thu Kha Kyawe</dc:creator>
      <pubDate>Sun, 19 Jul 2026 05:10:53 +0000</pubDate>
      <link>https://dev.to/thukhakyawe_cloud/day-19-complete-a-production-dvc-pipeline-with-seaweedfs-remote-17k9</link>
      <guid>https://dev.to/thukhakyawe_cloud/day-19-complete-a-production-dvc-pipeline-with-seaweedfs-remote-17k9</guid>
      <description>&lt;h1&gt;
  
  
  Lab Information
&lt;/h1&gt;

&lt;p&gt;Complete the xFusionCorp Industries fraud-detection production DVC pipeline. Three stages are already wired in dvc.yaml, two remain, and the pipeline must finish as a reproducible, SeaweedFS-backed, v1.0-tagged release.&lt;/p&gt;

&lt;p&gt;A project exists at /root/code/ml-pipeline/ with Git and DVC initialised. The params.yaml is in place and the .dvc/config is pre-configured to push to the SeaweedFS bucket dvc-storage at &lt;a href="http://localhost:8333" rel="noopener noreferrer"&gt;http://localhost:8333&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The ingest, validate, and preprocess stages are already declared in dvc.yaml, but one of them is misconfigured and prevents dvc repro from completing — run dvc repro to see it fail. The two scripts for the remaining stages are pre-staged at /root/code/ml-pipeline/scripts-staging/train.py and scripts-staging/evaluate.py, and belong in scripts/.&lt;/p&gt;

&lt;p&gt;Acceptance criteria:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The misconfigured existing stage is corrected so dvc repro can complete.
Two further stages are declared in dvc.yaml:
    train – Depends on the preprocessed dataset and scripts/train.py; reads n_estimators, max_depth, test_size, and random_seed from params.yaml; outputs models/model.pkl and data/processed/test_split.csv; declares metrics.json as a DVC metric with cache: false.
    evaluate – Depends on models/model.pkl, data/processed/test_split.csv, and scripts/evaluate.py; outputs reports/evaluation.json declared with cache: false.
The full pipeline has been reproduced, the cache pushed to the SeaweedFS remote, and the current state tagged v1.0.
Every change is committed to Git so the release is fully captured.

Open the SeaweedFS Filer button at the top of the lab and navigate to /buckets/dvc-storage/ to confirm that the bucket holds the pushed artefacts under the files/md5/... layout.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;h1&gt;
  
  
  Lab Solutions
&lt;/h1&gt;

&lt;p&gt;✅ Part 1: Lab Step-by-Step Guidelines&lt;/p&gt;

&lt;p&gt;Step 1: Enter the project&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /root/code/ml-pipeline
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 2: Run the pipeline once&lt;/p&gt;

&lt;p&gt;The lab tells you one stage is intentionally broken.&lt;/p&gt;

&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dvc repro
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don't fix anything yet.&lt;/p&gt;

&lt;p&gt;Read the error carefully.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;p&gt;Missing dependency&lt;br&gt;
Output mismatch&lt;br&gt;
Script not found&lt;br&gt;
Wrong filename&lt;/p&gt;

&lt;p&gt;The error will tell you exactly which existing stage is misconfigured.&lt;/p&gt;

&lt;p&gt;Step 3: Inspect the existing pipeline&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;cat dvc.yaml&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;root@controlplane ml-pipeline on  main [?] ✖ cat dvc.yaml&lt;/span&gt;
&lt;span class="na"&gt;stages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;ingest&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;cmd&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;python3 scripts/ingest.py&lt;/span&gt;
    &lt;span class="na"&gt;deps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;scripts/ingest.py&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;data/raw/data.csv&lt;/span&gt;

  &lt;span class="na"&gt;validate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;cmd&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;python3 scripts/validate.py&lt;/span&gt;
    &lt;span class="na"&gt;deps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;data/raw/data.csv&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;scripts/validate.py&lt;/span&gt;
    &lt;span class="na"&gt;outs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;reports/validation.json&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;cache&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;

  &lt;span class="na"&gt;preprocess&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;cmd&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;python3 scripts/preprocess.py&lt;/span&gt;
    &lt;span class="na"&gt;deps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;data/raw/data.csv&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;scripts/preprocess.py&lt;/span&gt;
    &lt;span class="na"&gt;outs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;data/processed/cleaned.csv&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 4: Check what preprocess.py actually created&lt;/p&gt;

&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; data/processed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;root@controlplane ml-pipeline on  main [?] ➜  ls -l data/processed
total 4
-rw-r--r-- 1 root root 702 Jul 19 00:15 clean.csv
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 5: Fix the preprocess output path.&lt;/p&gt;

&lt;p&gt;Open dvc.yaml in the VS Code editor. In the preprocess stage, change the last line from:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  - data/processed/cleaned.csv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;to:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  - data/processed/clean.csv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Save the file (Ctrl+S).&lt;/p&gt;

&lt;p&gt;Step 6: Copy the remaining scripts into scripts/.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp &lt;/span&gt;scripts-staging/train.py    scripts/train.py
&lt;span class="nb"&gt;cp &lt;/span&gt;scripts-staging/evaluate.py scripts/evaluate.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the train and evaluate stages to dvc.yaml.&lt;/p&gt;

&lt;p&gt;Step 7: Declare the train and evaluate stages with dvc stage add.&lt;/p&gt;

&lt;p&gt;Train stage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dvc stage add &lt;span class="nt"&gt;-n&lt;/span&gt; train &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; data/processed/clean.csv &lt;span class="nt"&gt;-d&lt;/span&gt; scripts/train.py &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-p&lt;/span&gt; n_estimators,max_depth,test_size,random_seed &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-o&lt;/span&gt; models/model.pkl &lt;span class="nt"&gt;-o&lt;/span&gt; data/processed/test_split.csv &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-M&lt;/span&gt; metrics.json &lt;span class="se"&gt;\&lt;/span&gt;
  python3 scripts/train.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Evaluate stage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dvc stage add &lt;span class="nt"&gt;-n&lt;/span&gt; evaluate &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; models/model.pkl &lt;span class="nt"&gt;-d&lt;/span&gt; data/processed/test_split.csv &lt;span class="nt"&gt;-d&lt;/span&gt; scripts/evaluate.py &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-O&lt;/span&gt; reports/evaluation.json &lt;span class="se"&gt;\&lt;/span&gt;
  python3 scripts/evaluate.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dvc repro
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Push to SeaweedFS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dvc push
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Commit everything:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Complete production DVC pipeline"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tag the release:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git tag v1.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 8: Verify the SeaweedFS bucket&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpro1uix69mf8zbfe1qm1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpro1uix69mf8zbfe1qm1.png" alt=" " width="800" height="176"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;🧠 Part 2: Simple Step-by-Step Explanation (Beginner Friendly)&lt;/p&gt;

&lt;p&gt;In this lab, the ingest and validate stages completed successfully, but the pipeline stopped during the preprocess stage.&lt;/p&gt;

&lt;p&gt;When you ran:&lt;/p&gt;

&lt;p&gt;dvc repro&lt;/p&gt;

&lt;p&gt;DVC executed the preprocess.py script successfully, and the script printed:&lt;/p&gt;

&lt;p&gt;Preprocessed: 20 clean rows&lt;/p&gt;

&lt;p&gt;However, DVC then displayed the following error:&lt;/p&gt;

&lt;p&gt;ERROR: failed to reproduce 'preprocess':&lt;br&gt;
output 'data/processed/cleaned.csv' does not exist&lt;/p&gt;

&lt;p&gt;This tells us that the Python script itself did not fail. Instead, DVC could not find the output file that was defined in dvc.yaml.&lt;/p&gt;

&lt;p&gt;To investigate, we opened the pipeline configuration:&lt;/p&gt;

&lt;p&gt;cat dvc.yaml&lt;/p&gt;

&lt;p&gt;Inside the preprocess stage, the output was configured as:&lt;/p&gt;

&lt;p&gt;outs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;data/processed/cleaned.csv&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next, we checked the actual contents of the data/processed directory:&lt;/p&gt;

&lt;p&gt;ls -l data/processed&lt;/p&gt;

&lt;p&gt;The output showed:&lt;/p&gt;

&lt;p&gt;clean.csv&lt;/p&gt;

&lt;p&gt;This revealed the problem: the script created clean.csv, but dvc.yaml expected cleaned.csv.&lt;/p&gt;

&lt;p&gt;Because DVC verifies that every declared output exists after a stage finishes, it stopped the pipeline when it couldn't find cleaned.csv.&lt;/p&gt;

&lt;p&gt;To fix the issue, we updated the outs section of the preprocess stage so that it matched the file actually produced by the script:&lt;/p&gt;

&lt;p&gt;preprocess:&lt;br&gt;
  cmd: python3 scripts/preprocess.py&lt;br&gt;
  deps:&lt;br&gt;
    - data/raw/data.csv&lt;br&gt;
    - scripts/preprocess.py&lt;br&gt;
  outs:&lt;br&gt;
    - data/processed/clean.csv&lt;/p&gt;

&lt;p&gt;After saving the change, running:&lt;/p&gt;

&lt;p&gt;dvc repro&lt;/p&gt;

&lt;p&gt;again allows DVC to locate the correct output file and continue executing the remaining stages of the pipeline.&lt;/p&gt;

&lt;p&gt;Key Takeaway&lt;/p&gt;

&lt;p&gt;A very common DVC error is:&lt;/p&gt;

&lt;p&gt;output '' does not exist&lt;/p&gt;

&lt;p&gt;When you see this message, the first thing to check is whether the output filename in dvc.yaml exactly matches the filename created by the script. Even a small difference—such as clean.csv versus cleaned.csv—is enough to cause the pipeline to fail. Always verify the actual output file (for example, using ls) before updating the pipeline configuration.&lt;/p&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Resources &amp;amp; Next Steps&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  📦 Full Code Repository: &lt;a href="https://github.com/thukhakyawe/100-Days-Of-MLOps-KodeKloud-Challenges-Solutions" rel="noopener noreferrer"&gt;KodeKloud Learning Labs&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💬 Join Discussion: &lt;a href="https://dev.to/thukhakyawe_cloud"&gt;DEV Community&lt;/a&gt; - Share your thoughts and questions
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💼 Let's Connect: &lt;a href="https://www.linkedin.com/in/thukhakyawe/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; - I'd love to connect with you
&lt;/h5&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Credits&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • All labs are from: &lt;a href="https://kodekloud.com/" rel="noopener noreferrer"&gt;KodeKloud&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • I sincerely appreciate your provision of these valuable resources.
&lt;/h5&gt;




</description>
      <category>100daysofmlops</category>
      <category>kodekloud</category>
    </item>
    <item>
      <title>Day 18: Version Datasets and Models Across Git Branches</title>
      <dc:creator>Thu Kha Kyawe</dc:creator>
      <pubDate>Sun, 19 Jul 2026 05:04:56 +0000</pubDate>
      <link>https://dev.to/thukhakyawe_cloud/day-18-version-datasets-and-models-across-git-branches-2c5c</link>
      <guid>https://dev.to/thukhakyawe_cloud/day-18-version-datasets-and-models-across-git-branches-2c5c</guid>
      <description>&lt;h1&gt;
  
  
  Lab Information
&lt;/h1&gt;

&lt;p&gt;The xFusionCorp Industries MLOps team versions datasets and models on separate Git branches so it can reproduce and roll between versions cleanly. Tag the current state as v1.0, create a v2-improved branch built on a newer dataset (which retrains the model), and confirm that switching back restores the original data and model.&lt;/p&gt;

&lt;p&gt;A project exists at /root/code/fraud-detection/ with a working DVC pipeline (it processes the data and trains a model) and the baseline data/raw/transactions.csv already tracked.&lt;/p&gt;

&lt;p&gt;An improved dataset has been pre-staged at /root/code/fraud-detection/data/raw/transactions_v2.csv and is visible in the file explorer. Do not delete this file.&lt;/p&gt;

&lt;p&gt;Acceptance criteria:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;On the main branch, the current state is tagged v1.0.
A branch named v2-improved holds the v2 state: the tracked dataset carries the contents of the v2 file (re-tracked with DVC), the pipeline has been re-run so models/model.pkl is retrained and versioned alongside the dataset, and the changes are committed.
Back on the main branch, the v1 dataset and model are restored on disk, matching the hashes recorded by the v1.0 tag.

The DVC extension's DVC TRACKED section in the EXPLORER panel reflects the tracked dataset and model for the branch you currently have checked out. To compare the exact hashes recorded on each branch, use git show &amp;lt;ref&amp;gt;:dvc.lock or dvc status.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;h1&gt;
  
  
  Lab Solutions
&lt;/h1&gt;

&lt;p&gt;✅ Part 1: Lab Step-by-Step Guidelines&lt;/p&gt;

&lt;p&gt;This is one of the most realistic DVC labs. You'll combine Git branches + DVC + pipeline reproducibility.&lt;/p&gt;

&lt;p&gt;Step 1: Go to the project&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /root/code/fraud-detection
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 2: Make sure everything is committed&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected:&lt;/p&gt;

&lt;p&gt;On branch main&lt;br&gt;
nothing to commit, working tree clean&lt;/p&gt;

&lt;p&gt;If not clean, commit your changes before continuing.&lt;/p&gt;

&lt;p&gt;Step 3: Tag the current version&lt;/p&gt;

&lt;p&gt;The lab requires the current main branch to be tagged as v1.0.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git tag v1.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git tag
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected:&lt;/p&gt;

&lt;p&gt;v1.0&lt;/p&gt;

&lt;p&gt;Step 4: Create the new branch&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; v2-improved
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git branch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;v2-improved
main&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Step 5: Replace the tracked dataset with the new version&lt;/p&gt;

&lt;p&gt;The improved dataset already exists:&lt;/p&gt;

&lt;p&gt;data/raw/transactions_v2.csv&lt;/p&gt;

&lt;p&gt;Replace the original dataset:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp &lt;/span&gt;data/raw/transactions_v2.csv data/raw/transactions.csv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 6: Update DVC tracking&lt;/p&gt;

&lt;p&gt;Since the tracked file changed, update the DVC metadata:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dvc add data/raw/transactions.csv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This updates:&lt;/p&gt;

&lt;p&gt;transactions.csv.dvc&lt;br&gt;
DVC cache&lt;/p&gt;

&lt;p&gt;Step 7: Retrain the pipeline&lt;/p&gt;

&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dvc repro
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This should rerun:&lt;/p&gt;

&lt;p&gt;process_data&lt;br&gt;
split_data&lt;br&gt;
train&lt;/p&gt;

&lt;p&gt;and regenerate:&lt;/p&gt;

&lt;p&gt;models/model.pkl&lt;br&gt;
metrics.json&lt;br&gt;
dvc.lock&lt;/p&gt;

&lt;p&gt;Step 8: Check Git status&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see changes similar to:&lt;/p&gt;

&lt;p&gt;modified: data/raw/transactions.csv.dvc&lt;br&gt;
modified: dvc.lock&lt;br&gt;
modified: metrics.json&lt;br&gt;
modified: models/model.pkl.dvc   (if model is DVC tracked)&lt;/p&gt;

&lt;p&gt;Note: The exact files may differ depending on how the lab repository is set up.&lt;/p&gt;

&lt;p&gt;Step 9: Commit the v2 state&lt;/p&gt;

&lt;p&gt;Stage everything:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Commit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Update dataset to v2 and retrain model"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 10: Return to main&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 11: Restore the DVC-tracked files&lt;/p&gt;

&lt;p&gt;After switching branches, restore the correct dataset and model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dvc checkout
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 12: Verify&lt;/p&gt;

&lt;p&gt;Check the dataset:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;md5sum &lt;/span&gt;data/raw/transactions.csv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check the model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; models/model.pkl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify DVC:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dvc status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected:&lt;/p&gt;

&lt;p&gt;Data and pipelines are up to date.&lt;/p&gt;




&lt;p&gt;🧠 Part 2: Simple Step-by-Step Explanation (Beginner Friendly)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why do we create a Git tag?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The command:&lt;/p&gt;

&lt;p&gt;git tag v1.0&lt;/p&gt;

&lt;p&gt;creates a permanent label for the current project state.&lt;/p&gt;

&lt;p&gt;Think of it as taking a snapshot:&lt;/p&gt;

&lt;p&gt;main&lt;br&gt;
 │&lt;br&gt;
 ├── v1.0  ← Snapshot&lt;/p&gt;

&lt;p&gt;You can always return to exactly this version later.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why create a new branch?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of changing the main branch directly, we create:&lt;/p&gt;

&lt;p&gt;v2-improved&lt;/p&gt;

&lt;p&gt;This allows us to safely experiment with a new dataset.&lt;/p&gt;

&lt;p&gt;The structure becomes:&lt;/p&gt;

&lt;p&gt;main&lt;br&gt;
 │&lt;br&gt;
 └── v2-improved&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why run dvc add again?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The file name stays the same:&lt;/p&gt;

&lt;p&gt;transactions.csv&lt;/p&gt;

&lt;p&gt;but its contents change because you copied in the improved dataset.&lt;/p&gt;

&lt;p&gt;DVC tracks file contents (using hashes), not just filenames.&lt;/p&gt;

&lt;p&gt;Running:&lt;/p&gt;

&lt;p&gt;dvc add data/raw/transactions.csv&lt;/p&gt;

&lt;p&gt;updates the .dvc pointer to reference the new dataset version.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why rerun the pipeline?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The dataset changed.&lt;/p&gt;

&lt;p&gt;That means:&lt;/p&gt;

&lt;p&gt;transactions.csv&lt;br&gt;
        │&lt;br&gt;
        ▼&lt;br&gt;
process_data&lt;br&gt;
        ▼&lt;br&gt;
split_data&lt;br&gt;
        ▼&lt;br&gt;
train&lt;br&gt;
        ▼&lt;br&gt;
model.pkl&lt;/p&gt;

&lt;p&gt;Every downstream stage depends on the dataset, so DVC reruns the pipeline to produce a model trained on the new data.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why use dvc checkout?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you switch back to:&lt;/p&gt;

&lt;p&gt;git checkout main&lt;/p&gt;

&lt;p&gt;Git restores:&lt;/p&gt;

&lt;p&gt;dvc.yaml&lt;br&gt;
.dvc files&lt;br&gt;
dvc.lock&lt;/p&gt;

&lt;p&gt;However, Git does not restore the actual dataset or model, because DVC manages those files.&lt;/p&gt;

&lt;p&gt;Running:&lt;/p&gt;

&lt;p&gt;dvc checkout&lt;/p&gt;

&lt;p&gt;reads the .dvc files and restores the correct versions of:&lt;/p&gt;

&lt;p&gt;transactions.csv&lt;br&gt;
model.pkl&lt;/p&gt;

&lt;p&gt;from the DVC cache.&lt;/p&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Resources &amp;amp; Next Steps&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  📦 Full Code Repository: &lt;a href="https://github.com/thukhakyawe/100-Days-Of-MLOps-KodeKloud-Challenges-Solutions" rel="noopener noreferrer"&gt;KodeKloud Learning Labs&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💬 Join Discussion: &lt;a href="https://dev.to/thukhakyawe_cloud"&gt;DEV Community&lt;/a&gt; - Share your thoughts and questions
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💼 Let's Connect: &lt;a href="https://www.linkedin.com/in/thukhakyawe/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; - I'd love to connect with you
&lt;/h5&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Credits&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • All labs are from: &lt;a href="https://kodekloud.com/" rel="noopener noreferrer"&gt;KodeKloud&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • I sincerely appreciate your provision of these valuable resources.
&lt;/h5&gt;




</description>
      <category>100daysofmlops</category>
      <category>kodekloud</category>
    </item>
    <item>
      <title>Day 17: Run and Compare DVC Experiments</title>
      <dc:creator>Thu Kha Kyawe</dc:creator>
      <pubDate>Sun, 19 Jul 2026 05:01:39 +0000</pubDate>
      <link>https://dev.to/thukhakyawe_cloud/day-17-run-and-compare-dvc-experiments-a97</link>
      <guid>https://dev.to/thukhakyawe_cloud/day-17-run-and-compare-dvc-experiments-a97</guid>
      <description>&lt;h1&gt;
  
  
  Lab Information
&lt;/h1&gt;

&lt;p&gt;The xFusionCorp Industries MLOps team needs every model training run to be reproducible, automatically tracked, and easy to compare so a chosen configuration can be promoted into version control. The fraud-detection pipeline is parameterized by max_depth, currently set shallow enough to underfit. Using DVC experiments, run three tracked experiments over different max_depth values, compare their recorded f1_score on the held-out test set, and promote the best-scoring run so its parameters, metrics, and model become the tracked workspace state.&lt;/p&gt;

&lt;p&gt;A project exists at /root/code/fraud-detection/ with a parameterised DVC pipeline already in place. params.yaml declares n_estimators: 100 and max_depth: 4, and the baseline pipeline has been run once. src/models/train.py reads both parameters, trains the model, and evaluates it on the held-out test set, writing the real accuracy and f1_score to metrics.json. Do not modify the Python files.&lt;/p&gt;

&lt;p&gt;Acceptance criteria:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Three DVC experiments have been run, each with a different value for max_depth across a reasonable range (for example 2, 6, and 12); each experiment retrains the model and produces a fresh metrics.json.
The experiment with the highest f1_score is applied to the workspace, so its max_depth, metrics.json, and models/model.pkl become the tracked state.

The DVC extension's EXPERIMENTS view (open the DVC panel from the Activity Bar) lists every experiment alongside its parameters and metrics, which is a convenient way to compare runs at a glance.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;h1&gt;
  
  
  Lab Solutions
&lt;/h1&gt;

&lt;p&gt;✅ Part 1: Lab Step-by-Step Guidelines&lt;/p&gt;

&lt;p&gt;This lab introduces DVC Experiments (dvc exp), which let you test different parameter values without committing changes to Git.&lt;/p&gt;

&lt;p&gt;Step 1: Move into the project&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /root/code/fraud-detection
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 2: Verify the current parameter&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;cat params.yaml&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected:&lt;/p&gt;

&lt;p&gt;n_estimators: 100&lt;br&gt;
max_depth: 4&lt;/p&gt;

&lt;p&gt;Step 3: Run the first experiment (max_depth=2)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dvc exp run &lt;span class="nt"&gt;-S&lt;/span&gt; &lt;span class="nv"&gt;max_depth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will:&lt;/p&gt;

&lt;p&gt;Update max_depth to 2 for the experiment.&lt;br&gt;
Retrain the model.&lt;br&gt;
Generate a new metrics.json.&lt;br&gt;
Save the experiment in DVC (without changing your Git history).&lt;/p&gt;

&lt;p&gt;Step 4: Run the second experiment (max_depth=6)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dvc exp run &lt;span class="nt"&gt;-S&lt;/span&gt; &lt;span class="nv"&gt;max_depth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;6
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 5: Run the third experiment (max_depth=12)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dvc exp run &lt;span class="nt"&gt;-S&lt;/span&gt; &lt;span class="nv"&gt;max_depth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;12
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you have three experiments, each using a different max_depth.&lt;/p&gt;

&lt;p&gt;Step 6: Compare the experiments &lt;/p&gt;

&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apt update
apt &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; less
dvc exp show
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;root@controlplane fraud-detection on  main [!] ➜  dvc exp show&lt;br&gt;
 ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────&amp;gt;&lt;br&gt;
  Experiment                 Created    accuracy   f1_score   n_estimators   max_depth   data/processed/clean_transactions.csv   data/processed/&amp;gt;&lt;br&gt;
 ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────&amp;gt;&lt;br&gt;
  workspace                  -              0.75     0.6795   100            12          34832f8da536af18bb25236981b31c04        1d9e91ebeec0d17&amp;gt;&lt;br&gt;
  main                       09:37 AM       0.71     0.5735   100            4           34832f8da536af18bb25236981b31c04        1d9e91ebeec0d17&amp;gt;&lt;br&gt;
  ├── f75ec1a [lying-zigs]   09:46 AM       0.75     0.6795   100            12          34832f8da536af18bb25236981b31c04        1d9e91ebeec0d17&amp;gt;&lt;br&gt;
  ├── fad90d2 [erect-flap]   09:45 AM      0.745     0.6483   100            6           34832f8da536af18bb25236981b31c04        1d9e91ebeec0d17&amp;gt;&lt;br&gt;
  └── 422a560 [stone-leas]   09:45 AM        0.6     0.2453   100            2           34832f8da536af18bb25236981b31c04        1d9e91ebeec0d17&amp;gt;&lt;br&gt;
 ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────&amp;gt;&lt;/p&gt;

&lt;p&gt;Step 7: Identify the best experiment&lt;/p&gt;

&lt;p&gt;Look at the f1_score column.&lt;/p&gt;

&lt;p&gt;Find the experiment with the highest f1_score.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;exp-f75ec1a has the highest f1_score of 0.6795.&lt;/p&gt;

&lt;p&gt;Step 8: Apply the best experiment&lt;/p&gt;

&lt;p&gt;Apply it to your workspace:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dvc exp apply &amp;lt;experiment-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;root@controlplane fraud-detection on  main [!] ➜  dvc exp apply f75ec1a
Building workspace index                                                                                             |7.00 [00:00, 1.46kentry/s]
Comparing indexes                                                                                                    |8.00 [00:00, 4.61kentry/s]
Applying changes                                                                                                      |0.00 [00:00,     ?file/s]
Changes for experiment 'f75ec1a' have been applied to your current workspace.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This updates:&lt;/p&gt;

&lt;p&gt;params.yaml&lt;br&gt;
metrics.json&lt;br&gt;
models/model.pkl&lt;/p&gt;

&lt;p&gt;to match the selected experiment.&lt;/p&gt;

&lt;p&gt;Step 9: Verify the applied parameter&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;cat params.yaml&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;root@controlplane fraud-detection on  main [!] ➜  cat params.yaml
n_estimators: 100
max_depth: 12
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 10: Verify the metrics&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dvc metrics show
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The displayed metrics should match the winning experiment.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;root@controlplane fraud-detection on  main [!] ➜  dvc metrics show
Path          accuracy    f1_score
metrics.json  0.75        0.6795
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 11: Verify the model&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; models/model.pkl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model file should have been regenerated for the applied experiment.&lt;/p&gt;




&lt;p&gt;🧠 Part 2: Simple Step-by-Step Explanation (Beginner Friendly)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is a DVC Experiment?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Normally, if you want to test a new model configuration, you would:&lt;/p&gt;

&lt;p&gt;Edit params.yaml.&lt;br&gt;
Run dvc repro.&lt;br&gt;
Record the results.&lt;br&gt;
Repeat.&lt;/p&gt;

&lt;p&gt;This becomes tedious and makes it hard to compare experiments.&lt;/p&gt;

&lt;p&gt;DVC Experiments automate this process.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why run multiple experiments?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Different values of max_depth can affect model performance.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;max_depth = 2&lt;/p&gt;

&lt;p&gt;A very shallow tree may underfit the data.&lt;/p&gt;

&lt;p&gt;max_depth = 6&lt;/p&gt;

&lt;p&gt;May provide a good balance.&lt;/p&gt;

&lt;p&gt;max_depth = 12&lt;/p&gt;

&lt;p&gt;A deeper tree may overfit.&lt;/p&gt;

&lt;p&gt;The goal is to find the value that gives the best f1_score.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What does dvc exp run do?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you run:&lt;/p&gt;

&lt;p&gt;dvc exp run -S max_depth=6&lt;/p&gt;

&lt;p&gt;DVC temporarily changes:&lt;/p&gt;

&lt;p&gt;max_depth: 6&lt;/p&gt;

&lt;p&gt;runs the pipeline, records the metrics, and saves the results as a named experiment.&lt;/p&gt;

&lt;p&gt;Your Git history remains unchanged.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why use dvc exp show?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of opening each metrics.json manually, DVC displays all experiments together.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;h2&gt;
  
  
  Experiment      max_depth    accuracy    f1_score
&lt;/h2&gt;

&lt;p&gt;exp-A               2          0.88        0.84&lt;br&gt;
exp-B               6          0.94        0.92&lt;br&gt;
exp-C              12          0.93        0.90&lt;/p&gt;

&lt;p&gt;This makes it easy to compare different parameter values.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What does dvc exp apply do?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once you've found the experiment with the highest f1_score, apply it:&lt;/p&gt;

&lt;p&gt;dvc exp apply exp-B&lt;/p&gt;

&lt;p&gt;This updates your workspace so that it reflects the best experiment:&lt;/p&gt;

&lt;p&gt;params.yaml uses the winning max_depth.&lt;br&gt;
metrics.json contains the winning metrics.&lt;br&gt;
models/model.pkl is the model trained with those parameters.&lt;/p&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Resources &amp;amp; Next Steps&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  📦 Full Code Repository: &lt;a href="https://github.com/thukhakyawe/100-Days-Of-MLOps-KodeKloud-Challenges-Solutions" rel="noopener noreferrer"&gt;KodeKloud Learning Labs&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💬 Join Discussion: &lt;a href="https://dev.to/thukhakyawe_cloud"&gt;DEV Community&lt;/a&gt; - Share your thoughts and questions
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💼 Let's Connect: &lt;a href="https://www.linkedin.com/in/thukhakyawe/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; - I'd love to connect with you
&lt;/h5&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Credits&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • All labs are from: &lt;a href="https://kodekloud.com/" rel="noopener noreferrer"&gt;KodeKloud&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • I sincerely appreciate your provision of these valuable resources.
&lt;/h5&gt;




</description>
      <category>100daysofmlops</category>
      <category>kodekloud</category>
    </item>
    <item>
      <title>Day 16: Track ML Metrics with DVC</title>
      <dc:creator>Thu Kha Kyawe</dc:creator>
      <pubDate>Sun, 19 Jul 2026 04:57:28 +0000</pubDate>
      <link>https://dev.to/thukhakyawe_cloud/day-16-track-ml-metrics-with-dvc-47m4</link>
      <guid>https://dev.to/thukhakyawe_cloud/day-16-track-ml-metrics-with-dvc-47m4</guid>
      <description>&lt;h1&gt;
  
  
  Lab Information
&lt;/h1&gt;

&lt;p&gt;After training a model, the xFusionCorp Industries ML team requires DVC to surface model metrics through dvc metrics show. Although the fraud-detection pipeline successfully trains a model and generates a metrics.json file, DVC currently does not recognize this file as a metric. Ensure that the metrics.json file is properly configured to be recognized by DVC.&lt;/p&gt;

&lt;p&gt;A project exists at /root/code/fraud-detection/ with a three-stage DVC pipeline (process_data, split_data, train). The train stage runs src/models/train.py, which writes the model to models/model.pkl and metrics to metrics.json. Do not modify the Python files.&lt;/p&gt;

&lt;p&gt;Acceptance criteria:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The train stage in dvc.yaml declares metrics.json as a DVC metric output rather than a regular file output, with cache: false so the JSON lives in Git for diff history rather than in the DVC cache.
The pipeline has been reproduced so the metric registration takes effect, and dvc metrics show reports the accuracy and f1_score values from metrics.json.

Tip: once the metric is registered, dvc metrics diff compares its values across Git commits, which is useful when iterating on the model.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;h1&gt;
  
  
  Lab Solutions
&lt;/h1&gt;

&lt;p&gt;✅ Part 1: Lab Step-by-Step Guidelines&lt;/p&gt;

&lt;p&gt;Step 1: Move into the project&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /root/code/fraud-detection
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 2: Inspect the current train stage&lt;/p&gt;

&lt;p&gt;Open dvc.yaml:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;cat dvc.yaml&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that metrics.json is missing.&lt;/p&gt;

&lt;p&gt;Step 3: Modify the train stage&lt;/p&gt;

&lt;p&gt;Add a metrics section.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;stages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;process_data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;cmd&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;python3 src/data/process_data.py&lt;/span&gt;
    &lt;span class="na"&gt;deps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;data/raw/transactions.csv&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;src/data/process_data.py&lt;/span&gt;
    &lt;span class="na"&gt;outs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;data/processed/clean_transactions.csv&lt;/span&gt;

  &lt;span class="na"&gt;split_data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;cmd&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;python3 src/data/split_data.py&lt;/span&gt;
    &lt;span class="na"&gt;deps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;data/processed/clean_transactions.csv&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;src/data/split_data.py&lt;/span&gt;
    &lt;span class="na"&gt;outs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;data/processed/train.csv&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;data/processed/test.csv&lt;/span&gt;

  &lt;span class="na"&gt;train&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;cmd&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;python3 src/models/train.py&lt;/span&gt;
    &lt;span class="na"&gt;deps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;data/processed/train.csv&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;src/models/train.py&lt;/span&gt;
    &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;n_estimators&lt;/span&gt;
    &lt;span class="na"&gt;outs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;models/model.pkl&lt;/span&gt;
    &lt;span class="na"&gt;metrics&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;metrics.json&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;cache&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Important: Do not put metrics.json under outs:. The lab specifically requires it to be declared as a metric with cache: false.&lt;/p&gt;

&lt;p&gt;Step 4: Save dvc.yaml and add params.yaml if it doesn't exist.&lt;/p&gt;

&lt;p&gt;Verify the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;dvc.yaml
&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; params.yaml &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;
n_estimators: 100
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 5: Reproduce the pipeline&lt;/p&gt;

&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dvc repro
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This regenerates:&lt;/p&gt;

&lt;p&gt;models/model.pkl&lt;br&gt;
metrics.json&lt;br&gt;
dvc.lock&lt;/p&gt;

&lt;p&gt;Step 6: Verify the metric&lt;/p&gt;

&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dvc metrics show
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output will look similar to:&lt;/p&gt;

&lt;p&gt;Path          accuracy    f1_score&lt;br&gt;
metrics.json  1.0         1.0&lt;/p&gt;

&lt;p&gt;The exact values will vary.&lt;/p&gt;

&lt;p&gt;Step 7: Verify the metric file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;cat&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;metrics.json&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;{&lt;br&gt;
  "accuracy": 1.0,&lt;br&gt;
  "f1_score": 1.0&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;Step 8: Verify dvc.lock&lt;/p&gt;

&lt;p&gt;(Optional)&lt;/p&gt;

&lt;p&gt;cat dvc.lock&lt;/p&gt;

&lt;p&gt;You should see metrics.json recorded under the train stage.&lt;/p&gt;




&lt;p&gt;🧠 Part 2: Simple Step-by-Step Explanation (Beginner Friendly)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is metrics.json?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After training the model, the Python script creates a file called:&lt;/p&gt;

&lt;p&gt;metrics.json&lt;/p&gt;

&lt;p&gt;It contains information about how well the model performed.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;{&lt;br&gt;
  "accuracy": 1.0,&lt;br&gt;
  "f1_score": 1.0&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;These numbers help you evaluate the model.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why doesn't DVC recognize it automatically?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;DVC only knows about files that are declared in dvc.yaml.&lt;/p&gt;

&lt;p&gt;Currently, DVC knows about:&lt;/p&gt;

&lt;p&gt;input files (deps)&lt;br&gt;
output files (outs)&lt;br&gt;
parameters (params)&lt;/p&gt;

&lt;p&gt;It doesn't know that metrics.json contains evaluation metrics.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why use metrics: instead of outs:?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Regular outputs:&lt;/p&gt;

&lt;p&gt;outs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;models/model.pkl&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;are treated as artifacts (files produced by the pipeline).&lt;/p&gt;

&lt;p&gt;Metrics are different—they are values you want to compare between experiments.&lt;/p&gt;

&lt;p&gt;So we use:&lt;/p&gt;

&lt;p&gt;metrics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;metrics.json:
  cache: false&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This tells DVC:&lt;/p&gt;

&lt;p&gt;metrics.json contains evaluation metrics.&lt;br&gt;
Keep it in Git (cache: false) instead of storing it in the DVC cache.&lt;br&gt;
Allow commands like dvc metrics show and dvc metrics diff to read it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why cache: false?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Normally, DVC stores outputs in its cache.&lt;/p&gt;

&lt;p&gt;For metrics, we want the JSON file to stay in the Git repository because:&lt;/p&gt;

&lt;p&gt;it's small,&lt;br&gt;
it's easy to compare between commits,&lt;br&gt;
Git can track its history.&lt;/p&gt;

&lt;p&gt;That's why the lab requires:&lt;/p&gt;

&lt;p&gt;cache: false&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What does dvc metrics show do?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After running:&lt;/p&gt;

&lt;p&gt;dvc repro&lt;/p&gt;

&lt;p&gt;you can execute:&lt;/p&gt;

&lt;p&gt;dvc metrics show&lt;/p&gt;

&lt;p&gt;Instead of opening metrics.json manually, DVC displays the important values in a table, for example:&lt;/p&gt;

&lt;p&gt;Path          accuracy    f1_score&lt;br&gt;
metrics.json  1.0         1.0&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is dvc metrics diff?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As you experiment with different model parameters (such as n_estimators), the metrics may change.&lt;/p&gt;

&lt;p&gt;Running:&lt;/p&gt;

&lt;p&gt;dvc metrics diff&lt;/p&gt;

&lt;p&gt;compares the metric values across Git commits, making it easy to see whether the new model performed better or worse.&lt;/p&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Resources &amp;amp; Next Steps&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  📦 Full Code Repository: &lt;a href="https://github.com/thukhakyawe/100-Days-Of-MLOps-KodeKloud-Challenges-Solutions" rel="noopener noreferrer"&gt;KodeKloud Learning Labs&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💬 Join Discussion: &lt;a href="https://dev.to/thukhakyawe_cloud"&gt;DEV Community&lt;/a&gt; - Share your thoughts and questions
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💼 Let's Connect: &lt;a href="https://www.linkedin.com/in/thukhakyawe/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; - I'd love to connect with you
&lt;/h5&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Credits&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • All labs are from: &lt;a href="https://kodekloud.com/" rel="noopener noreferrer"&gt;KodeKloud&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • I sincerely appreciate your provision of these valuable resources.
&lt;/h5&gt;




</description>
      <category>100daysofmlops</category>
      <category>kodekloud</category>
    </item>
    <item>
      <title>Day 15: Parameterize a DVC Pipeline</title>
      <dc:creator>Thu Kha Kyawe</dc:creator>
      <pubDate>Sun, 19 Jul 2026 04:54:04 +0000</pubDate>
      <link>https://dev.to/thukhakyawe_cloud/day-15-parameterize-a-dvc-pipeline-227k</link>
      <guid>https://dev.to/thukhakyawe_cloud/day-15-parameterize-a-dvc-pipeline-227k</guid>
      <description>&lt;h1&gt;
  
  
  Lab Information
&lt;/h1&gt;

&lt;p&gt;The xFusionCorp Industries ML team manages model hyperparameters using params.yaml, enabling experiments to be conducted without altering the code. In the fraud-detection project, the train stage retrieves the n_estimators parameter from params.yaml, but this parameter is not declared to DVC, which means that changing its value does not initiate retraining. Integrate the parameter into the pipeline and illustrate the concept of parameter-driven reproducibility.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;A project exists at /root/code/fraud-detection/ with a three-stage DVC pipeline (process_data, split_data, train) and a params.yaml declaring n_estimators: 100. src/models/train.py already reads n_estimators from params.yaml. Do not modify the Python files.

The train stage in dvc.yaml has no params: section, so DVC does not track n_estimators — changing it would not re-run the stage. Add a params: entry to the train stage that lists n_estimators (edit dvc.yaml, or use dvc stage add --force … -p n_estimators …).

Run the full pipeline with dvc repro.

Demonstrate parameter-driven retraining: change n_estimators to a different value (for example 200) and run dvc repro again. Only the train stage should re-execute, the new value must be recorded in dvc.lock, and models/model.pkl must be regenerated.

dvc params diff reports changes to the tracked parameter values across Git commits, which is useful when comparing experiments.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;h1&gt;
  
  
  Lab Solutions
&lt;/h1&gt;

&lt;p&gt;✅ Part 1: Lab Step-by-Step Guidelines&lt;/p&gt;

&lt;p&gt;Step 1: Move into the repository&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /root/code/fraud-detection
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 2: Inspect the current pipeline&lt;/p&gt;

&lt;p&gt;Open dvc.yaml:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;cat dvc.yaml&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Locate the train stage.&lt;/p&gt;

&lt;p&gt;It will look similar to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;stages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;process_data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;cmd&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;python3 src/data/process_data.py&lt;/span&gt;
    &lt;span class="na"&gt;deps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;data/raw/transactions.csv&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;src/data/process_data.py&lt;/span&gt;
    &lt;span class="na"&gt;outs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;data/processed/clean_transactions.csv&lt;/span&gt;

  &lt;span class="na"&gt;split_data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;cmd&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;python3 src/data/split_data.py&lt;/span&gt;
    &lt;span class="na"&gt;deps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;data/processed/clean_transactions.csv&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;src/data/split_data.py&lt;/span&gt;
    &lt;span class="na"&gt;outs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;data/processed/train.csv&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;data/processed/test.csv&lt;/span&gt;

  &lt;span class="na"&gt;train&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;cmd&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;python3 src/models/train.py&lt;/span&gt;
    &lt;span class="na"&gt;deps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;data/processed/train.csv&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;src/models/train.py&lt;/span&gt;
    &lt;span class="na"&gt;outs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;models/model.pkl&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 3: Verify params.yaml&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;cat params.yaml&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected:&lt;/p&gt;

&lt;p&gt;n_estimators: 100&lt;/p&gt;

&lt;p&gt;Step 4: Add the parameter to the train stage&lt;/p&gt;

&lt;p&gt;Edit dvc.yaml:&lt;/p&gt;

&lt;p&gt;vi dvc.yaml&lt;/p&gt;

&lt;p&gt;Add the highlighted section:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;train&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;cmd&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;python3 src/models/train.py&lt;/span&gt;

  &lt;span class="na"&gt;deps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;data/processed/train.csv&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;src/models/train.py&lt;/span&gt;

  &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;n_estimators&lt;/span&gt;

  &lt;span class="na"&gt;outs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;models/model.pkl&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save the file.&lt;/p&gt;

&lt;p&gt;Step 5: Run the pipeline&lt;/p&gt;

&lt;p&gt;Execute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dvc repro
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;root@controlplane fraud-detection on  main ➜  dvc repro
Running stage 'process_data':                                                  
&lt;/span&gt;&lt;span class="gp"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;python3 src/data/process_data.py
&lt;span class="go"&gt;Processed 15 rows
Generating lock file 'dvc.lock'                                                
Updating lock file 'dvc.lock'

Running stage 'split_data':                                                    
&lt;/span&gt;&lt;span class="gp"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;python3 src/data/split_data.py
&lt;span class="go"&gt;Train: 12 rows, Test: 3 rows
Updating lock file 'dvc.lock'                                                  

Running stage 'train':                                                         
&lt;/span&gt;&lt;span class="gp"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;python3 src/models/train.py
&lt;span class="go"&gt;Trained RandomForestClassifier with n_estimators=100
Updating lock file 'dvc.lock'                                                  

To track the changes with git, run:

        git add data/processed/.gitignore dvc.lock models/.gitignore

To enable auto staging, run:

        dvc config core.autostage true
Use `dvc push` to send your updates to remote storage.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 6: Verify dvc.lock&lt;/p&gt;

&lt;p&gt;Search for the parameter:&lt;/p&gt;

&lt;p&gt;grep -A5 params dvc.lock&lt;/p&gt;

&lt;p&gt;You should see something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;root@controlplane fraud-detection on  main [!?] ➜  grep -A5 params dvc.lock
    params:
      params.yaml:
        n_estimators: 100
    outs:
    - path: models/model.pkl
      hash: md5
      md5: ba2187225d8642cbbcd4b127310ced91
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This confirms DVC is now tracking the parameter.&lt;/p&gt;

&lt;p&gt;Step 7: Change the parameter&lt;/p&gt;

&lt;p&gt;Edit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vi params.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Change:&lt;/p&gt;

&lt;p&gt;n_estimators: 100&lt;/p&gt;

&lt;p&gt;to&lt;/p&gt;

&lt;p&gt;n_estimators: 200&lt;/p&gt;

&lt;p&gt;Save the file.&lt;/p&gt;

&lt;p&gt;Step 8: Run the pipeline again&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dvc repro
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;root@controlplane fraud-detection on  main [!?] ➜  dvc repro
Stage 'process_data' didn't change, skipping                                   
Stage 'split_data' didn't change, skipping                                     
Running stage 'train':                                                         
&lt;/span&gt;&lt;span class="gp"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;python3 src/models/train.py
&lt;span class="go"&gt;Trained RandomForestClassifier with n_estimators=200
Updating lock file 'dvc.lock'                                                  

To track the changes with git, run:

        git add dvc.lock

To enable auto staging, run:

        dvc config core.autostage true
Use `dvc push` to send your updates to remote storage.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 9: Verify dvc.lock&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-A5&lt;/span&gt; params dvc.lock
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;    &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;params.yaml&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;n_estimators&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;200&lt;/span&gt;
    &lt;span class="na"&gt;outs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;models/model.pkl&lt;/span&gt;
      &lt;span class="na"&gt;hash&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;md5&lt;/span&gt;
      &lt;span class="na"&gt;md5&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;c74b4c9de3ba10fc6f8c3789964ec187&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 11: View parameter differences&lt;/p&gt;

&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dvc params diff
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;root@controlplane fraud-detection on  main [!?] ➜  dvc params diff
Path         Param         HEAD    workspace
params.yaml  n_estimators  100     200
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;🧠 Part 2: Simple Step-by-Step Explanation (Beginner Friendly)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is params.yaml?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of hardcoding values like:&lt;/p&gt;

&lt;p&gt;n_estimators = 100&lt;/p&gt;

&lt;p&gt;the project stores them in a separate file:&lt;/p&gt;

&lt;p&gt;n_estimators: 100&lt;/p&gt;

&lt;p&gt;The training script reads this value automatically.&lt;/p&gt;

&lt;p&gt;This makes it easy to try different settings without changing the Python code.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why isn't changing params.yaml enough?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even though train.py reads params.yaml, DVC doesn't automatically know that the train stage depends on it.&lt;/p&gt;

&lt;p&gt;If the params: section is missing from dvc.yaml, DVC thinks:&lt;/p&gt;

&lt;p&gt;"Nothing important changed."&lt;/p&gt;

&lt;p&gt;So running:&lt;/p&gt;

&lt;p&gt;dvc repro&lt;/p&gt;

&lt;p&gt;may skip the training stage.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What does the params: section do?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Adding:&lt;/p&gt;

&lt;p&gt;params:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;n_estimators&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;tells DVC:&lt;/p&gt;

&lt;p&gt;"The train stage depends on the value of n_estimators."&lt;/p&gt;

&lt;p&gt;Now, whenever n_estimators changes, DVC knows the model needs to be retrained.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What happens after changing the parameter?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Initially:&lt;/p&gt;

&lt;p&gt;n_estimators: 100&lt;/p&gt;

&lt;p&gt;After editing:&lt;/p&gt;

&lt;p&gt;n_estimators: 200&lt;/p&gt;

&lt;p&gt;When you run:&lt;/p&gt;

&lt;p&gt;dvc repro&lt;/p&gt;

&lt;p&gt;DVC compares the tracked parameter values and notices that n_estimators has changed.&lt;/p&gt;

&lt;p&gt;Since only the training configuration changed:&lt;/p&gt;

&lt;p&gt;✅ train runs again.&lt;br&gt;
✅ process_data is skipped.&lt;br&gt;
✅ split_data is skipped.&lt;/p&gt;

&lt;p&gt;This saves time by only rerunning the stage that is affected.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is dvc.lock?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After each successful run, DVC records the parameter value used.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;params:&lt;br&gt;
  params.yaml:&lt;br&gt;
    n_estimators: 200&lt;/p&gt;

&lt;p&gt;This allows anyone to reproduce the exact experiment later using the same parameter values.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What does dvc params diff do?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The command:&lt;/p&gt;

&lt;p&gt;dvc params diff&lt;/p&gt;

&lt;p&gt;shows how parameter values changed between Git commits.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;Path         Param          Old   New&lt;br&gt;
params.yaml  n_estimators   100   200&lt;/p&gt;

&lt;p&gt;This is useful for comparing different experiments and understanding what changed between model versions.&lt;/p&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Resources &amp;amp; Next Steps&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  📦 Full Code Repository: &lt;a href="https://github.com/thukhakyawe/100-Days-Of-MLOps-KodeKloud-Challenges-Solutions" rel="noopener noreferrer"&gt;KodeKloud Learning Labs&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💬 Join Discussion: &lt;a href="https://dev.to/thukhakyawe_cloud"&gt;DEV Community&lt;/a&gt; - Share your thoughts and questions
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💼 Let's Connect: &lt;a href="https://www.linkedin.com/in/thukhakyawe/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; - I'd love to connect with you
&lt;/h5&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Credits&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • All labs are from: &lt;a href="https://kodekloud.com/" rel="noopener noreferrer"&gt;KodeKloud&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • I sincerely appreciate your provision of these valuable resources.
&lt;/h5&gt;




</description>
      <category>100daysofmlops</category>
      <category>kodekloud</category>
    </item>
  </channel>
</rss>
