Skip to main content

Dockerfile Writing Lab

· 3 min read

Lab 1: The Foundation (Basic Web Server)​

Goal: Create a simple Nginx server that displays a custom HTML page. This introduces FROM, COPY, and EXPOSE.

Step 1: Create a file named index.html


# Hello from Docker!

Step 2: Create a file named Dockerfile

# Step 1: Base Image (The OS)
FROM nginx:alpine

# Step 2: Metadata (Good practice)
LABEL maintainer="devsecops-guru"

# Step 3: Copy your web page to the server's default folder
COPY index.html /usr/share/nginx/html/index.html

# Step 4: Documentation (Tell humans this port is needed)
EXPOSE 80

# Note: Nginx has a default CMD, so we don't need to write it!

Step 3: Build and Run

docker build -t my-web-server .
docker run -p 8080:80 my-web-server
  • Test: Open your browser to localhost:8080. You should see "Hello from Docker!".

Lab 2: The Optimizer (Layer Caching)​

Goal: Understand why the order of instructions matters for speed.

Step 1: Create a python file app.py

print("Hello World")

Step 2: Create a requirement file requirements.txt

flask

Step 3: The "Bad" Dockerfile (Write this first)

FROM python:3.9-slim
WORKDIR /app
COPY . .
# ^ PROBLEM: If you change code, cache breaks here!
RUN pip install -r requirements.txt
CMD ["python", "app.py"]

Step 4: The "Good" Dockerfile (Write this second)

FROM python:3.9-slim
WORKDIR /app

# 1. Copy only files needed for installation first
COPY requirements.txt .

# 2. Install dependencies (This layer is now cached!)
RUN pip install -r requirements.txt

# 3. NOW copy the rest of the source code
COPY . .

CMD ["python", "app.py"]

Activity:

  • Build the "Good" Dockerfile.

  • Change one word in app.py.

  • Build it again.

  • Notice that RUN pip install says ---> Using cache. It didn't run again! This saves huge time in big projects.


Lab 3: The Architect (Multi-Stage Build)​

Goal: Build a Go application. Go needs a compiler (heavy), but the final app is just a binary (tiny). We will throw away the compiler.

Step 1: Create a Go program main.go

package main
import "fmt"
func main() {
fmt.Println("I am a tiny container!")
}

Step 2: Create the Multi-Stage Dockerfile

# ----------------------------
# STAGE 1: The Builder (Heavy)
# ----------------------------
FROM golang:1.19-alpine AS builder

WORKDIR /app

# Copy source code
COPY main.go .

# Compile the code to a binary named "my-app"
RUN go build -o my-app main.go

# ----------------------------
# STAGE 2: The Runner (Tiny)
# ----------------------------
FROM alpine:latest

WORKDIR /root/

# Copy ONLY the binary from the "builder" stage
COPY --from=builder /app/my-app .

# Command to run the binary
CMD ["./my-app"]

Step 3: Verify the Size

  • Build it: docker build -t tiny-go .

  • Check size: docker images

  • Result: You will see the image is roughly 10MB. If you didn't use multi-stage, it would be 800MB+.

Dockerfile Writing Quiz

· One min read

Build Process

Score: 0/20

🐳 Master Quiz: Dockerfiles

Architecting Infrastructure as Code: Layers, Cache, and Security.

🎉 Image Built Successfully!​

Your Build Status:

0/20 Junior Dev

  • **↺ Rebuild Image**

Python ASCII & Unicode Lab

· 3 min read

Lab: The "Hidden Numbers" Workshop​

Objective: Understand how computers store text and manipulate characters using ord() (to number) and chr() (to text).


Experiment 1: The "Secret Decoder" Ring (Caesar Cipher)​

Goal: Create a simple encryption script by shifting ASCII values.

Scenario: You want to send a secret message by shifting every letter forward by 1 (A becomes B, B becomes C).

Step 1: Run the Encryption Code

