Docker offers a way to run applications in a consistent environment, which simplifies deployment and scaling. FastAPI is a modern, fast web framework for building APIs with Python based on standard Python type hints. In this article, we’ll guide you through the process of dockerizing a FastAPI application.
Prerequisites
- Basic understanding of Python and FastAPI.
- Docker installed on your machine.
Steps to Dockerize a FastAPI Application
1. Create a FastAPI application
Before we start with the Dockerization process, let’s create a basic FastAPI application. If you have an existing application skip this step. Here’s a simple `main.py`:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
2. Setup a requirements.txt
It’s a good practice to list all of your Python dependencies in a `requirements.txt` file. For this example, you’d have:
fastapi
uvicorn
3. Create a Dockerfile
The `Dockerfile` contains instructions for Docker on how to create an image of our application. Create a `Dockerfile` in the root directory of your application with the following content:
# Use an official Python runtime as a parent image
FROM python:3.9-slim
# Set environment varibles
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
# Set the working directory in docker
WORKDIR /app
# Copy the current directory contents into the container at /app
COPY . /app
# Install any needed packages specified in requirements.txt
RUN pip install --no-cache-dir -r requirements.txt
# Specify the command to run on container start
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"]
In this Dockerfile:
- We’re using a lightweight Python 3.9 image.
- We set some environment variables to optimize Python for running in a Docker container.
- We set the working directory inside the container to `/app`.
- We copy the contents of our current directory into the container.
- We install the Python dependencies.
- Lastly, we tell Docker to run `uvicorn` with our application when the container starts.
4. Create a .dockerignore
Just as we can ignore files with `.gitignore`, we can do the same with `.dockerignore`. This ensures that certain files and directories aren’t copied into the container. Here’s a basic `.dockerignore`:
__pycache__
*.pyc
*.pyo
*.egg-info
5. Build the Docker Image
Now that we have our `Dockerfile` set up, we can build an image for our application:
docker build -t fastapi_app .
This will create a Docker image named `fastapi_app` from our current directory.
6. Run the Docker Container
Now that we have our image, we can run it:
docker run -p 8000:80 fastapi_app
This command tells Docker to run our image and map port 8000 on our host machine to port 80 on the container.
Once the container is running, you can visit `http://localhost:8000` and see the FastAPI application in action.
Configuring FastAPI with Docker-compose
Docker-compose is a tool for defining and running multi-container Docker applications. For FastAPI and many other applications, it’s especially useful when you need to link your application with services like databases, cache systems, etc. For the sake of simplicity, we’ll demonstrate setting up docker-compose just for the FastAPI application, but you can extend this to other services as well.
1. Install Docker-compose
Before you start, ensure you have Docker-compose installed. If not, you can install it by following instructions.
2. Create a docker-compose.yml file
In the root directory of your FastAPI application, create a file named `docker-compose.yml` and populate it with the following:
version: '3.8'
services:
web:
build: .
command: ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80", "--reload"]
ports:
- "8000:80"
volumes:
- .:/app
environment:
- PYTHONUNBUFFERED=1
In this configuration:
- version: Specifies the version of Docker-compose file format.
- services: Defines the services to run.
- web: Name of our FastAPI service.
- build: Specifies the directory where the Dockerfile resides (in this case, the current directory).
- command: This overrides the CMD set in the Dockerfile.
- ports: Maps port 8000 on the host to port 80 on the container.
- volumes: Synchronizes the current directory (your FastAPI code) with /app inside the container.
- environment: Sets environment variables for the container. We only set PYTHONUNBUFFERED=1 for this example.
3. Start the Docker-compose Services
With the `docker-compose.yml` file in place, navigate to the root directory of your FastAPI application and run:
docker-compose up
This command tells Docker-compose to start the services defined in `docker-compose.yml`. In our example, it builds and starts the FastAPI application.
Now, if you go to http://localhost:8000, you should see your FastAPI application running.
4. Stopping the Services
To stop the services started by Docker-compose, simply press Ctrl+C in the terminal where docker-compose up is running. To stop and remove all containers defined in the docker-compose.yml, you can run:
docker-compose down
Conclusion
By following the steps above, you’ve successfully dockerized a FastAPI application. Dockerizing your applications offers several benefits, including consistent environments, easier scaling, and simplified deployment. With FastAPI’s speed and Docker’s convenience, you’re well-equipped to build and deploy high-performance web applications.
By integrating Docker-compose into your Docker setup, you’ve added a level of flexibility and scalability. Now, you can easily add other services (like databases, caching systems, etc.) by extending the docker-compose.yml file. Docker-compose ensures that all the services you define can seamlessly communicate with each other, giving you a cohesive environment for your application’s components.