Deploying the API: Docker and Production Configuration
Learn how to move your Python API to production. We cover containerizing your app with Docker, managing environment variables, and basic server deployment.

Previously in this course, we explored packaging Python projects to organize our code for distribution. Now that your API is modular and documented, the final step is moving it out of your local machine and into a environment where others can use it: production.
Deployment is the process of moving your application from a developer's environment to a server. To do this reliably, we use Docker. Docker allows us to bundle our application, its dependencies, and the operating system settings into a single "container," ensuring that if it works on your machine, it will work on the server.
Why Containerize with Docker?
When you deploy a Python app, you often face the "it works on my machine" problem. Perhaps your server has a different version of Python, or it's missing a system-level library your code requires.
Docker solves this by creating a Container Image. Think of this as a snapshot of your entire application environment. When you deploy this image, you aren't just sending your code; you are sending the exact environment required to run it.
Creating Your First Dockerfile
To containerize your FastAPI project, you need a Dockerfile. This is a plain text file containing the instructions to build your image. Create a file named Dockerfile (no extension) in your project root:
Dockerfile# 1. Use an official Python runtime as a parent image FROM python:3.11-slim # 2. Set the working directory in the container WORKDIR /app # 3. Copy only the requirements file first (for better caching) COPY requirements.txt . # 4. Install dependencies RUN pip install --no-cache-dir -r requirements.txt # 5. Copy the rest of the application code COPY . . # 6. Expose the port the app runs on EXPOSE 8000 # 7. Define the command to run the app CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
Managing Environment Variables in Production
In reading environment variables, we learned why you should never hardcode secrets like database passwords or API keys. In a containerized environment, you inject these variables when you start the container.
Instead of putting secrets in your code, you pass them via the command line or a .env file when running Docker:
Bash# Building the image docker build -t my-api-app . # Running the container with an environment variable docker run -d -p 8000:8000 -e DATABASE_URL="postgres://user:pass@db:5432/db" my-api-app
The -e flag allows you to pass variables directly into the container's environment, keeping your source code clean and secure.
Hands-on Exercise: Containerize Your Project
- Ensure you have a
requirements.txtfile in your root folder (you can generate this usingpip freeze > requirements.txt). - Create the
Dockerfileprovided above in your project root. - Build your image by running
docker build -t my-api .in your terminal. - Verify it works by running
docker run -p 8000:8000 my-apiand visitinghttp://localhost:8000in your browser.
Common Pitfalls
- Including Local Folders: Always create a
.dockerignorefile. You don't want to copy your local.gitfolder or your__pycache__directories into the container, as they bloat the image and can cause conflicts. - Running as Root: By default, Docker containers run as the
rootuser. For production, it is a security best practice to create a non-privileged user inside your Dockerfile and use theUSERcommand to switch to it before starting your app. - Hardcoding Ports: Don't hardcode your port inside your Python code. Use
os.getenv("PORT", 8000)so your deployment platform (or Docker) can dictate which port the application listens on.
Frequently Asked Questions
Does Docker replace a web server like Nginx? Not necessarily. In production, you often place a web server like Nginx in front of your Docker container to handle SSL (HTTPS), load balancing, and static file caching.
How do I update my app once it's deployed? You rebuild the image, push it to a registry (like Docker Hub), and tell your server to pull the new image and restart the container.
Recap
Deployment is the final bridge between your code and your users. By using Docker, we package our dependencies and environment, making our application portable and predictable. We use environment variables to keep configuration separate from our code, ensuring security and flexibility.
You’ve successfully built a modular, tested, and containerized API. You are now equipped with the core skills of a backend engineer.
Up next: We will discuss the path forward, identifying your next learning steps in the Python ecosystem and how to build a professional portfolio.
Work with me

Laravel REST API Development
Clean, secure, well-documented Laravel REST APIs — the backend engine for your app, mobile client, or SaaS. Built by an API specialist.

CI/CD Pipeline & Docker Containerization
Ship with confidence: automated CI/CD pipelines and Docker setups so every push is tested and deployed — no more manual, error-prone releases.


