Setup
API
Tests
Lint
Docker
CI/CD
SAST
Trivy

Your Progress

Phase 0: Setup
Phase 1: API
Phase 2: Tests
Phase 3: Lint
Phase 4: Docker
Phase 5: CI/CD
Phase 6: SAST
Phase 7: Trivy
0% Complete

FastAPI DevSecOps Demo: A Production-Ready Microservice from Zero to Deployment

What Makes This Project Different?

No project structure

Professional folder organization

No tests

Automated test suite with Pytest

No input validation

Pydantic models for data validation

No logging

Comprehensive logging system

Manual deployment

CI/CD with GitHub Actions

No security scanning

SAST with Semgrep + Trivy

Works on my machine

Dockerized for consistency

No documentation

Auto-generated API docs

View Source Code

Explore the complete source code, documentation, and implementation details on GitHub.

View on GitHub

Tech Stack

Key Concepts Flashcards

Click any card to flip and reveal the definition.

What is DevOps?

DevOps is a way of working where software developers (Dev) and IT/operations teams (Ops) work together to build, test, release, and run software faster and more reliably through automation, continuous integration, continuous deployment, and shared responsibility.

What is a REST API?

A REST API is a way for applications to communicate with servers over the internet using standard HTTP methods. The client sends requests using GET, POST, PUT, DELETE to specific URLs, and the server responds with data in JSON format. REST APIs only transfer data, not user interfaces.

What is FastAPI?

FastAPI is a Python framework that developers use to build an API that follows REST principles. It receives requests, interprets the HTTP method and URL, executes backend logic, interacts with databases, and sends responses back in REST-compliant format.

What is a Docker Image?

A Docker image is a packaged, read-only template containing the application code, the required Python runtime, all necessary libraries, and instructions on how to start the service. The image itself does not run; it represents the standardized version of the application.

What is a Docker Container?

A Docker container is a running instance of a Docker image, capable of handling real user requests. Multiple containers can be created from the same image, each running independently while ensuring consistency, scalability, and reliability.

What is Kubernetes?

Kubernetes is a container orchestration platform that manages how containerized applications run at scale across multiple servers. It automatically monitors load, starts additional containers when demand increases, and replaces crashed containers automatically.

What is Git?

Git is a time machine for your code. It tracks every change you make, so you can go back to any previous version, see what you changed and when, and collaborate with others without conflicts.

What is a commit?

A commit is a snapshot of your project at a specific moment. It's like taking a photo of your code. Good commit messages show communication skills, organized thinking, and professional habits.

What is GitHub?

GitHub is like Google Drive for code. It backs up your code in the cloud, makes it accessible from anywhere, showcases your work to recruiters, and enables collaboration. Your GitHub is your portfolio - recruiters visit it more than your resume.

What is .gitignore?

A .gitignore file tells Git which files to NOT track. Think of it like a "Do Not Disturb" sign for certain files. Recruiters check if you have .gitignore - not having one shows you don't understand security basics.

What is Pytest?

Pytest is Python's most popular testing framework. It's simple (write tests as regular functions), powerful (fixtures, parameterization, plugins), and industry standard (used by almost every Python project). No tests = No job offer.

What is Linting?

A linter scans your code and says: "Hey, this might be a bug!" or "This is bad practice!" It catches unused variables, undefined variables, unused imports, and wrong comparisons. Linting finds bugs BEFORE you run the code.

What is Code Formatting?

A formatter automatically fixes your code style to be consistent. It handles spacing, indentation, and quotes. Formatting makes code consistent without changing what it does.

What is Ruff?

Ruff is a modern Python tool that does BOTH linting and formatting. It's fast (written in Rust, 10-100x faster than older tools), all-in-one (replaces flake8, isort, black, pyupgrade), and the new standard in Python community.

What is CI/CD?

CI (Continuous Integration) automatically tests code when it changes. CD (Continuous Deployment/Delivery) automatically deploys code after it passes tests. GitHub Actions does both - everything is automatic, same steps every time, faster releases, fewer bugs.

