Python Framework

    Deploy FastAPI on RamNode VPS

    Production-ready setup with Uvicorn, Gunicorn, Nginx reverse proxy, SSL, and systemd process management.

    Ubuntu 22.04/24.04 LTS
    Python 3.11+
    ⏱️ 30-45 minutes

    What is FastAPI?

    FastAPI is one of the fastest-growing Python web frameworks, known for high performance, automatic API documentation, and modern async support. This guide takes you from initial server setup through production hardening.

    • High Performance: Built on Starlette and Pydantic
    • Auto Documentation: Swagger UI & ReDoc out of the box
    • Async Support: Native async/await for I/O-bound workloads
    • Type Safety: Python type hints with validation
    • WebSocket Support: Real-time communication built in
    • Production Ready: Gunicorn + Uvicorn workers
    1

    Prerequisites

    RequirementDetails
    RamNode VPSMinimum 1 GB RAM, 1 vCPU (2 GB+ recommended)
    Operating SystemUbuntu 22.04 LTS or Ubuntu 24.04 LTS
    Domain NameA domain pointed to your VPS IP (for SSL)
    SSH AccessRoot or sudo-capable user
    2

    Initial Server Setup

    Connect to Your VPS
    ssh root@your-server-ip
    Update System Packages
    apt update && apt upgrade -y

    Create a Non-Root User

    Running applications as root is a security risk. Create a dedicated user:

    Create Deploy User
    adduser deploy
    usermod -aG sudo deploy
    su - deploy

    Configure the Firewall

    UFW Configuration
    sudo ufw allow OpenSSH
    sudo ufw allow 80/tcp
    sudo ufw allow 443/tcp
    sudo ufw enable
    sudo ufw status
    💡 Tip: Always allow SSH before enabling the firewall to avoid locking yourself out.
    3

    Install Python and Dependencies

    FastAPI requires Python 3.8+, but Python 3.11+ is recommended for optimal performance.

    Install Python 3.11+
    sudo apt install -y python3 python3-pip python3-venv python3-dev build-essential
    python3 --version
    Create Project Directory
    sudo mkdir -p /opt/fastapi-app
    sudo chown deploy:deploy /opt/fastapi-app
    cd /opt/fastapi-app
    Set Up Virtual Environment
    python3 -m venv venv
    source venv/bin/activate
    Install FastAPI and Uvicorn
    pip install fastapi uvicorn[standard] gunicorn

    The uvicorn[standard] extras package includes uvloop and httptools for better performance.

    4

    Create Your FastAPI Application

    Application Structure

    Project Layout
    /opt/fastapi-app/
    ├── venv/
    ├── app/
    │   ├── __init__.py
    │   ├── main.py
    │   ├── routers/
    │   ├── models/
    │   └── schemas/
    ├── requirements.txt
    └── .env

    Sample Application

    app/main.py
    from fastapi import FastAPI
    from fastapi.middleware.cors import CORSMiddleware
    
    app = FastAPI(
        title="My API",
        description="Deployed on RamNode VPS",
        version="1.0.0"
    )
    
    app.add_middleware(
        CORSMiddleware,
        allow_origins=["https://yourdomain.com"],
        allow_methods=["*"],
        allow_headers=["*"],
    )
    
    @app.get("/")
    async def root():
        return {"message": "Hello from RamNode!"}
    
    @app.get("/health")
    async def health_check():
        return {"status": "healthy"}

    Test Locally

    Run Development Server
    cd /opt/fastapi-app
    source venv/bin/activate
    uvicorn app.main:app --host 0.0.0.0 --port 8000

    Visit http://your-server-ip:8000/docs to see the auto-generated Swagger UI. Press Ctrl+C to stop.

    5

    Configure Gunicorn with Uvicorn Workers

    For production, use Gunicorn as the process manager with Uvicorn worker classes for better process supervision, graceful restarts, and multi-worker support.

    gunicorn.conf.py
    # gunicorn.conf.py
    import multiprocessing
    
    bind = "127.0.0.1:8000"
    workers = multiprocessing.cpu_count() * 2 + 1
    worker_class = "uvicorn.workers.UvicornWorker"
    worker_tmp_dir = "/dev/shm"
    timeout = 120
    keepalive = 5
    errorlog = "/var/log/fastapi-app/error.log"
    accesslog = "/var/log/fastapi-app/access.log"
    loglevel = "info"
    ⚡ Performance: The formula (CPU cores × 2) + 1 is a solid starting point. For a 2-core RamNode VPS, that gives you 5 workers. Adjust based on your workload.
    Create Log Directory
    sudo mkdir -p /var/log/fastapi-app
    sudo chown deploy:deploy /var/log/fastapi-app
    6

    Set Up systemd Service

    systemd ensures your application starts on boot and restarts automatically if it crashes.

    /etc/systemd/system/fastapi-app.service
    [Unit]
    Description=FastAPI Application
    After=network.target
    
    [Service]
    User=deploy
    Group=deploy
    WorkingDirectory=/opt/fastapi-app
    Environment=PATH=/opt/fastapi-app/venv/bin:/usr/bin
    EnvironmentFile=/opt/fastapi-app/.env
    ExecStart=/opt/fastapi-app/venv/bin/gunicorn app.main:app -c gunicorn.conf.py
    ExecReload=/bin/kill -s HUP $MAINPID
    Restart=on-failure
    RestartSec=10
    StandardOutput=journal
    StandardError=journal
    
    [Install]
    WantedBy=multi-user.target
    Enable and Start the Service
    sudo systemctl daemon-reload
    sudo systemctl enable fastapi-app
    sudo systemctl start fastapi-app
    sudo systemctl status fastapi-app

    Useful Service Commands

    CommandDescription
    sudo systemctl restart fastapi-appRestart the application
    sudo systemctl stop fastapi-appStop the application
    sudo journalctl -u fastapi-app -fView live logs
    sudo journalctl -u fastapi-app --since todayView today's logs
    7

    Configure Nginx Reverse Proxy

    Nginx handles SSL termination, static file serving, request buffering, and load distribution.

    Install Nginx
    sudo apt install -y nginx
    sudo systemctl enable nginx
    /etc/nginx/sites-available/fastapi-app
    server {
        listen 80;
        server_name yourdomain.com www.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;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_buffering on;
            proxy_buffer_size 8k;
            proxy_buffers 8 8k;
            proxy_read_timeout 300s;
            proxy_connect_timeout 75s;
        }
    
        # WebSocket support (if needed)
        location /ws {
            proxy_pass http://127.0.0.1:8000;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_set_header Host $host;
        }
    
        client_max_body_size 10M;
    }
    Enable the Configuration
    sudo ln -s /etc/nginx/sites-available/fastapi-app /etc/nginx/sites-enabled/
    sudo rm /etc/nginx/sites-enabled/default
    sudo nginx -t
    sudo systemctl reload nginx
    8

    Enable SSL with Let's Encrypt

    Install Certbot
    sudo apt install -y certbot python3-certbot-nginx
    Obtain Certificate
    sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com

    Certbot will automatically modify your Nginx configuration to redirect HTTP to HTTPS and configure the SSL certificates.

    Verify Auto-Renewal
    sudo certbot renew --dry-run
    📝 Note: Let's Encrypt certificates expire every 90 days. Certbot installs a systemd timer that handles renewals automatically. Verify with: sudo systemctl list-timers | grep certbot
    9

    Environment Variables & Configuration

    /opt/fastapi-app/.env
    APP_ENV=production
    DATABASE_URL=postgresql://user:password@localhost:5432/mydb
    SECRET_KEY=your-secure-random-key-here
    ALLOWED_HOSTS=yourdomain.com
    DEBUG=false
    Set Permissions
    chmod 600 /opt/fastapi-app/.env
    🔒 Security: Never commit .env files to version control. File permissions of 600 ensure only the owning user can read it.

    Load Variables in FastAPI

    Install pydantic-settings
    pip install pydantic-settings
    app/config.py
    from pydantic_settings import BaseSettings
    
    class Settings(BaseSettings):
        app_env: str = "development"
        database_url: str = ""
        secret_key: str = ""
        debug: bool = False
    
        class Config:
            env_file = ".env"
    
    settings = Settings()
    10

    Security Hardening

    SSH Key Authentication

    Disable password-based SSH logins:

    Copy SSH Key to Server
    ssh-copy-id deploy@your-server-ip
    Edit /etc/ssh/sshd_config
    PasswordAuthentication no
    PermitRootLogin no
    PubkeyAuthentication yes
    Restart SSH
    sudo systemctl restart sshd

    Install Fail2Ban

    Fail2Ban Setup
    sudo apt install -y fail2ban
    sudo systemctl enable fail2ban
    sudo systemctl start fail2ban

    Automatic Security Updates

    Enable Unattended Upgrades
    sudo apt install -y unattended-upgrades
    sudo dpkg-reconfigure -plow unattended-upgrades

    Nginx Security Headers

    Add these headers inside your location / block:

    Security Headers
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-Frame-Options "DENY" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    11

    Monitoring & Logging

    Extended Health Check

    Enhanced /health Endpoint
    @app.get("/health")
    async def health_check():
        # Add database ping, cache checks, etc.
        return {"status": "healthy", "version": "1.0.0"}

    Log Rotation

    Prevent logs from consuming all disk space:

    /etc/logrotate.d/fastapi-app
    /var/log/fastapi-app/*.log {
        daily
        missingok
        rotate 14
        compress
        delaycompress
        notifempty
        create 0640 deploy deploy
        postrotate
            systemctl reload fastapi-app
        endscript
    }

    Resource Monitoring

    Monitor Resources
    # Check memory usage
    free -h
    
    # Monitor CPU and process activity
    htop
    
    # Check disk usage
    df -h
    
    # Watch application-specific resources
    sudo journalctl -u fastapi-app -f

    For advanced monitoring dashboards, see our Grafana + Prometheus Guide.

    12

    Deployment Workflow

    Use this workflow for subsequent updates after your initial deployment:

    Update Deployment
    # 1. SSH into your server
    ssh deploy@your-server-ip
    
    # 2. Navigate to your app directory
    cd /opt/fastapi-app
    
    # 3. Pull latest code
    git pull origin main
    
    # 4. Activate venv and install dependencies
    source venv/bin/activate
    pip install -r requirements.txt
    
    # 5. Run database migrations (if applicable)
    alembic upgrade head
    
    # 6. Restart the application
    sudo systemctl restart fastapi-app
    
    # 7. Verify the deployment
    curl -s https://yourdomain.com/health | python3 -m json.tool
    💡 Pro Tip: Consider setting up a CI/CD pipeline with GitHub Actions to automate these steps for consistent, repeatable deployments.
    13

    Recommended VPS Specifications

    Use CaseRAMCPUStorage
    Development/staging1 GB1 vCPU20 GB SSD
    Small API (low traffic)2 GB1 vCPU40 GB SSD
    Medium API with database4 GB2 vCPU80 GB SSD
    High-traffic production8 GB+4 vCPU+160 GB+ SSD
    📈 Scaling: RamNode makes it easy to upgrade your VPS as your traffic grows. Start with a smaller plan and scale up when resource monitoring shows you need more headroom. View Cloud VPS Plans →
    14

    Troubleshooting

    502 Bad Gateway: Check if Gunicorn is running: sudo systemctl status fastapi-app
    Connection refused on port 8000: Verify the app binds to 127.0.0.1:8000 and Nginx proxies correctly.
    SSL certificate errors: Re-run: sudo certbot --nginx -d yourdomain.com
    High memory usage: Reduce Gunicorn worker count in gunicorn.conf.py.
    Slow response times: Check logs, consider adding caching, or upgrade your VPS plan.
    Permission denied errors: Verify file ownership: chown -R deploy:deploy /opt/fastapi-app

    Next Steps

    • • Add a PostgreSQL or MySQL database with connection pooling
    • • Implement Redis caching for frequently accessed endpoints
    • • Set up CI/CD pipelines with GitHub Actions or GitLab CI
    • • Add container-based deployments with Docker and Docker Compose
    • • Configure Prometheus and Grafana for advanced monitoring
    • • Implement rate limiting with slowapi or Nginx