ShortIQ

ShortIQ

Deployment

How to Deploy FastAPI on Ubuntu 24 with Nginx and SSL Certificate

A step-by-step guide to deploying a FastAPI application on Ubuntu 24.04 with Nginx as a reverse proxy, a systemd service for process management, and a free SSL certificate from Certbot.

June 10, 2026ShortIQ Editorial Team

Advertisement

Prerequisites

This guide walks through a complete FastAPI deployment on Ubuntu 24.04: installing the dependencies, creating a systemd service so FastAPI restarts automatically, configuring Nginx as a reverse proxy, and securing everything with a free SSL certificate from Certbot. By the end, your API will be running at https://yourdomain.com, served over HTTPS, managed by systemd, and proxied through Nginx.

You need an Ubuntu 24.04 server (VPS, AWS EC2, DigitalOcean Droplet, or similar), a domain name with an A record pointing to your server IP address, SSH access as a non-root user with sudo privileges, and a FastAPI application ready to deploy.

Step 1: Update the Server and Install Python

Connect to your server via SSH and update the package list. Ubuntu 24.04 ships with Python 3.12 — verify it is installed and then install pip and the venv module.

Run: sudo apt update && sudo apt upgrade -y then sudo apt install -y python3-pip python3-venv. Verify Python is working with python3 --version.

bash
sudo apt update && sudo apt upgrade -y
python3 --version
# Python 3.12.x
sudo apt install -y python3-pip python3-venv

Step 2: Set Up Your Application Directory

Create a directory for your application and set up a Python virtual environment. Using a virtual environment keeps your application dependencies isolated from the system Python packages.

bash
sudo mkdir -p /var/www/myapi
sudo chown $USER:$USER /var/www/myapi
cd /var/www/myapi
python3 -m venv venv
source venv/bin/activate
pip install fastapi uvicorn[standard] gunicorn

Step 3: Upload Your Application and Test Locally

Clone your repository or upload your application files to /var/www/myapi. If you do not have an application yet, create a minimal main.py to verify the setup works before configuring Nginx.

Test that the application runs locally before setting up Nginx. Run uvicorn main:app --host 127.0.0.1 --port 8000 and verify it starts without errors. Use Ctrl+C to stop it once confirmed.

python
# main.py
from fastapi import FastAPI

app = FastAPI()

@app.get("/health")
def health_check():
    return {"status": "healthy"}

Step 4: Create a Systemd Service

A systemd service ensures your FastAPI application starts automatically when the server boots and restarts if it crashes. Create the service file at /etc/systemd/system/myapi.service.

The service uses Gunicorn with the UvicornWorker class, which is the recommended way to run FastAPI in production. It provides multiple worker processes and proper signal handling. The application binds to 127.0.0.1:8000, not 0.0.0.0, because Nginx will proxy requests to it.

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

[Service]
User=ubuntu
Group=ubuntu
WorkingDirectory=/var/www/myapi
Environment="PATH=/var/www/myapi/venv/bin"
ExecStart=/var/www/myapi/venv/bin/gunicorn main:app     --workers 2     --worker-class uvicorn.workers.UvicornWorker     --bind 127.0.0.1:8000
Restart=always
RestartSec=3

[Install]
WantedBy=multi-user.target
bash
sudo systemctl daemon-reload
sudo systemctl enable myapi
sudo systemctl start myapi
sudo systemctl status myapi

Step 5: Install and Configure Nginx

Install Nginx and create a site configuration. The configuration proxies all requests to your Gunicorn process on port 8000 and sets the appropriate headers so your FastAPI application can read the real client IP address and protocol.

nginx
server {
    listen 80;
    server_name api.yourdomain.com;

    access_log /var/log/nginx/myapi_access.log;
    error_log /var/log/nginx/myapi_error.log;

    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;
        proxy_read_timeout 60s;
        proxy_buffering off;
    }
}
bash
sudo ln -s /etc/nginx/sites-available/myapi /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Step 6: Add SSL with Certbot