# The message to hide
message = "HELLO"
encrypted_text = ""

print(f"Original: {message}")

for char in message:
# 1. Convert char to ASCII number
ascii_val = ord(char)

# 2. Shift the number by +1
shifted_val = ascii_val + 1

# 3. Convert back to character
new_char = chr(shifted_val)

# Append to result
encrypted_text += new_char

print(f"Encrypted: {encrypted_text}")

Observation: HELLO becomes IFMMP. You just performed basic cryptography!


Experiment 2: The "Magic 32" (Manual Case Conversion)​

Goal: Understand why computers see 'a' and 'A' as different, and how to convert them mathematically.

Context: The difference between any Uppercase letter and its Lowercase version in ASCII is exactly 32.

  • 'a' (97) - 'A' (65) = 32

Step 1: Run the Manual "Lowercaser"

def manual_to_lower(text):
result = ""
for char in text:
# Check if character is Uppercase (A-Z are 65-90)
if 65 <= ord(char) <= 90:
# Add 32 to "slide" it into the lowercase range
new_char = chr(ord(char) + 32)
result += new_char
else:
# Keep punctuation or existing lowercase as is
result += char
return result

original = "PYTHON Code!"
lowered = manual_to_lower(original)

print(f"Original: {original}")
print(f"Manual Lower: {lowered}")

Observation: You just recreated Python's built-in .lower() method using raw math!


Experiment 3: The "Password Strength" Validator​

Goal: Use ASCII ranges to validate input without using helper methods like .isdigit().

Scenario: A password must contain at least one Capital Letter and one Number.

def check_password(password):
has_upper = False
has_digit = False

for char in password:
code = ord(char)

# Check ASCII range for 'A' to 'Z' (65-90)
if 65 <= code <= 90:
has_upper = True

# Check ASCII range for '0' to '9' (48-57)
elif 48 <= code <= 57:
has_digit = True

if has_upper and has_digit:
return "✅ Password Strong"
else:
return "❌ Password Weak (Needs Uppercase & Number)"

# Test the function
print(check_password("pass123")) # Weak (No Upper)
print(check_password("Passcode")) # Weak (No Number)
print(check_password("Pass123")) # Strong

Experiment 4: Unicode & Emojis​

Goal: Prove that Python can handle numbers way bigger than 127 (ASCII).

Step 1: Run the Emoji Generator We will print characters using their specific Hexadecimal Unicode points.

# Unicode uses hex numbers (e.g., 0x1F600)
# You can find these codes online at unicode.org

print("Here are some Unicode characters:")
print(f"U+03A9 (Greek Omega): {chr(0x03A9)}")
print(f"U+2602 (Umbrella): {chr(0x2602)}")
print(f"U+1F680 (Rocket): {chr(0x1F680)}")
print(f"U+1F40D (Snake): {chr(0x1F40D)}")

Python ASCII & Unicode Quiz

· One min read

Code Points

Score: 0/20

🌐 Master Quiz: ASCII & Unicode

Test your knowledge on Character Encoding, Ordinals, and the Universal Standard.

🎉 Translation Complete!​

Your Encoding Proficiency:

0/20 Novice

  • **↺ Re-Encode**

Python Lists Lab

· 3 min read

Lab 1: User Access Management (The "Admin" Scenario)​

Scenario: You are a System Administrator. You have a list of active employees, and you need to onboard new hires and remove employees who have left the organization.

Concepts Covered: .append(), .remove(), if/else logic.

# 1. Current Active Users List
active_users = &#91;"raj_admin", "priya_dev", "amit_ops", "sara_test"]

# 2. New Joiners to be added
new_hires = &#91;"vikram_sec", "neha_ds"]

# 3. Employee who resigned
resigned_user = "amit_ops"

print(f"--- Original Team: {active_users} ---")