What is GitHub Actions?

GitHub Actions is a built-in automation tool in GitHub that lets you automatically test, build, and deploy your code whenever something happens in your repository - like pushing code, opening a pull request, merging code, or releasing a version.

What is SAST?

SAST (Static Application Security Testing) analyzes your source code for security vulnerabilities without running the application. Think of it like a spell checker, but for security flaws. Finding bugs early saves money - $100 during coding vs $100,000+ in production.

What is Semgrep?

Semgrep is a fast, open-source security scanner that scans code for security vulnerabilities, finds bugs and anti-patterns, supports many languages (Python, JavaScript, Go, etc.), and has thousands of pre-built rules.

What is Trivy?

Trivy is an open-source security scanner by Aqua Security that scans Docker images for known vulnerabilities in OS packages and application dependencies. It finds CVEs in your dependencies, not bugs in your own code.

What is a CVE?

CVE (Common Vulnerabilities and Exposures) is a unique ID for each known security vulnerability. Example: CVE-2021-44228 (Log4j vulnerability). When a vulnerability is discovered, it gets assigned a CVE ID and added to databases that scanners like Trivy can detect.

Key Concepts in this Project

DevOps is a way of working where software developers (Dev) and IT/operations teams (Ops) work together to build, test, release, and run software faster and more reliably. DevOps bridges the gap between these teams by introducing automation, continuous integration, continuous deployment, and shared responsibility, allowing applications to be updated frequently while remaining stable and reliable in production.

Real-life example (Instagram-style app)

Who are Developers:

  • Build login page
  • Create photo upload feature
  • Write recommendation logic

What does it mean by Operations:

  • Deploy app on cloud
  • Ensure app works 24/7
  • Scale servers when traffic increases
  • Monitor crashes
  • Secure user data

Both are equally important.

A REST API (Representational State Transfer Application Programming Interface) is a way for applications to communicate with servers over the internet using standard HTTP methods. In a REST API, the client (such as a web or mobile app) sends requests using methods like GET, POST, PUT, and DELETE to specific URLs, and the server responds with data, usually in JSON format. REST APIs do not handle user interfaces; they only transfer data. The client application then uses this data to display information or perform actions. REST APIs are widely used because they are simple, scalable, language-independent, and work efficiently over the web.

When I open an app like Instagram and view a user's profile, the app sends a request to Instagram's backend using an API (REST-style). This API is part of Instagram's server and is responsible for fetching the required data, such as the user's profile details, from the database. The server returns this data in a structured format (like JSON), and the app then displays it in a user-friendly interface. The API itself does not show anything to the user; it only transfers data between the app and the server.

When I open a food delivery app like Uber Eats and search for a restaurant, the app sends a request to the backend using a REST API. This API is part of the server and handles the request using an HTTP method such as GET to retrieve the restaurant's details from the database. The server then returns the data in a structured format like JSON, and the app displays this information on the screen. The REST API does not show anything by itself; it simply acts as a communication layer that transfers data between the app and the server.

A REST API is a server-side interface that receives requests from an app, fetches or updates data, and sends the data back for the app to display.

A REST API is not a separate program or service that fetches data on its own; instead, it is an architectural style that defines rules and best practices for how communication between a client and a server should happen over the internet. These rules include using HTTP methods such as GET for reading data, POST for creating data, PUT for updating data, and DELETE for removing data, along with structured URLs and data formats like JSON.

FastAPI is a Python framework that developers use to build an API that follows these REST principles. When a client application, such as a mobile or web app, sends a request (for example, searching for a restaurant or viewing a user profile), FastAPI receives the request on the server, interprets the HTTP method and URL according to REST rules, executes the backend logic, interacts with the database or other services to fetch or modify data, and then sends the response back to the client in a REST-compliant format. In simple terms, REST defines how an API should behave, while FastAPI is the actual tool that implements those rules and performs the real work of handling requests, processing data, and returning responses.

