DEV Community

marlinekhavele
marlinekhavele

Posted on

Deploying a FastAPI Application on Digital Ocean Droplet with Nginx and CI/CD

Deploying a FastAPI application with Nginx on Digital Ocean droplet can be challenging especially for beginners. This guide will walk you through setting up an Droplet, installing necessary dependencies, configuring Nginx as a reverse proxy, and setting up a CI/CD pipeline with GitHub Actions.
Prerequisites

  • A Digital Ocean account.
  • A FastAPI application in a GitHub repository.
  • Basic familiarity with the command line and SSH.

Part 1: Setting Up Your Digital Ocean Droplet

  1. Create a Droplet:
  • Log in to your Digital Ocean dashboard and click "Create" -> "Droplets".
  • Choose Ubuntu (a recent LTS version like 22.04 or 24.04) as your distribution.
  • Select a plan. The Basic Shared CPU plan is a great starting point.
  • Choose a datacenter region closest to you.
  • Authentication: For security, highly prefer SSH keys over a password. Add your SSH public key. If you haven't set one up, follow this guide.
  • Finalize and create the Droplet.
  1. Access Your Droplet:
  • Once created, find the Droplet's public IP address in your dashboard.
  • Open your terminal and connect:
ssh root@your_droplet_ip_address
Enter fullscreen mode Exit fullscreen mode

Part 2: Server Setup and Application Installation
Once logged in as root, run these commands to prepare your server.

  • Create a Non-root User (Security Best Practice):
adduser deployer
usermod -aG sudo deployer
Enter fullscreen mode Exit fullscreen mode

This creates a new user named deployer and adds it to the sudo group.

  • Copy your SSH key to the new user to allow password less login:
rsync --archive --chown=deployer:deployer ~/.ssh /home/deployer
Enter fullscreen mode Exit fullscreen mode

Now, you can disconnect and log in as the new user: ssh deployer@your_droplet_ip_address.

  • Update the System:
sudo apt update && sudo apt upgrade -y
Enter fullscreen mode Exit fullscreen mode
  • Install Python, Pip, and Pipenv: We will use pipenv for managing your application's virtual environment and dependencies.
sudo apt install python3-pip -y
pip3 install pipenv
Enter fullscreen mode Exit fullscreen mode
  • Install Nginx: Nginx will act as a reverse proxy, handling client requests and passing them to your FastAPI app.
sudo apt install nginx -y
Enter fullscreen mode Exit fullscreen mode
  • Set Up Firewall (UFW): Configure the firewall to allow SSH, HTTP, and HTTPS traffic.
sudo ufw allow 'OpenSSH'
sudo ufw allow 'Nginx Full'
sudo ufw enable
Enter fullscreen mode Exit fullscreen mode

Part 3: Configuring Nginx as a Reverse Proxy
Create an Nginx Configuration File:

  • Create a new file for your site in /etc/nginx/sites-available/. Paste the following configuration: Replace your_droplet_ip_addresswith your actual IP or domain name if you have one.
server {
    listen 80;
    server_name your_droplet_ip_address;

    location / {
        proxy_pass http://127.0.0.1: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

This tells Nginx to listen on port 80 and forward all traffic to the FastAPI application running on 127.0.0.1:8000.

Enable the Configuration:

  • Create a symbolic link to the sites-enableddirectory:
sudo ln -s /etc/nginx/sites-available/fastapi_app /etc/nginx/sites-enabled/
Enter fullscreen mode Exit fullscreen mode
  • Test the Nginx configuration for syntax errors:
sudo nginx -t
Enter fullscreen mode Exit fullscreen mode

If successful, restart Nginx:

sudo systemctl restart nginx
Enter fullscreen mode Exit fullscreen mode

Part 4: Deploying the Application Manually

Clone Your Repository:

git clone https://github.com/your_username/your_repo_name.git /home/deployer/app
cd /home/deployer/app
Enter fullscreen mode Exit fullscreen mode

Install Dependencies with Pipenv:

pipenv install
Enter fullscreen mode Exit fullscreen mode

Run the Application:
Let's test if everything works. Run your app inside the Pipenv shell

pipenv run uvicorn main:app --host 0.0.0.0 --port 8000
Enter fullscreen mode Exit fullscreen mode

Visit http://your_droplet_ip_address in your browser. You should see your FastAPI app running behind Nginx! Press Ctrl+C to stop the server.

Part 5: Automating Deployments with GitHub Actions CI/CD
We'll create a workflow that automatically deploys our app when we push to the main branch.

Create GitHub Secrets:
In your GitHub repository, go to Settings > Secrets and variables > Actions.

  • Create two new secrets: HOST: Your Droplet's IP address. SSH_PRIVATE_KEY: The entire contents of your private SSH key (the one that matches the public key you added to Digital Ocean).

Create the Workflow File:
In your repo, create the directory .github/workflows/ and a file inside it named deploy.yml.

Configure the Deployment Workflow:
Paste the following YAML configuration into .github/workflows/deploy.yml:

name: Deploy to DigitalOcean Droplet

on:
  push:
    branches: [ main ]

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
    - name: Checkout code
      uses: actions/checkout@v4

    - name: Deploy to Droplet
      uses: appleboy/ssh-action@v1.0.0
      with:
        host: ${{ secrets.HOST }}
        username: deployer
        key: ${{ secrets.SSH_PRIVATE_KEY }}
        script: |
          cd /home/deployer/app
          git pull origin main
          pipenv install
          sudo systemctl restart fastapi.service
Enter fullscreen mode Exit fullscreen mode

Create a Systemd Service

The CI/CD script above tries to run sudo systemctl restart fastapi.service. We need to create this service to run our app in the background and restart on reboot.
On your Droplet,create a service file:

sudo nano /etc/systemd/system/fastapi.service
Enter fullscreen mode Exit fullscreen mode

Paste the following configuration, adjusting paths if necessary (User, WorkingDirectory, and the command):

[Unit]
Description=FastAPI Application
After=network.target

[Service]
User=deployer
Group=www-data
WorkingDirectory=/home/deployer/app
Environment="PATH=/home/deployer/.local/bin"
ExecStart=/usr/local/bin/pipenv run uvicorn main:app --host 0.0.0.0 --port 8000

[Install]
WantedBy=multi-user.target
Enter fullscreen mode Exit fullscreen mode

Enable and start the service:

sudo systemctl daemon-reload
sudo systemctl enable fastapi.service
sudo systemctl start fastapi.service
Enter fullscreen mode Exit fullscreen mode

You can check its status with: sudo systemctl status fastapi.service.

You're Live!
Your automated pipeline is now set up. The next time you push code to the main branch on GitHub, the GitHub Action will:

  1. SSH into your Droplet.
  2. git pull the latest code.
  3. pipenv install any new dependencies.
  4. Restart the fastapi.service to apply the changes.

You can now visit your Droplet's IP address in a web browser, and you will see your automatically deployed FastAPI application!

Top comments (0)