Install Certbot and request a free SSL certificate from the ACME certificate authority. Certbot will automatically update your Nginx configuration to handle HTTPS and set up a systemd timer for automatic certificate renewal.

After running certbot --nginx, your Nginx configuration will be updated with the certificate paths and an HTTPS server block. The --nginx flag handles this automatically. Certbot will also ask whether to redirect HTTP to HTTPS — choose yes to enforce HTTPS for all traffic.

bash
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d api.yourdomain.com
# Test automatic renewal
sudo certbot renew --dry-run

Step 7: Configure the Firewall

Configure UFW to allow only the ports your server needs. After running certbot, your server should only accept SSH, HTTP (for redirects), and HTTPS traffic. Port 8000 should not be publicly accessible because your application only listens on 127.0.0.1.

bash
sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable
sudo ufw status

Step 8: Test the Deployment

Test that HTTPS is working, that HTTP redirects to HTTPS, and that your API endpoints are responding correctly. In production you may want to disable the automatic FastAPI docs by passing docs_url=None and redoc_url=None when NODE_ENV is production.

bash
# Should return {"status":"healthy"}
curl https://api.yourdomain.com/health

# Should show a 301 redirect to HTTPS
curl -I http://api.yourdomain.com/

Deploying Updates

When you push a new version of your application, the deployment process is straightforward. Gunicorn handles graceful restarts: it finishes processing current requests before stopping worker processes, which means there is effectively zero downtime for most deployments.

bash
cd /var/www/myapi
git pull origin main
source venv/bin/activate
pip install -r requirements.txt
sudo systemctl restart myapi
sudo systemctl status myapi

Troubleshooting Common Issues

502 Bad Gateway from Nginx means Nginx cannot reach Gunicorn. Check that the FastAPI service is running with sudo systemctl status myapi and that it is listening on port 8000 with sudo ss -tlnp | grep 8000.

If the application starts but returns 500 errors, check the application logs with sudo journalctl -u myapi -f. For SSL certificate renewal failures, verify that port 80 is open in your firewall and that your domain A record resolves to the correct server IP address.

FAQ

Should I use Gunicorn or Uvicorn directly in production?

Use Gunicorn with the UvicornWorker as shown in this guide. Running Uvicorn directly with a single process is fine for development but does not give you multiple worker processes or proper signal handling for graceful restarts. Gunicorn manages the worker processes and handles SIGTERM correctly, which matters for deployments.

How many Gunicorn workers should I set?

A common starting formula is (2 x CPU cores) + 1. For a 1-core server use 3 workers, for a 2-core server use 5 workers. Monitor memory usage: if workers are consuming too much RAM, reduce the count. For async FastAPI endpoints that spend most of their time waiting on I/O, a smaller worker count is often sufficient.

Can I run multiple FastAPI apps on the same server?

Yes. Create a separate systemd service for each app on a different port (8000, 8001, 8002, etc.) and a separate Nginx server block for each domain. Each app gets its own virtual environment and systemd service, and Nginx routes traffic to the correct one based on the domain name.

Do I need to restart Nginx after getting an SSL certificate?

Certbot reloads Nginx automatically after issuing the certificate. For manual changes to the Nginx configuration, run sudo nginx -t to check for syntax errors and then sudo systemctl reload nginx to apply the changes without dropping active connections.

Related free tools

If you want to turn this topic into action, use one of ShortIQ's free tools for campaign planning, UTM structure, or QR distribution.

Continue Reading

Explore more guides on link shortener SaaS strategy, Bitly alternatives, and white label link management.

Free newsletter

Get new guides in your inbox

We publish practical guides on dev tooling, prompt engineering, marketing workflows, and deployment. No fluff — straight to the point.

No spam. Unsubscribe any time.

Was this article helpful?

Tell us if this guide solved the problem or what was still missing. We use this to improve the blog and only follow up if you explicitly allow it.

We use this to improve tutorials, examples, and technical depth.