REST API should be understood as an architectural blueprint or a set of rules rather than something that actually runs or executes code. REST defines how communication between an application and a server should happen, such as using URLs to represent resources, using HTTP methods like GET, POST, PUT, and DELETE to perform actions, exchanging data in formats like JSON, and keeping interactions stateless. REST itself does not fetch data, does not execute logic, and does not exist as a software component; it is simply a set of guidelines.

FastAPI, on the other hand, is a real Python framework that runs on a server and is responsible for implementing these REST principles. When a user searches for something like "Chipotle" in an app, the app sends a REST-style request such as GET /restaurants?name=chipotle. FastAPI receives this request, identifies the HTTP method, endpoint, and parameters, executes the backend Python code, queries the database, and retrieves the relevant data. FastAPI then sends the response back to the client in a REST-compliant format, typically JSON, following REST rules such as stateless communication and clear resource-based responses.

Therefore, the correct mental model is that FastAPI is the actual API that performs all the work, while REST simply describes how that API should behave. In real-world usage, when people say terms like "Instagram REST API" or "Uber Eats REST API," they are referring to an API built using REST principles, not a separate REST component.

Consider a real-world food delivery application where the backend order service is built using FastAPI and needs to run reliably on different machines such as developer laptops, testing servers, and cloud production servers. To solve the problem of environment differences, the development team creates a Docker image, which is a packaged, read-only template containing the application code, the required Python runtime, all necessary libraries, and instructions on how to start the service. This Docker image itself does not run; it simply represents the standardized version of the application.

When this image is executed on a server, it creates a Docker container, which is a running instance of the application capable of handling real user requests. During peak usage, such as a busy evening when many users place food orders, the same Docker image can be run multiple times to create several containers of the order service, allowing traffic to be distributed across them. Each container runs independently while using the same image, ensuring consistency, scalability, and reliability. In this setup, the image acts as the blueprint for the application, while containers are the actual running copies that keep the service responsive and stable in real-world production environments.

Traditionally, applications handled increased traffic by adding more servers, which is known as horizontal scaling, or by upgrading a single server's resources, which is called vertical scaling. With containers, scaling happens at the application level rather than immediately at the server level. When traffic increases, such as on a Friday night for a food delivery app like Uber Eats, the system can start additional containers of the same application on existing servers, allowing requests to be distributed across them. This approach is still horizontal scaling, but it focuses on scaling the application using containers instead of directly adding servers. New servers are only added when existing servers reach their capacity, making container-based scaling more efficient, faster, and cost-effective.

Kubernetes is a container orchestration platform that manages how containerized applications run at scale across multiple servers. While Docker is responsible for packaging an application into an image and running it as containers, Kubernetes takes over the responsibility of controlling those containers in production. In a real-world scenario like a food delivery app experiencing heavy traffic on a Friday night, Kubernetes automatically monitors application load and starts additional containers when demand increases, distributing them across available servers. If a container crashes or a server goes down, Kubernetes detects the failure and replaces the container automatically, ensuring the application remains available. When traffic decreases, Kubernetes scales the containers back down to save resources. In this way, Kubernetes provides automated scaling, self-healing, load balancing, and efficient resource management, allowing applications to run reliably and smoothly without manual intervention.

Phase 0: Repository Setup and Project Structure

⏱️
Reading8 mins
📊
DifficultyBeginner
🔧
Hands-onYes
📋
PrerequisitesGit installed

What is Phase 0 About?

Phase 0 is about setting up the foundation of your project before writing any code. In this phase, we create the project folder structure, set up version control with Git, and connect it to GitHub. This might seem basic, but doing it right from the start is what separates professional projects from beginner projects.

Why is This Important?

For Your Career: When recruiters look at your GitHub, the first thing they notice is project organization. A messy project with no structure screams "beginner." A well-organized project with proper Git history shows professionalism.

