https://github.com/murat-polat/fastapi-deploymet-example
FastAPI production deployment with secure SSL/HTTPS, and Caddy server
https://github.com/murat-polat/fastapi-deploymet-example
caddy deployment fastapi https-proxy python rest-api supervisor
Last synced: 8 months ago
JSON representation
FastAPI production deployment with secure SSL/HTTPS, and Caddy server
- Host: GitHub
- URL: https://github.com/murat-polat/fastapi-deploymet-example
- Owner: murat-polat
- Created: 2023-04-23T12:02:51.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2025-03-22T20:54:28.000Z (9 months ago)
- Last Synced: 2025-04-30T06:07:24.664Z (8 months ago)
- Topics: caddy, deployment, fastapi, https-proxy, python, rest-api, supervisor
- Language: Python
- Homepage:
- Size: 246 KB
- Stars: 5
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
### This is a simple example for deploying a FastAPI application, to production environment. And probably the easiest way to run an application with secure SSL/HTTPS, and with Caddy server magic. So, you can focus just your application and code, not deployment process :)
### What we need ?
- Linux machine/VM
- Domainname
- FastAPI application
- Caddy server and reverse proxy configuration for HTTPS/SSL
### Linux VM :
You can order a Linux VM from the Digital Ocean, Contabo, Vultr, Linode etc. For this tutorial, we choose an Debian instance on Contabo.
After first login, run:
`sudo apt-get update`
If sudo not working on Debian:
`apt install sudo`
It's optional add a new user, or continue with "root" user. But we choose and recommend a new user, and give it admin privileges.
`sudo adduser `
`sudo usermod -aG sudo `
Change root user to new user
`su `
`python3 -m pip install fastapi[all] gunicorn uvicorn`
If "pip" not working, so install python3 pip
`sudo apt install python3-pip`
### Domain configuration
We need a domain name for publishing our application in World Wide Web. We choose a domainname from the https://www.namecheap.com. And we must tell the domain provider which server/IP provider will be used for publishing. Our FastAPI application will be served on Contabo. From domain list => management => Nameservers => Custom DNS add three nameservers (ns1.contabo.net, ns2.contabo.net, ns3.contabo.net) and save.

From Contabo "DNS Zone Management", add your domainname to "Domain", and "Target IP address" select your VM instance/IP from dropdown menu => then click "create zone".

### FastAPI application
As we mentioned above that, this is just a demo application. For demonstration perposes
`nano main.py`
```
from fastapi import FastAPI
app = FastAPI()
@app.get("/items/{item_id}")
async def read_item(item_id: int):
return {"item_id": item_id}
```
For testing just run:
`uvicorn main:app --reload`
If it's running without error, so vi need make a "service" or "supervisor" for our FastAPI application. The reason for that, to do application more robust and relable for pruduction. After that you can start, stop and see status just from the command line.
To do that run:
`sudo nano /etc/systemd/system/fastapi.service`
and copy-paste the code block below
```
[Unit]
Description=fastapi service
After=network.target
[Service]
User=
Group=www-data
WorkingDirectory=/home//fastapi
ExecStart=gunicorn main:app --workers 4 --worker-class uvicorn.workers.UvicornWorker --bind 0.0.0.0:8000
Restart=always
[Install]
WantedBy=multi-user.target
```
Hit "Ctrl+X" then "Y" for save the "fastapi.service" (For Nano editor)
Now our FastAPI application more robust and easy to control. For start and enable the service, run:
` sudo systemctl start fastapi`
To enable the service:
` sudo systemctl enable fastapi`
To stop the service:
` sudo systemctl stop fastapi`
To see status of the service:
` sudo systemctl status fastapi`
```
● fastapi.service - fastapi service
Loaded: loaded (/etc/systemd/system/fastapi.service; enabled; vendor preset: enabled)
Active: active (running) since Sat 2023-04-22 21:52:48 CEST; 15h ago
Main PID: 333920 (gunicorn)
Tasks: 5 (limit: 9507)
Memory: 82.6M
CPU: 8min 26.889s
CGroup: /system.slice/fastapi.service
├─333920 /usr/bin/python3 /usr/bin/gunicorn main:app --workers 4 --worker-class uvicorn.workers.UvicornWorker --bind 0.0.0.0:8000
├─333921 /usr/bin/python3 /usr/bin/gunicorn main:app --workers 4 --worker-class uvicorn.workers.UvicornWorker --bind 0.0.0.0:8000
├─333922 /usr/bin/python3 /usr/bin/gunicorn main:app --workers 4 --worker-class uvicorn.workers.UvicornWorker --bind 0.0.0.0:8000
├─333923 /usr/bin/python3 /usr/bin/gunicorn main:app --workers 4 --worker-class uvicorn.workers.UvicornWorker --bind 0.0.0.0:8000
└─333924 /usr/bin/python3 /usr/bin/gunicorn main:app --workers 4 --worker-class uvicorn.workers.UvicornWorker --bind 0.0.0.0:8000
Apr 22 21:52:48 vmi1180878.contaboserver.net gunicorn[333924]: [2023-04-22 21:52:48 +0200] [333924] [INFO] Application startup complete.
Apr 22 22:03:18 vmi1180878.contaboserver.net gunicorn[333923]: [2023-04-22 22:03:18 +0200] [333923] [WARNING] Invalid HTTP request received.
```
Now everything is working properly with HTTP on port 8000. But we need SSL/HTTPS,and configure Caddy server for reverse proxy.
### Caddy Server configuration
#### Installation:
https://caddyserver.com/docs/install#debian-ubuntu-raspbian
`sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https`
`curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg`
`curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list`
`sudo apt update`
`sudo apt install caddy`
#### Configuration reverse proxy with Caddyfile
`sudo nano /etc/caddy/Caddyfile`
```
yourdomainname.net {
reverse_proxy localhost:8000
}
```
`sudo systemctl reload caddy`
Done !
Happy coding with awasome FastAPI :)
