This is a simple step by step process to setup an Apache server as a reverse proxy for a unicorn server that serves python code. Let’s assume that you want to serve at sub.website.com and your uvicorn is supposed to run in the default port which is 8000. Here we go:
- Define your vHost. You have to let Apache know about your reverse proxy needs. In essence you are going to tell it what is the virtual host and where it can find its contents. For that, you may modify your /etc/apache2/conf.d/includes/pre_main_global.conf file with the definition of the virtual host as below:
ServerAdmin username@website.com
ServerName sub.website.com
ErrorLog /location/error.log
CustomLog /location/access.log combined
ProxyTimeout 60
ProxyRequests On
ProxyPass / http://127.0.0.1:8000
ProxyPassReverse / http://127.0.0.1:8000
Or you can create a new file specific for your user and sub domain, then define the vhost there:
/etc/apache2/conf.d/userdata/ssl/2_4/{username}/{subdomain.domain.com}/proxy.conf
In that newly created file, define the vhost:
# Example uvicorn on port 8000
ProxyPass / http://127.0.0.1:8000/
ProxyPassReverse / http://127.0.0.1:8000/
Now create the service under systemd, giving it a name that makes sense to you:
/etc/systemd/system/myuvicorn.service
The contents of the file are as below for a uvicorn server:
[Unit]
Description=Uvicorn ASGI server
After=network.target
[Service]
User={youruser}
Group={yourgroup}
WorkingDirectory=/home/{username}/sub.website.com
ExecStart=/usr/bin/env uvicorn app:app --host 127.0.0.1 --port 8000 --workers 2
Restart=always
RestartSec=25
KillMode=mixed
TimeoutStopSec=5
[Install]
WantedBy=multi-user.target
Now it is time to load the service:
sudo systemctl daemon-reload # Reload systemd, scanning for new or changed units
sudo systemctl enable myuvicorn.service # Enable the uvicorn service to start at boot
sudo systemctl start myuvicorn.service # Start the service now
Finally, let’s stop it and restart it and also view logs in case we want to see what is happening:
systemctl stop myuvicorn.service; # stops the service
systemctl enable --now myuvicorn.service; # enables the service
systemctl status myuvicorn.service -l # show me the status
journalctl -u myuvicorn.service -f # Show me logs as they happen
Now, why did we do all this? In the modern web you may have a python based API (like FastAPI) that you want to run in your LAMP system. But you can’t just direct traffic to your API directly, that’s why you need a reverse proxy.
Hope this is helpful.