Project Structure

fastapi-devsecops-demo/
├── app/                    # Your application code will go here
├── tests/                  # Your test code will go here
├── .github/
│   └── workflows/          # CI/CD automation will go here
└── docs/                   # Documentation will go here
💡

Key Takeaway

Phase 0 establishes the foundation. Professional projects start with proper structure, version control, and documentation. Your GitHub organization is the first thing recruiters evaluate.

Setting Up Your Project
▶️

Click the Play button above to start!

Watch the commands execute step by step

Phase 0 Quiz

1 / 3

What is Git?

Phase 1: Build FastAPI Microservice MVP

⏱️
Reading15 mins
📊
DifficultyIntermediate
🔧
Hands-onYes
📋
PrerequisitesPhase 0, Python basics

What is Phase 1 About?

Phase 1 is where we actually start coding! We build a working REST API using FastAPI - a modern Python web framework. But we're not just building "any" API. We're building it the way professional companies do - with proper configuration, data validation, logging, and error handling from day one.

API Comparison

No input validation

Pydantic models validate all input

No logging

Comprehensive logging system

Crashes on errors

Graceful error handling

No documentation

Auto-generated OpenAPI docs

What We Built

  1. app/__init__.py - Package Marker
  2. app/config.py - Configuration & Logging
  3. app/models.py - Data Models
  4. app/main.py - The Actual API
  5. requirements.txt - Dependencies
  6. Makefile - Helper Commands
💡

Key Takeaway

Phase 1 isn't just "build an API" - it's "build an API the way professionals do." The foundation of validation + logging + error handling is what companies look for.

Building Your FastAPI App
▶️

Click the Play button above to start!

Watch the commands execute step by step

Phase 2: Add Automated Tests with Pytest

⏱️
Reading12 mins
📊
DifficultyIntermediate
🔧
Hands-onYes
📋
PrerequisitesPhase 1

What is Phase 2 About?

Phase 2 adds automated testing to your API. Instead of manually testing your endpoints by running curl commands, you write code that tests your code automatically.

Testing Comparison

Manual testing takes 30+ minutes

Automated tests run in seconds

Easy to forget test cases

Never forgets a test case

Inconsistent testing

Runs the same way every time

No proof code works

Documented test coverage

What is Pytest?

Pytest is Python's most popular testing framework. It's:

  • Simple - Write tests as regular functions
  • Powerful - Fixtures, parameterization, plugins
  • Industry standard - Used by almost every Python project
def test_addition():
    result = 1 + 1
    assert result == 2  # If true, test passes. If false, test fails.
💡

Key Takeaway

No tests = No job offer. Every professional software team requires tests before merging code. Automated testing is non-negotiable in production environments.

Running Pytest
▶️

Click the Play button above to start!

Watch the commands execute step by step

Phase 3: Add Linting and Code Formatting

⏱️
Reading10 mins
📊
DifficultyBeginner
🔧
Hands-onYes
📋
PrerequisitesPhase 2

What is Phase 3 About?

Phase 3 adds automatic code quality checks. Linting finds bugs and bad practices. Formatting ensures consistent code style across the team.

What is Ruff?

Ruff is a modern Python tool that does BOTH linting and formatting:

  • Fast - Written in Rust, 10-100x faster than older tools
  • All-in-one - Replaces flake8, isort, black, pyupgrade
  • Modern - New standard in Python community
💡

Key Takeaway

Linting catches bugs BEFORE you run the code. Formatting makes code consistent without changing what it does. Ruff combines both into one fast tool.

Using Ruff for Linting & Formatting
▶️

Click the Play button above to start!

Watch the commands execute step by step

Phase 4: Dockerize the Application

⏱️
Reading12 mins
📊
DifficultyIntermediate
🔧
Hands-onYes
📋
PrerequisitesPhase 3, Docker installed

What is Phase 4 About?

Phase 4 packages your application into a Docker container - a portable box that includes your app and everything it needs to run.