# Step A: Onboarding (Adding Users)
# We use .extend() because we are adding multiple people at once.
# Official Doc: https://docs.python.org/3/tutorial/datastructures.html#more-on-lists
active_users.extend(new_hires)
print(f"After Hiring: {active_users}")

# Step B: Offboarding (Removing Users)
# Always check if the user exists before removing to avoid errors!
if resigned_user in active_users:
active_users.remove(resigned_user)
print(f"User '{resigned_user}' has been removed successfully.")
else:
print(f"User '{resigned_user}' not found in the system.")

print(f"--- Final Team List: {active_users} ---")

Lab 2: Server Health Monitoring (Data Analysis)​

Scenario: You have a list of CPU utilization percentages collected every minute. You need to find the peak load, the lowest load, and the average load to generate a health report.

Concepts Covered: max(), min(), sum(), len().

# CPU Load readings (in percentage)
cpu_usage = &#91;12, 45, 67, 89, 15, 99, 23, 56, 12, 45]

# Step A: Find Peak Load (Maximum)
peak_load = max(cpu_usage)

# Step B: Find Idle Load (Minimum)
idle_load = min(cpu_usage)

# Step C: Calculate Average Load
# Formula: Sum of all items divided by count of items
average_load = sum(cpu_usage) / len(cpu_usage)

print("--- Server Health Report ---")
print(f"Peak CPU Usage: {peak_load}% (Critical Alert if > 90)")
print(f"Lowest CPU Usage: {idle_load}%")
print(f"Average Load: {average_load:.2f}%")

# Logic Check:
if peak_load > 90:
print("WARNING: Server hit critical load! Check logs immediately.")
else:
print("Status: Server is healthy.")

Lab 3: Cleaning Network Data (Sanitization)​

Scenario: You pulled a list of IP addresses from a firewall log. However, the logs are messy—there are duplicate entries because some IPs were blocked multiple times. You need a clean, unique list of blocked IPs sorted numerically.

Concepts Covered: set() (to remove duplicates), .sort(), Type Conversion.

# Raw Firewall Logs (Notice duplicates)
blocked_ips = &#91;
"192.168.1.5",
"10.0.0.1",
"192.168.1.5",
"172.16.0.50",
"10.0.0.1"
]

print(f"Raw Count: {len(blocked_ips)}")

# Step A: Remove Duplicates
# Converting list to a Set removes duplicates automatically.
# Then we convert it back to a list.
unique_ips = list(set(blocked_ips))

# Step B: Sort the IPs
# Note: This does string sorting, not numeric sorting, but it works for basic organization.
unique_ips.sort()

print(f"Cleaned Count: {len(unique_ips)}")
print(f"Unique Block List: {unique_ips}")

Lab 4: Job Queue Simulation (FIFO - First In, First Out)​

Scenario: You are building a simple "Task Scheduler" for a DevOps pipeline. Jobs come in and must be processed in the order they arrived.

Concepts Covered: .pop(0) vs .pop(), while loops.

# Pending Tasks Queue
deployment_queue = &#91;"Build_Image", "Run_Tests", "Deploy_to_Staging", "Notify_Slack"]

print(f"Initial Queue: {deployment_queue}")

# Process the queue until it is empty
while len(deployment_queue) > 0:
# .pop(0) removes the item at index 0 (The first one)
# This simulates a Queue (FIFO). If we used .pop(), it would be a Stack (LIFO).
current_task = deployment_queue.pop(0)

print(f"Processing Task: {current_task}...")
# Simulate work...
print(f"Task '{current_task}' Completed!")
print(f"Remaining Queue: {deployment_queue}")
print("-" * 30)

print("All tasks finished. Pipeline idle.")

Python Lists Quiz

· One min read

Smart Inventory

Score: 0/20

📦 Master Quiz: Python Lists

Manage the Smart Warehouse: Arrays, Pointers, and Big O Complexity.

🎉 Inventory Check Complete!​

Your Efficiency:

