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
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
π‘ Security Tips:
Create a non-root user:
adduser ubuntu
usermod -aG sudo ubuntu
Set up the UFW firewall:
ufw allow OpenSSH
ufw allow 'Nginx Full'
ufw enable
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
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
Or use the standard venv:
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
4. Run the Project Manually (Test)
Test your project manually first:
poetry run uvicorn app.main:app --host 0.0.0.0 --port 8000
Or, if using venv:
venv/bin/uvicorn app.main:app --host 0.0.0.0 --port 8000
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
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
Activate the service:
sudo systemctl daemon-reload
sudo systemctl enable fastapi
sudo systemctl start fastapi
sudo systemctl status fastapi
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
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;
}
}
Enable the config:
sudo ln -s /etc/nginx/sites-available/fastapi /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
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
SSL will be automatically installed and Nginx updated to HTTPS.
Check status:
sudo systemctl reload nginx
8. Testing & Monitoring
Test your service:
curl -I https://yourdomain.com
View real-time logs:
sudo journalctl -u fastapi -f
Restart service after code updates:
sudo systemctl restart fastapi
9. Extra Tips for Developers
- Use tmux to keep manual sessions running.
- Add auto-deploy via Git hook:
git pull && sudo systemctl restart fastapi
- 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
Each can auto-run and be monitored with:
sudo systemctl status telegram-bot
sudo systemctl status fastapi
Top comments (3)
Nice, I was looking for something like this. Thanks.
Awesome! Happy to hear that it helped π
Iβve got a few more deployment and FastAPI tips coming next β thanks for reading!
will definitely read them