Docker Comparison

"Works on my machine" problems

Runs the same everywhere

Manual dependency installation

All dependencies packaged

Environment inconsistencies

Identical dev and prod environments

Complex deployment

Single container to deploy

Dockerfile

FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app/ ./app/
EXPOSE 8000
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
💡

Key Takeaway

Docker solves the "works on my machine" problem. The same image runs in development AND production with no surprises.

Docker Workflow

📝
Dockerfile
🔨
Build Image
📦
Docker Image
▶️
Run Container
📈
Scale Up
📝Dockerfile

A recipe file that contains instructions on how to build the Docker image - what base image to use, what to install, and how to run the app.

Docker Commands
▶️

Click the Play button above to start!

Watch the commands execute step by step

Phase 4 Quiz

1 / 3

What is a Docker image?

Phase 5: CI/CD with GitHub Actions

⏱️
Reading15 mins
📊
DifficultyIntermediate
🔧
Hands-onYes
📋
PrerequisitesPhase 4, GitHub account

What is Phase 5 About?

Phase 5 sets up CI/CD - a system that automatically tests, checks, and builds your code every time you push to GitHub. No more manual checking.

CI/CD Comparison

Manually run tests

Tests run automatically on push

Easy to forget steps

Same steps every time

Slow releases

Fast, confident releases

Errors reach production

Errors caught in pipeline

CI/CD in One Line

  • CI (Continuous Integration) → Automatically test code when it changes
  • CD (Continuous Deployment/Delivery) → Automatically deploy code after it passes tests
💡

Key Takeaway

GitHub Actions automates your entire workflow. Push code → tests run → security scans → Docker builds → deployment. All automatic, every time.

CI/CD Pipeline Flow

📤
Push Code
🧹
Lint & Format
🧪
Run Tests
🔒
Security Scan
🐳
Build Image
🛡️
Container Scan
📤Push Code

Developer pushes code changes to GitHub repository, triggering the CI/CD pipeline automatically.

Setting Up GitHub Actions CI/CD
▶️

Click the Play button above to start!

Watch the commands execute step by step

Phase 5 Quiz

1 / 3

What does CI stand for?

Phase 6: SAST Security Scanning with Semgrep

⏱️
Reading10 mins
📊
DifficultyIntermediate
🔧
Hands-onYes
📋
PrerequisitesPhase 5

What is SAST?

SAST = Static Application Security Testing - analyzes your source code for security vulnerabilities without running the application. Think of it like a spell checker, but for security flaws.

The Cost of Security Bugs

When FoundCost to Fix
During coding$100
During code review$1,000
During testing$10,000
In production$100,000+
💡

Key Takeaway

Semgrep scans your source code for security vulnerabilities. Finding bugs early saves money and reputation. The Equifax breach cost $1.4 billion - all from a known, unpatched vulnerability.

Running Semgrep Security Scan
▶️

Click the Play button above to start!

Watch the commands execute step by step

Phase 7: Container Scanning with Trivy

⏱️
Reading10 mins
📊
DifficultyIntermediate
🔧
Hands-onYes
📋
PrerequisitesPhase 6

Semgrep vs Trivy

Semgrep (Phase 6)Trivy (Phase 7)
Scans your source codeScans your Docker image
Finds bugs you wroteFinds vulnerabilities in dependencies
Catches coding mistakesCatches outdated packages

Your Code Can Be Perfect, But Still Vulnerable

You write perfect code, but use an old version of FastAPI with a security bug, or a Python library that got hacked. Your app is now vulnerable - even though YOUR code is fine.

💡

Key Takeaway

You need BOTH: Semgrep ensures your code is secure. Trivy ensures your dependencies are secure. The Log4j disaster proved that even perfect code can be vulnerable through dependencies.

Running Trivy Container Scan
▶️

Click the Play button above to start!

Watch the commands execute step by step

Let's
Collaborate.

Location

Denton, TX