When you start FastAPI but are familiar with hosting’s cPanel instead of VPS/Server, you can still deploy FastAPI on cPanel using Uvicorn instead of WSGI. We do not need dedicated hosting for Python. Follow the instructions below to save time and money.
Deploy FastAPI on cPanel
To quickly Deploy FastAPI on cPanel, we will start with a simple FastAPI project with 2 files as follows:
main.py
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello World"}
@app.post("/items/")
async def create_item(item: Item):
return item
requirements.txt
fastapi
pydantic
uvicorn

Step 1: Make sure you have pointed the domain name to the correct IP of the hosting and added the domain name to the hosting. Don’t forget to enable the secure HTTPS protocol for the domain name.

Step 2: Upload your project files to your domain’s folder in File Manager.

Step 3: Create a Python application. Go to Setup Python App in cPanel.

Click the CREATE APPLICATION button to create a Python application in cPanel.

Just fill in the Application root and Application URL as your domain name and click the CREATE button. You don’t need to worry about the other fields.

Step 4: Install the packages in the requirements.txt file. This step includes 2 small steps as follows:
- Type “requirements.txt” and click the Add button.
- Click the Run Pip Install button and select requirements.txt.

Step 5: Click the STOP APP button and copy the command to access the application’s virtual environment.
The reason for stopping is because FastAPI does not work well with WSGI. No matter how you configure the passenger_wsgi.py file, it still gives you an error as [UID:1003][2014879] Child process with pid: 2021889 was killed by signal: 15, core dumped: no
. We just borrowed the Setup Python App to create a valid virtual environment on cPanel.

Step 6: Run FastAPI in Terminal.
Open Terminal in cPanel.

Paste and run the command you copied in step 5; you can also install other packages with Pip in this place.
# Copy from your Python app
source /home/fysyrgiz/virtualenv/api.domain.com/3.11/bin/activate && cd /home/fysyrgiz/api.domain.com
Then run Uvicorn using this command.
uvicorn main:app --host 0.0.0.0 --port 8000
If you get the error “address already in use” then it means that there is another application running with this local IP. You just need to increase the port, for example, 8001.

If you want to run in the background, you need to use the nohup command.
nohup uvicorn main:app --host 0.0.0.0 --port 8000 &
Once Terminal is error-free, access your FastAPI in the domain:port
or domain:port/docs
format. It’s great that your FastAPI is finally working, but it still has two issues to deal with.
- No HTTPS (SSL) causes the browser to display “Not Secure”.
- The Port part at the end makes the URL look unprofessional and unfinished.

Step 7: Enable HTTPS and set up a proxy for your domain pointing to the local FastAPI address. Add this code to the .htaccess file in your domain directory. Remember to replace fastapi.lucidgen.com:8001
with your local FastAPI address.
RewriteEngine On
# Force HTTPS
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
# Reverse Proxy
RewriteRule ^(.*)$ http://fastapi.lucidgen.com:8001/$1 [P,L]

If you don’t see the .htaccess file, it may be hidden, click the Settings button and enable Show Hidden Files (dotfiles) to display hidden files in File Manager. If there is no .htaccess file at all, create it.
Step 8: Go to your official FastAPI domain. HTTPS is now enabled, and Port is no longer in the URL.

Create bash file for easy control
To efficiently control FastAPI on the server, I will create a run.sh file with the following arguments:
-a
: Activate and move to the domain directory.-s
: Start FastAPI withnohup
.-r
: Restart FastAPI withnohup
.-f
: Start FastAPI in the foreground.-k
: Kill the FastAPI process.
Replace your VENV_PATH
and APP_DIR
in this file.
#!/bin/bash
# ========== CONFIG ==========
VENV_PATH="/home/username/virtualenv/api.domain.com/3.11/bin/activate"
APP_DIR="/home/username/api.domain.com"
UVICORN_CMD="uvicorn main:app --host 0.0.0.0 --port 8000"
# ========== FUNCTIONS ==========
activate_env() {
echo "[Activating virtualenv and changing dir]"
source "$VENV_PATH" && cd "$APP_DIR"
}
kill_uvicorn() {
echo "[Killing uvicorn process]"
pkill -f "$UVICORN_CMD"
}
nohup_start() {
echo "[Starting uvicorn with nohup in background]"
activate_env
nohup $UVICORN_CMD &
echo "[Started with nohup]"
}
restart_uvicorn() {
echo "[Restarting uvicorn with nohup]"
activate_env
kill_uvicorn
nohup $UVICORN_CMD &
echo "[Restarted]"
}
run_foreground() {
echo "[Running uvicorn in foreground]"
activate_env
$UVICORN_CMD
}
# ========== PARSE ARGS ==========
if [ $# -eq 0 ]; then
echo "Please provide an argument."
echo "Valid arguments: $0 [-a] [-s] [-r] [-f] [-k]"
echo " -a Activate virtualenv and cd"
echo " -s Start uvicorn with nohup"
echo " -r Restart uvicorn with nohup"
echo " -f Run uvicorn in foreground"
echo " -k Kill uvicorn"
exit 1
fi
while getopts "asrfk" opt; do
case $opt in
a)
activate_env
;;
k)
kill_uvicorn
;;
s)
nohup_start
;;
r)
restart_uvicorn
;;
f)
run_foreground
;;
*)
echo "Argument is invalid"
echo "Valid arguments: $0 [-a] [-s] [-r] [-f] [-k]"
exit 1
;;
esac
done
Example of usage:
Just activate the environment and move to the domain.
source ~/domain.com/run.sh -a
Restart FastAPI.
bash ~/domain.com/run.sh -r
Conclusion
I just accidentally thought of how to deploy FastAPI on cPanel as above, and luckily, it works; I am not really an expert on hosting, VPS/Server. If you find this article useful, please share it on forums to help others.
For now, for small and medium-sized FastAPI projects, I find that they work very well on cPanel this way. I don’t have any FastAPI projects with large scale and access to test its stability on cPanel. If you find any problems with this way, please share with me and everyone through the comments below.