0/20 Novice

  • **↺ Restock**

Python r-strings Lab

· 3 min read

Experiment 1: The "Broken Path" Scenario​

Goal: Understand how standard strings corrupt Windows file paths and how raw strings fix them.

Step 1: Run the "Buggy" Code Copy and run the following code. We are trying to print a folder path: C:\new\tables.

# ❌ The Wrong Way
# Python sees \n (newline) and \t (tab) inside the string
path = "C:\new\tables"

print("--- Standard String Output ---")
print(path)

Observation: You will see the output is messy. The "n" disappeared and created a new line. The "t" disappeared and created a tab space.

C:
ew ables

Step 2: Run the "Fixed" Code Now, let's apply the raw string fix.

# ✅ The Right Way (Raw String)
# The 'r' prefix tells Python to ignore the special meaning of \
path = r"C:\new\tables"

print("\n--- Raw String Output ---")
print(path)

Observation: The output is now perfect: C:\new\tables.


Experiment 2: The "Regex Backslash Plague"​

Goal: See why raw strings are mandatory for clean Regular Expressions.

Scenario: You want to find the latex command \section inside a text string. To find a literal backslash in Regex, you normally have to escape it twice (\\\\).

Step 1: The "Hard" Way (Standard String)

import re

text = "Error in \section name"

# Without raw string, we must type FOUR backslashes to match ONE
# Python parser eats 2, Regex engine eats 2 -> matches 1 literal \
pattern = "\\\\section"

match = re.search(pattern, text)
print(f"Standard String Match: {match}")

Step 2: The "Smart" Way (Raw String)

# With raw string, we only type TWO backslashes
# Python passes both to Regex, Regex uses first to escape the second
pattern = r"\\section"

match = re.search(pattern, text)
print(f"Raw String Match: {match}")

Analysis: Both work, but the Standard String version requires \\\\ to match one \. If you needed to match two backslashes, you would need to type eight (\\\\\\\\)! The Raw String version keeps your code readable.


Experiment 3: The "Trailing Backslash" Crash​

Goal: encounter the most common error with raw strings and learn the workaround.

Step 1: Trigger the Error Try to define a path that ends with a backslash.

# ❌ This will cause a SyntaxError
# The final \ escapes the closing quote "
bad_path = r"C:\Program Files\"
print(bad_path)

Step 2: Apply the Workaround Since raw strings cannot end in an odd number of backslashes, we must use string concatenation or os.path.

# ✅ Workaround 1: Concatenation
fixed_path = r"C:\Program Files" + "\\"
print("Fixed Path 1:", fixed_path)

# ✅ Workaround 2: os.path.join (Best Practice for actual files)
import os
best_path = os.path.join(r"C:\Program Files", "")
print("Fixed Path 2:", best_path)

Python r-strings Quiz

· One min read

Regex Mode

Score: 0/20

📜 Master Quiz: Raw Strings

Taming the 'Backslash Plague' in File Paths and Regular Expressions.

🎉 Pattern Matched!​

Your Raw Accuracy:

0/20 Novice

  • **↺ Re-compile**

Python Escape Characters Lab

· 4 min read

Lab: Try it Yourself!​

Open a Python terminal or any online compiler and run this code:

# Lab 1: The messy vs clean string
print("Name: DevSecOps Guru\nRole: Architect\tLocation: India")

# Lab 2: Handling quotes
print("He said, \"Learning DevSecOps is 100% worth it!\"")

# Lab 3: The backslash struggle
print("The folder is located at C:\\Program Files\\Scripts")

Lab 1: Python - The "Broken" String Try running this without the backslash and watch it fail. Then fix it.

# BROKEN CODE
# text = 'It's a beautiful day'

# FIXED CODE
text = 'It\'s a beautiful day'
print(text)

Lab 1: The "Restaurant Menu" (Formatting with \n and \t)​

