Docker Basics & Advanced Challenge – Week 5 of #90DaysOfDevOps
Hi, I'm Laxmi Shiwarkar — a DevOps & Cloud Infrastructure enthusiast with 5+ years of hands-on experience in automating deployments, managing Linux systems, and supporting scalable infrastructure. My journey began in infrastructure support, and over time, I’ve grown into roles that bridge development and operations. I write about: 1.AWS & GCP cloud services 2.Jenkins, GitHub Actions & CI/CD pipelines 3.Docker & containerization basics 4.Shell scripting and automation 5.Linux troubleshooting and real-world DevOps challenges I'm here to share what I learn, document practical experiences, and connect with fellow DevOps and cloud professionals. If you're passionate about infrastructure, automation, or learning-by-doing — you’ll feel right at home here.
As part of the #90DaysOfDevOps journey, I’ve completed Week 5, which was all about diving deep into Docker – from the basics to some advanced concepts like multi-stage builds, Docker networking, and vulnerability analysis using Docker Scout. This blog documents my learnings, the steps I followed, and key insights I gained.
Task 1: Introduction & Conceptual Understanding
What is Docker?
Docker is a platform that enables developers to package applications into containers—lightweight, portable, and consistent units of software that include everything needed to run: code, runtime, system tools, libraries, and settings.
Virtualization vs. Containerization
| Virtualization | Containerization |
| Runs full OS per VM | Shares OS kernel, lighter weight |
| Heavyweight, slower startup | Lightweight, fast boot time |
| Suitable for multi-tenant environments | Ideal for microservices and CI/CD |
Why containers?
Containers are perfect for building, shipping, and running apps reliably across different environments. They're faster, portable, and ideal for microservices-based architecture.
Task 2: Docker file for a Sample App
My Sample App: Python Flask Web Server : Picked up a GitHub sample repo and cloned in the ec2

Dockerfile

Note: Correction the line 7 should be COPY . .
Build & Run

build command:docker build -t laxmi/sample-app:latest .

Task -3
Key Terms – The Building Blocks of Docker
Image: This is like a mold or template. It defines what your application and its environment should look like. Once created, it can be replicated anywhere—your laptop, a cloud server, or a CI/CD pipeline.
Container: A running instance of the image. You can think of it as a package that’s been assembled and is now active—just like a product ready to be delivered.
Docker file: This is your instruction manual. It tells Docker exactly how to build your image: which base system to use, what dependencies to install, and how to run your app.
Volume: External storage that stays intact even if the container is removed or restarted. It’s like storing project data in a shared folder outside the machine—safe and reusable.
Network: Allows containers to communicate with each other securely and efficiently. In microservice architectures, this is critical—just like how different departments in a factory coordinate during production.
Docker Components – The Core System
Docker Engine: The runtime that does all the heavy lifting. It manages images, containers, and the underlying system resources needed to keep them running smoothly.
Docker CLI: Your command-line tool to interact with Docker. Whether you're building images, running containers, or checking logs—this is your control panel.
Docker Hub: A cloud-based registry where you can publish your images for others to use or pull existing images created by the community. Think of it as GitHub, but for container images.
Task 4: Multi-Stage Build Optimization
Modified Dockerfile
Builder stage
FROM python:3.9 as builder
WORKDIR /app
COPY . .
RUN pip install --no-cache-dir -r requirements.txt --target=/app/deps
# Final stage
FROM python:3.9-slim
WORKDIR /app
COPY --from=builder /app/deps /app/deps
COPY --from=builder /app .
EXPOSE 80
CMD ["python", "app.py"]
Size Comparison


| Build Type | Size |
| Initial Build | ~137 MB |
| Multi-Stage | ~63 MB |
Insight: Multi-stage builds reduce bloat and remove unnecessary build-time dependencies.
Task 5: Docker Hub Integration




Task 6: Docker Volumes



Why Volumes?
They allow you to persist data across container restarts, making them ideal for databases and stateful services.




Task 7: Docker Networking performed for a two-tier flask application
bashCopyEditdocker network create my_network
docker run -d --name sample-app --network my_network laxmi/sample-app:v1.0
docker run -d --name my-db --network my_network -e MYSQL_ROOT_PASSWORD=root mysql:latest
Networking Insight:
Containers on the same custom network can communicate using container names—essential for microservices.
created a docker bridge:


Connected mysql and a flask container to the created network .
Task 8: Docker Compose
docker-compose.yml

flaskapp:
build:
context: .
container_name: flaskapp
environment:
MYSQL_USER: admin
MYSQL_PASSWORD: admin
MYSQL_ROOT_PASSWORD: admin
MYSQL_DATABASE: tws_db
MYSQL_HOST: mysql
networks:
- two_tier
ports:
- "5000:5000"
depends_on:
mysql:
condition: service_healthy
restart: always
Task 9: Docker Scout Vulnerability Analysis
scout cves laxmi/sample-app:v1.0 > scout_report.txt
Findings Summary:
CVEs Found: 3 (1 High, 1 Medium, 1 Low)
Affected Layers: Flask version dependency
Recommendations: Use latest base image & pin package versions.
Takeaway:
Docker Scout (or tools like Trivy) give visibility into your image's security posture, essential for production readiness.
Task 10: Reflection
Commands Recap
docker build,docker run,docker volume,docker network,docker-composedocker scout,docker push,docker pull
Final Thoughts
Docker has revolutionized software development by enabling fast, consistent, and scalable deployments. Its lightweight architecture makes it perfect for microservices, and features like Compose and multi-stage builds make DevOps workflows smoother. But remember: with great power comes great responsibility—secure your images!