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
- 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.
- 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
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
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
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
- 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
- Install Nginx: Nginx will act as a reverse proxy, handling client requests and passing them to your FastAPI app.
sudo apt install nginx -y
- 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
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: Replaceyour_droplet_ip_address
with 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;
}
}
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-enabled
directory:
sudo ln -s /etc/nginx/sites-available/fastapi_app /etc/nginx/sites-enabled/
- Test the Nginx configuration for syntax errors:
sudo nginx -t
If successful, restart Nginx:
sudo systemctl restart nginx
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
Install Dependencies with Pipenv:
pipenv install
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
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
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
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
Enable and start the service:
sudo systemctl daemon-reload
sudo systemctl enable fastapi.service
sudo systemctl start fastapi.service
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:
- SSH into your Droplet.
-
git pull
the latest code. -
pipenv install
any new dependencies. - 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)