Goal: Create a clean, aligned menu using only one print statement. Concept:

  • \n (New Line): Moves text to the next line.

  • \t (Tab): Adds spacing to align prices.

Code:

# Lab 1: Formatting a Menu
print("--- INDIAN STREET FOOD MENU ---")

# Without Escape Characters (Messy)
print("Item Price")
print("Samosa 20 INR")
print("Vada Pav 50 INR")

print("\n--- FIXED VERSION ---")

# With Escape Characters (Clean)
# Notice we use only ONE print() function for the whole list!
print("Item\t\tPrice\n----\t\t-----\nSamosa\t\t20 INR\nVada Pav\t50 INR\nChai\t\t10 INR")

Expected Output: You will see a perfectly aligned table. The \t pushes the price to the right column, and \n starts the next item on a new line.


Lab 2: The "Storyteller" (Handling Quotes \' and \")​

Goal: Print a sentence that contains both single and double quotes without causing a syntax error. Concept:

  • \': Escapes a single quote inside a single-quoted string.

  • \": Escapes a double quote inside a double-quoted string.

Code:

# Lab 2: Handling Dialogue

# Scenario: We need to print: The developer said, "It's working!"

# Attempt 1: This will fail (Syntax Error)
# print('The developer said, "It's working!"')

# Attempt 2: The Fix
print('The developer said, "It\'s working!"')

# Alternative Fix (Swapping outer quotes)
print("The developer said, \"It's working!\"")

# Advanced: Both inside one string
print("My manager asked: \"Is the 'deploy' button ready?\"")

Lab 3: The "Windows Path" Struggle (Backslash \\)​

Goal: Print a Windows file path correctly. This is a very common issue for Python beginners on Windows. Concept:

  • \\: Prints a literal backslash.

Code:

# Lab 3: File Paths

# Incorrect Way (Python thinks \U is an escape sequence start)
# path = "C:\Users\Admin\Documents" <-- This causes an error!

# Correct Way 1: Double Backslash
path_fixed = "C:\\Users\\Admin\\Documents\\SecretFile.txt"
print("Path 1:", path_fixed)

# Correct Way 2: Raw Strings (The Developer's Favorite)
# putting 'r' before the quote tells Python to ignore ALL escape characters.
path_raw = r"C:\Users\Admin\Documents\SecretFile.txt"
print("Path 2:", path_raw)

Lab 4: The "DevSecOps Log" (Simulating Data Sanitization)​

Goal: Visualize how raw data looks versus "escaped" data. This is crucial for understanding security logs. Concept:

  • repr(): A Python function that shows the "raw" representation of a string, including the escape characters.

Code:

# Lab 4: Security Logging Simulation

user_input = "Admin\nDelete_All"

print("--- VISUALIZING THE ATTACK ---")

# 1. Normal Print (What the user intends to happen)
# This looks like two separate commands on the console.
print("User Input Executed:\n" + user_input)

# 2. Raw Representation (What the log file sees)
# This reveals the hidden \n character.
print("\nLog File Entry:")
print(repr(user_input))

Lab 5: Fun with Unicode (Hex Escape \u)​

Goal: Print special symbols and emojis using their specific ID. Concept:

  • \uXXXX: Prints a 16-bit Unicode character.

  • \UXXXXXXXX: Prints a 32-bit Unicode character (for Emojis).

Code:

# Lab 5: Icons and Symbols

# 16-bit hex value for Checkmark and Copyright
print("\u2705 System Check Complete")
print("\u00A9 2026 DevSecOps Guru")

# 32-bit hex value for Python Snake Emoji (Note the capital U and 8 digits)
print("I love coding in Python \U0001F40D")

Python Escape Characters Quiz

· One min read

System Check

Score: 0/20

_ Master Quiz: Escape Characters

Identify the hidden signals, secure the shell, and escape the matrix.

🎉 Check Complete!​

Sanitization Status:

0/20 Guest

  • **↺ Re-Authenticate**