Deploy FastAPI to DigitalOcean Droplet
DigitalOcean is one of the leading cloud infrastructure service providers, offering a simple yet powerful platform for deploying web applications. In this tutorial, we will walk through the process of deploying a FastAPI application on a DigitalOcean droplet using Docker and Nginx.
Provision a Droplet
Visit DigitalOcean and create an account or login with your existing account. Then follow these steps to create your droplet:
- Select Ubuntu (my preferred option, though you can use any Linux distro)
- The $4/month plan is suitable for a test/simple project
- Select a datacenter closer to your targeted audience (not necessarily closest to you)
- Choose SSH Key as the authentication method
- Add your SSH key to the droplet so you can easily and securely access it from your local computer
Tip: For production applications, consider a higher-tier plan with more resources. The pricing is still very reasonable compared to other cloud providers.
Generate SSH Key
To generate an SSH key, you can use the ssh-keygen
command in your terminal. Here is how:
- Open your terminal
- Type the following command and press Enter:Replace
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
"your_email@example.com"
with your own email address. - You will be prompted to choose a location to save the key. Press Enter to accept the default location (
/Users/your_username/.ssh/id_rsa
) or specify a different location. - Next, you will be prompted to enter a passphrase. It is optional, but recommended for added security. Press Enter if you don't want to set a passphrase.
- The SSH key pair will be generated and saved in the specified location.
- You can now use the public key (
id_rsa.pub
) to add it to your DigitalOcean droplet.
Important: Keep your private key (id_rsa
) secure and never share it with anyone.
Create a User Account
It is a best practice to create a non-root user for security reasons. To create a user account on Linux, you can use the adduser
command:
- SSH into your droplet using the command:Replace
ssh username@your_droplet_ip
username
with the desired username andyour_droplet_ip
with the IP address of your droplet. - Once logged in, run the following command to create a new user:Replace
sudo adduser new_username
new_username
with the desired username for the new account. - You will be prompted to set a password for the new user. Follow the instructions to set a secure password.
- Provide additional information for the user, such as their full name and contact information, or press Enter to leave them blank.
- Confirm the information and press Enter.
Grant Privileges to the User
After creating the user account, you will want to grant administrative privileges to the user:
- Run the following command to add the user to the
sudo
group:Replaceusermod -aG sudo new_username
new_username
with the username you created earlier. - The user now has administrative privileges and can execute commands with
sudo
.
Note: You may need to create a .ssh directory for the new user and copy the SSH key you added to the user's .ssh directory.
Add SSH Key to User
To enable SSH login for the new user without a password:
- Login as root or current user
- Change user:
su - new_username
- Create .ssh directory:
mkdir ~/.ssh
- Change directory permission:
chmod 700 ~/.ssh
- Copy the SSH key (.pub file) and paste the content:
nano ~/.ssh/authorized_keys
- Exit and now login as the new user.
Read more about how to add a new user to your droplet on DigitalOcean's community tutorials.
Update the Droplet
Once connected to your droplet, use the following command to update the machine:
sudo apt update && apt upgrade -y
This ensures your system has the latest security patches and software updates.
Install and Configure Nginx
We will be using Nginx, a popular open-source web server software that serves as a reverse proxy server, load balancer, media streamer, and HTTP cache.
Use this code to install Nginx:
sudo apt install nginx -y
Use the following commands to start and enable Nginx:
systemctl start nginx systemctl enable nginx
Note: Once Nginx is installed, you should be able to see the default Nginx welcome page by visiting your droplet's IP address in a web browser.
Install Docker
We will be using Docker to containerize our FastAPI application. Use this command to install Docker:
sudo apt-get install docker-ce docker-ce-cli containerd.io
Set up Docker Compose:
curl -L
"https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname
-s)-$(uname -m)" -o /usr/local/bin/docker-compose chmod +x
/usr/local/bin/docker-compose
Tip: You might want to check for the latest version of Docker Compose on the official GitHub repository.
Prepare Your FastAPI Application
Create a new directory for your project:
mkdir -p /var/www/myapi
Once the directory is created, you can either:
- Clone your FastAPI application from a Git repository
- Create your FastAPI application files directly on the server
- Upload your application files using SCP or SFTP
For a basic FastAPI application, create the following files in your project directory:
# main.py
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: str = None):
return {"item_id": item_id, "q": q}
# requirements.txt
fastapi==0.95.0
uvicorn==0.21.1</code></pre>
</div>
<div className="bg-gray-100 p-4 rounded-md my-4">
<pre><code># Dockerfile
FROM python:3.9
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
# docker-compose.yml
version: '3'
services:
api:
build: .
ports:
- "8000:8000"
restart: always
Configure Nginx as a Reverse Proxy
Create an Nginx configuration file for your FastAPI application:
sudo nano /etc/nginx/sites-available/myapi
Add the following configuration:
server {
listen 80;
server_name your_domain.com; # Replace with your domain or IP address
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;
}
}
Enable the configuration by creating a symbolic link:
sudo ln -s /etc/nginx/sites-available/myapi /etc/nginx/sites-enabled/
Test the Nginx configuration:
sudo nginx -t
If the test is successful, restart Nginx:
sudo systemctl restart nginx
Deploy Your FastAPI Application
Navigate to your project directory:
cd /var/www/myapi
Build and start your Docker containers:
docker-compose up -d
This will build the Docker image and start the container in detached mode.
Tip: You can view the logs of your container with docker-compose logs -f
.
Secure Your Application with HTTPS (Optional)
For a production application, you should secure your API with HTTPS. You can use Certbot and Let's Encrypt to get a free SSL certificate:
sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d your_domain.com
Follow the prompts to complete the certificate installation. Certbot will automatically modify your Nginx configuration to use HTTPS.
Testing Your Deployment
Now that your FastAPI application is deployed, you can test it by visiting your domain or IP address in a web browser. You should see the JSON response from your API:
{"Hello": "World"}
You can also test the interactive API documentation that FastAPI automatically generates by visiting:
http://your_domain.com/docs
Conclusion
Congratulations! You have successfully deployed your FastAPI application to a DigitalOcean droplet using Docker and Nginx. Your application is now accessible on the internet and can be used by clients worldwide.
This setup provides a solid foundation for your API, but there are additional steps you might want to take depending on your needs:
- Set up a firewall using UFW to further secure your server
- Configure database connections for your API
- Implement CI/CD pipelines for automated deployments
- Set up monitoring and logging for your application
- Configure auto-scaling if your application needs to handle variable loads
Remember to regularly update your server and dependencies to ensure your application remains secure and reliable.