⤵️ Quick shortcut: Select the module you’re currently studying ⤵️
Courses Module 1 Module 2 Module 3 Module 4 Module 5 Module 6
⏲️ Duration: 20 minutes lecture + 20 minutes hands-on.
Topics:
Introduction to Docker and its role in modern application deployment.
Writing a Dockerfile for a Flask/FastAPI application.
Testing Docker containers locally before deployment.
Here are some Udemy courses that cover the topics mentioned:
Below you will find some suggested materials on these topics, which we believe may help you complete the final activity in the lesson. Please note that using these resources is entirely optional, and you are welcome to explore any other sources or courses at your own discretion.
Here are some recommended courses to explore:
Mastering Python: FastAPI, Docker, Streamlit, PostgreSQL
Overview: Learn practical skills with FastAPI and Docker to build robust and scalable web applications. The course includes writing Dockerfiles for FastAPI applications and testing Docker containers locally before deployment.
Essential Docker for Python Flask Development
Overview: Focused on effectively using Docker and Docker Compose for developing production-ready Flask applications. Learn to write Dockerfiles for Flask apps and test Docker containers in your local environment.
Try FastAPI Test Driven Development 2024
Overview: This course guides you in building secure and scalable APIs using FastAPI and test-driven development (TDD). It includes setting up Docker for containerization and testing FastAPI applications locally.
Test-Driven Development with FastAPI and Docker
Overview: Learn to build, test, and deploy microservices with Python, FastAPI, and Docker. The course emphasizes writing efficient Dockerfiles and testing containers locally before deployment.
Dockerize FastAPI Project Like a Pro - Step-by-Step Tutorial
Overview: This step-by-step tutorial demonstrates how to containerize your FastAPI project using Docker. It includes writing Dockerfiles and testing containers in your development environment.
These courses should provide a solid foundation in API design principles, structuring endpoints for LLM-based tasks, and handling edge cases and errors in API responses.
Below you will find some suggested materials on these topics, which we believe may help you complete the final activity in the lesson. Please note that using these resources is entirely optional, and you are welcome to explore any other sources or courses at your own discretion.
Introduction (2 Minutes)
Opening Statement:
Welcome to this lecture on Docker for Modern Application Deployment. Today, we will explore how Docker is transforming the way applications are built, shipped, and deployed.
Agenda:
Introduction to Docker and its role in modern deployment.
Writing a Dockerfile for a Flask or FastAPI application.
Testing Docker containers locally before deployment.
Part 1: Introduction to Docker and Its Role in Modern Deployment (5 Minutes)
What is Docker?
Docker is a platform for containerization, allowing developers to package applications and their dependencies into portable containers.
Why Use Docker?
Consistency Across Environments:
Containers ensure that the application runs the same way on any system, eliminating "it works on my machine" problems.
Scalability:
Containers can be easily scaled horizontally to handle increased workloads.
Isolation:
Each container runs independently, preventing conflicts between applications.
Efficiency:
Containers share the host OS kernel, making them lightweight compared to virtual machines.
How Docker Fits in Modern Deployment Pipelines:
Docker enables Continuous Integration and Continuous Deployment (CI/CD).
Example Workflow:
Developers write code and commit to a repository.
Docker builds the application into an image.
Images are tested locally and then pushed to a registry (e.g., Docker Hub).
Containers are deployed on platforms like Kubernetes, AWS, or Google Cloud.
Part 2: Writing a Dockerfile for Flask/FastAPI Applications (8 Minutes)
What is a Dockerfile?
A Dockerfile is a script that contains instructions to build a Docker image.
Structure of a Dockerfile:
Base Image: The starting point for your application.
Dependencies: Install libraries and frameworks.
Application Code: Add the application files.
Entry Point: Command to run the application.
Example Dockerfile for FastAPI:
dockerfile
Copy code
# Step 1: Use an official Python base image
FROM python:3.9-slim
# Step 2: Set the working directory
WORKDIR /app
# Step 3: Copy application files to the container
COPY requirements.txt .
COPY app/ ./app
# Step 4: Install dependencies
RUN pip install --no-cache-dir -r requirements.txt
# Step 5: Expose the application port
EXPOSE 8000
# Step 6: Define the entry point
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
Explanation of the Steps:
Base Image: python:3.9-slim provides a minimal Python environment.
Working Directory: /app is where application files will reside.
Copy Files: COPY adds the necessary files to the container.
Install Dependencies: pip install ensures all required packages are available.
Expose Port: EXPOSE 8000 allows communication on port 8000.
Entry Point: CMD runs the FastAPI server when the container starts.
Part 3: Testing Docker Containers Locally (5 Minutes)
Build the Docker Image:
Use the docker build command to create an image from the Dockerfile.
bash
Copy code
docker build -t my-fastapi-app .
Run the Docker Container:
Use the docker run command to start the container.
bash
Copy code
docker run -p 8000:8000 my-fastapi-app
Visit http://localhost:8000 to access your application.
Test the Container:
Use tools like Postman or curl to send requests to your API and verify its behavior.
bash
Copy code
curl http://localhost:8000
Debugging Common Issues:
Missing Dependencies:
Ensure requirements.txt includes all required packages.
Port Conflicts:
Use a different host port with -p 8080:8000.
File Not Found:
Check the paths in the COPY instructions.
Stop and Remove Containers:
Stop a running container:
bash
Copy code
docker stop <container_id>
Remove a container:
bash
Copy code
docker rm <container_id>
Conclusion and Key Takeaways (3 Minutes)
Recap:
Docker simplifies application deployment with consistency, scalability, and isolation.
Writing a Dockerfile involves specifying the base image, dependencies, and entry points.
Testing containers locally ensures your application is ready for deployment.
Call to Action:
Experiment with Dockerfiles for your Flask or FastAPI projects.
Push your Docker images to a registry and deploy them to a cloud platform.
Continue learning about advanced Docker concepts like multi-stage builds and Docker Compose.
Suggestions for Visual Aids:
Slide 1: Title slide with "Docker for Modern Application Deployment."
Slide 2: Diagram comparing Docker containers and virtual machines.
Slide 3: Example Dockerfile with annotations.
Slide 4: Docker workflow (build, run, test, deploy).
Write a Dockerfile for the Jarvid API.
Build and run the Docker container locally.
By the end of this activity, you will:
Write a Dockerfile for the Jarvid API.
Build and run the Docker container locally.
Verify that the Jarvid API functions correctly inside the container.
Create the Application Directory:
bash
Copy code
mkdir jarvid-api
cd jarvid-api
Set Up the Application Structure:
plaintext
Copy code
jarvid-api/
├── app/
│ ├── main.py
├── requirements.txt
├── Dockerfile
Write the Jarvid API Code: File: app/main.py
python
Copy code
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"message": "Welcome to the Jarvid API"}
@app.get("/health")
def health_check():
return {"status": "Healthy"}
@app.post("/generate-embedding")
def generate_embedding():
# Placeholder for embedding logic
return {"embedding": [0.1, 0.2, 0.3]}
@app.post("/search-similarity")
def search_similarity(embedding: list, top_k: int):
# Placeholder for similarity search logic
return {"results": [{"id": 1, "name": "Alice", "similarity": 0.95}]}
Add Dependencies to requirements.txt: File: requirements.txt
plaintext
Copy code
fastapi
uvicorn
File: Dockerfile
dockerfile
Copy code
# Step 1: Use an official Python base image
FROM python:3.9-slim
# Step 2: Set the working directory
WORKDIR /app
# Step 3: Copy requirements and application files
COPY requirements.txt .
COPY app/ ./app
# Step 4: Install dependencies
RUN pip install --no-cache-dir -r requirements.txt
# Step 5: Expose the application port
EXPOSE 8000
# Step 6: Define the entry point
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
Build the Docker Image: Run the following command in the project root directory (jarvid-api):
bash
Copy code
docker build -t jarvid-api .
Verify the Image: Check if the image was built successfully:
bash
Copy code
docker images
Start the Container:
bash
Copy code
docker run -p 8000:8000 jarvid-api
Access the API:
Open your browser and visit: http://localhost:8000.
API documentation is available at: http://localhost:8000/docs.
Test the Root Endpoint: Use curl to test the root endpoint:
bash
Copy code
curl http://localhost:8000
Expected Response:
json
Copy code
{"message": "Welcome to the Jarvid API"}
Test the Health Check Endpoint:
bash
Copy code
curl http://localhost:8000/health
Expected Response:
json
Copy code
{"status": "Healthy"}
Test the Embedding Endpoint:
bash
Copy code
curl -X POST "http://localhost:8000/generate-embedding" -H "Content-Type: application/json" -d '{"text": "example text"}'
Expected Response:
json
Copy code
{"embedding": [0.1, 0.2, 0.3]}
Test the Similarity Search Endpoint:
bash
Copy code
curl -X POST "http://localhost:8000/search-similarity" -H "Content-Type: application/json" -d '{"embedding": [0.1, 0.2, 0.3], "top_k": 3}'
Expected Response:
json
Copy code
{"results": [{"id": 1, "name": "Alice", "similarity": 0.95}]}
Port Conflicts: If port 8000 is already in use:
bash
Copy code
docker run -p 8080:8000 jarvid-api
Access the application at http://localhost:8080.
File Not Found Errors:
Ensure the Dockerfile paths match your application structure.
Double-check the COPY commands in the Dockerfile.
Missing Dependencies:
Rebuild the image if you add new dependencies:
bash
Copy code
docker build --no-cache -t jarvid-api .
Stop the Running Container:
bash
Copy code
docker ps
docker stop <container_id>
Remove the Container:
bash
Copy code
docker rm <container_id>
Functional Dockerized Jarvid API:
The Jarvid API runs successfully inside a Docker container.
Local Testing:
All endpoints return the expected responses when tested.
Portable Docker Image:
The Docker image can be shared or deployed to any Docker-supported environment.
Push the image to Docker Hub:
bash
Copy code
docker tag jarvid-api yourusername/jarvid-api
docker push yourusername/jarvid-api
Deploy the container to a cloud platform like AWS, Google Cloud, or Azure.
Create a multi-stage Dockerfile to optimize image size and performance.
In this activity, you will:
Create a multi-stage Dockerfile to optimize the size and performance of your Docker image.
Understand how multi-stage builds separate the build and runtime environments.
Build and run the optimized Docker container locally.
What is a Multi-Stage Build?
A Dockerfile with multiple FROM statements.
Separates the build environment (e.g., compiling code) from the runtime environment (e.g., running the application).
Reduces the final image size by only including necessary components for production.
Directory Structure:
plaintext
Copy code
jarvid-api/
├── app/
│ ├── main.py
├── requirements.txt
├── Dockerfile
Application Code: File: app/main.py
python
Copy code
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"message": "Optimized Docker Image"}
@app.get("/health")
def health_check():
return {"status": "Healthy"}
Dependencies: File: requirements.txt
plaintext
Copy code
fastapi
uvicorn
File: Dockerfile
dockerfile
Copy code
# Stage 1: Build stage
FROM python:3.9-slim as builder
# Set the working directory
WORKDIR /app
# Copy dependencies file
COPY requirements.txt .
# Install dependencies
RUN pip install --no-cache-dir --prefix=/install -r requirements.txt
# Stage 2: Production stage
FROM python:3.9-slim
# Set the working directory
WORKDIR /app
# Copy only the necessary files from the builder stage
COPY --from=builder /install /usr/local
COPY app/ ./app
# Expose the application port
EXPOSE 8000
# Define the entry point
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
Explanation of the Stages:
Builder Stage (python:3.9-slim as builder):
Installs dependencies in a clean environment.
Reduces unnecessary files in the final image.
Production Stage (FROM python:3.9-slim):
Copies only the required files from the builder stage.
Ensures a lightweight final image with no build-time artifacts.
Build the Image:
bash
Copy code
docker build -t jarvid-api-optimized .
Verify the Image Size: Compare the size of the optimized image to a non-optimized version.
bash
Copy code
docker images
Start the Container:
bash
Copy code
docker run -p 8000:8000 jarvid-api-optimized
Access the Application:
Visit http://localhost:8000 to see the application in action.
API documentation is available at: http://localhost:8000/docs.
Test the Root Endpoint:
bash
Copy code
curl http://localhost:8000
Expected Response:
json
Copy code
{"message": "Optimized Docker Image"}
Test the Health Check Endpoint:
bash
Copy code
curl http://localhost:8000/health
Expected Response:
json
Copy code
{"status": "Healthy"}
Build Failures:
Ensure the COPY paths in the Dockerfile match your directory structure.
Missing Dependencies:
Revisit the requirements.txt file to ensure all required libraries are listed.
Port Conflicts:
Use a different host port if 8000 is already in use:
bash
Copy code
docker run -p 8080:8000 jarvid-api-optimized
Optimized Docker Image:
Smaller image size compared to a non-optimized version.
Faster container startup times.
Production-Ready Container:
The final image contains only runtime dependencies, ensuring better security and performance.
Push the optimized image to Docker Hub:
bash
Copy code
docker tag jarvid-api-optimized yourusername/jarvid-api-optimized
docker push yourusername/jarvid-api-optimized
Deploy the image to a cloud platform like AWS ECS or Google Cloud Run.