DEV Community

Cover image for The FastAPI Deployment Cookbook: Recipe for deploying FastAPI app with Docker and DigitalOcean"
Sujit Kumar
Sujit Kumar

Posted on

The FastAPI Deployment Cookbook: Recipe for deploying FastAPI app with Docker and DigitalOcean"

From Local to Live: My Journey Deploying FastAPI with Docker on DigitalOcean

Hey there, fellow developers! Today, I want to share my recent experience deploying a FastAPI application using Docker on a DigitalOcean droplet. It was quite a learning curve, but I've broken it down into manageable steps that I hope will help you avoid some of the pitfalls I encountered. Let's dive in!

What You'll Need Before We Start

  • A DigitalOcean account (I'm using a basic droplet with Docker pre-installed)
  • Some familiarity with Docker and FastAPI (but don't worry if you're new, we'll go through this together!)
  • SSH access to your droplet

Step 1: Crafting Your FastAPI App

First things first, let's create a simple FastAPI app. Here's the bare-bones version I started with:

main.py

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
    return {"message": "Hello from FastAPI"}
Enter fullscreen mode Exit fullscreen mode

Pretty straightforward, right? This just returns a JSON response when you hit the root endpoint.

Step 2: Don't Forget Your Dependencies!

I learned this the hard way: always keep your requirements.txt updated. Here's what mine looks like:

requirements.txt

fastapi
uvicorn
Enter fullscreen mode Exit fullscreen mode

Pro tip: Use pip freeze > requirements.txt to automatically generate this file from your current environment.

Step 3: Dockerizing Your App

Now, let's containerize our app. Here's the Dockerfile I ended up with after some tweaking:

Dockerfile

FROM python:3.11-slim
WORKDIR /app
COPY . /app
RUN pip install --no-cache-dir -r requirements.txt
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]  #or second command will work only when your main.py file contains your initial fastapi setup
# CMD ["fastpi", "run", "--host", "0.0.0.0", "--port", "8000"]  
Enter fullscreen mode Exit fullscreen mode

Step 4: Building and Running Your Docker Container

Here's where the magic happens. SSH into your DigitalOcean droplet:

ssh user@your_droplet_ip
Enter fullscreen mode Exit fullscreen mode

Note: You can build your docker image locally then push it on dockerhub and after that you can pull your app-image on your production server directly. But for now we are building our docker image on production sever
Once logged in, run these commands:

docker build -t fastapi-app .
docker run -d --name fastapi-app -p 8000:8000 fastapi-app
Enter fullscreen mode Exit fullscreen mode

Quick tip: Add --restart unless-stopped to the docker run command to make your container restart automatically if it crashes or if your droplet reboots.

Step 5: Verifying Your Deployment

After deployment, you can check the status of your running FastAPI app:

docker ps
Enter fullscreen mode Exit fullscreen mode

To view the logs of your FastAPI app:

docker logs fastapi-app
Enter fullscreen mode Exit fullscreen mode

To view stats of docker container usage(memory, cpu usage) of each running container

docker stats
Enter fullscreen mode Exit fullscreen mode

Step 6: Accessing Your Live Website

Your FastAPI app should now be accessible at http://your_droplet_ip:8000. Open this URL in your browser to see your live website!

Important Note: If your main file is named main.py and contains the FastAPI app instance named app, you can use the fastapi run command instead of the custom uvicorn setup. However, when using Docker, we typically stick with the uvicorn command for more control over the host and port settings.

Step 7: Setting Up Nginx as a Reverse Proxy (Optional)

Setting up Nginx as a reverse proxy can improve performance and security. Here's how to do it:

  1. Install Nginx:
   sudo apt update
   sudo apt install nginx
Enter fullscreen mode Exit fullscreen mode
  1. Create a new config file:
   sudo nano /etc/nginx/sites-available/fastapi
Enter fullscreen mode Exit fullscreen mode
  1. Add this configuration:
   server {
       listen 80;
       server_name your_domain_or_ip;

       location / {
           proxy_pass http://localhost:8000;
           proxy_set_header Host $host;
           proxy_set_header X-Real-IP $remote_addr;
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
           proxy_set_header X-Forwarded-Proto $scheme;
       }
   }
Enter fullscreen mode Exit fullscreen mode
  1. Enable the config and restart Nginx:
   sudo ln -s /etc/nginx/sites-available/fastapi /etc/nginx/sites-enabled/
   sudo systemctl restart nginx
Enter fullscreen mode Exit fullscreen mode

If you set up Nginx, your app will be accessible at http://your_droplet_ip (without the port number).

Bonus Tips I Wish I'd Known Earlier

  1. HTTPS is a must: I highly recommend setting up HTTPS using Let's Encrypt. It's free and easier than you might think!

  2. Monitoring is key: I use Prometheus and Grafana to keep an eye on my app's performance. It's saved me more than once!

  3. Automate your deployments: Look into CI/CD pipelines. I use GitHub Actions, and it's been a game-changer for my workflow.

  4. Keep your images lean: Use multi-stage builds to keep your Docker images as small as possible. It'll save you time and resources in the long run.

  5. Environment variables are your friends: Don't hardcode sensitive information. Use environment variables or Docker secrets instead.

Wrapping Up

Deploying FastAPI with Docker on DigitalOcean has been an exciting journey for me. It's opened up a whole new world of possibilities for my web development projects. I hope this guide helps you on your own deployment adventures!

Have you tried deploying FastAPI or any other Python web framework? I'd love to hear about your experiences in the comments. And if you found this guide helpful, don't forget to share it with your fellow devs!

Happy coding, and may your deployments always be smooth! 🚀

Top comments (2)

Collapse
 
raajaryan profile image
Deepak Kumar

Hello everyone,

I hope you're all doing well. I recently launched an open-source project called the Ultimate JavaScript Project, and I'd love your support. Please check it out and give it a star on GitHub: Ultimate JavaScript Project. Your support would mean a lot to me and greatly help in the project's growth.

Thank you!

Collapse
 
mnamesujit profile image
Sujit Kumar

sure buddy