DEV Community

Zaenal Arifin
Zaenal Arifin

Posted on

πŸš€ Deploying a FastAPI Project to an Ubuntu VPS β€” A Complete Guide for Developers

As an independent developer, I often get asked: how do you deploy a Python project to a VPS so it runs automatically and stays stable?

Well, in this article, I’ll walk you through step-by-step how to host a FastAPI project (or a Python bot) on an Ubuntu VPS β€” complete with systemd, Nginx, and SSL setup.

1. Why Use a VPS?

If you’ve been coding backend projects for a while, chances are you want your project to be accessible online β€” whether it’s an API, a bot, or a web dashboard.

A VPS (Virtual Private Server) gives you:

  • Full freedom (root access)
  • Ability to install anything (Python, Docker, etc.)
  • Faster and more stable than shared hosting

Popular providers:

πŸ‘‰ DigitalOcean, Vultr, Linode, Hetzner, or HostHatch.

2. VPS Preparation

Log in to your VPS using SSH:

ssh root@ip-address-vps
Enter fullscreen mode Exit fullscreen mode

Then update the system and install basic packages:

sudo apt update && sudo apt upgrade -y
sudo apt install python3 python3-venv python3-pip git nginx ufw -y
Enter fullscreen mode Exit fullscreen mode

πŸ’‘ Security Tips:

Create a non-root user:

adduser ubuntu
usermod -aG sudo ubuntu
Enter fullscreen mode Exit fullscreen mode

Set up the UFW firewall:

ufw allow OpenSSH
ufw allow 'Nginx Full'
ufw enable
Enter fullscreen mode Exit fullscreen mode

3. Clone Project to the Server

Go to a safe directory to store your source code:

cd /opt
sudo git clone https://github.com/username/project.git
sudo chown -R ubuntu:ubuntu project
cd project
Enter fullscreen mode Exit fullscreen mode

If you’re using Poetry, install it first:

curl -sSL https://install.python-poetry.org | python3 -
export PATH="$HOME/.local/bin:$PATH"
poetry install --no-root
Enter fullscreen mode Exit fullscreen mode

Or use the standard venv:

python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
Enter fullscreen mode Exit fullscreen mode

4. Run the Project Manually (Test)

Test your project manually first:

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

Or, if using venv:

venv/bin/uvicorn app.main:app --host 0.0.0.0 --port 8000
Enter fullscreen mode Exit fullscreen mode

Then open your browser:
πŸ‘‰ http://<vps-ip>:8000

If you see the FastAPI default page β€” it’s running fine.

5. Create a Systemd Service

To make the project auto-start on VPS reboot and manageable via systemctl.

Create a new service file:

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

Add the following:

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

[Service]
User=ubuntu
WorkingDirectory=/opt/project
ExecStart=/home/ubuntu/.local/bin/poetry run uvicorn app.main:app --host 127.0.0.1 --port 8000
Restart=always
Environment="PATH=/home/ubuntu/.local/bin:/usr/bin"

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

Activate the service:

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

If the status shows active (running) β€” everything’s good.

πŸ’‘ Use journalctl -u fastapi -f to view real-time logs.

6. Configure Nginx (Reverse Proxy)

This allows your app to be accessed via port 80/443 (HTTP/HTTPS).

Create a new config file:

sudo vim /etc/nginx/sites-available/fastapi
Enter fullscreen mode Exit fullscreen mode

Add the following:

server {
    server_name yourdomain.com;

    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;
    }
}
Enter fullscreen mode Exit fullscreen mode

Enable the config:

sudo ln -s /etc/nginx/sites-available/fastapi /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
Enter fullscreen mode Exit fullscreen mode

Now open your browser:
πŸ‘‰ http://yourdomain.com

If it loads correctly β€” your setup is complete.

7. Install Free SSL (Let’s Encrypt)

Use certbot:

sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d yourdomain.com
Enter fullscreen mode Exit fullscreen mode

SSL will be automatically installed and Nginx updated to HTTPS.

Check status:

sudo systemctl reload nginx
Enter fullscreen mode Exit fullscreen mode

8. Testing & Monitoring

Test your service:

curl -I https://yourdomain.com
Enter fullscreen mode Exit fullscreen mode

View real-time logs:

sudo journalctl -u fastapi -f
Enter fullscreen mode Exit fullscreen mode

Restart service after code updates:

sudo systemctl restart fastapi
Enter fullscreen mode Exit fullscreen mode

9. Extra Tips for Developers

  • Use tmux to keep manual sessions running.
  • Add auto-deploy via Git hook:
  git pull && sudo systemctl restart fastapi
Enter fullscreen mode Exit fullscreen mode
  • Save logs to a custom file in /var/log/fastapi.log.
  • If you run multiple projects, create separate systemd services for each.
  • Use fail2ban to secure SSH and Nginx.

10. Conclusion

Now you have a VPS that:

  • Runs FastAPI 24/7
  • Is secure, auto-started, and SSL-ready
  • Can be redeployed easily with git pull + restart

With this setup, you can professionally and efficiently deploy backends, Telegram bots, or internal APIs.

In the next article, I’ll cover auto-deploy CI/CD using GitHub Actions directly to your VPS β€” stay tuned!

πŸ’¬ Bonus: Quick Multi-App systemd Template

If you have multiple projects (e.g., a bot and a web app):

sudo vim /etc/systemd/system/telegram-bot.service
sudo vim /etc/systemd/system/fastapi.service
Enter fullscreen mode Exit fullscreen mode

Each can auto-run and be monitored with:

sudo systemctl status telegram-bot
sudo systemctl status fastapi
Enter fullscreen mode Exit fullscreen mode

Top comments (3)

Collapse
 
dshaw0004 profile image
Dipankar Shaw

Nice, I was looking for something like this. Thanks.

Collapse
 
1amkaizen profile image
Zaenal Arifin

Awesome! Happy to hear that it helped πŸ˜„
I’ve got a few more deployment and FastAPI tips coming next β€” thanks for reading!

Collapse
 
dshaw0004 profile image
Dipankar Shaw

will definitely read them