Deploy Django on Ubuntu with Caddy && Gunicorn
Pre-setup
- Make the necessary preparation so that we can open the site on a browser outside the host machine with
http://host_ip_address:8000when we runpython3 manage.py runserver 0.0.0.0:8000on the host machine terminal - Install Gunicorn in the virtual environment
pip3 install gunicorn
- Create a gunicorn configuration in your django project folder(e.g. ~/mdblog/gunicorn.conf.py)
bind = "localhost:8000"
workers = 4
keepalive = 5
wsgi_app = "blog.wsgi" # Replace 'blog' with your main app (the name of the directory that contains wsgi.py)
- Create a systemd unit
sudo nano /etc/systemd/system/gunicorn.service
[Install]
WantedBy=multi-user.target
[Unit]
Description=Gunicorn service
After=network.target
[Service]
WorkingDirectory=/home/ubuntu/mdblog # /path/to/django_project/
ExecStart=/home/ubuntu/mdblog/venv/bin/gunicorn # /path/to/django_project_venv/bin/gunicorn
- Test Gunicorn
sudo systemctl enable gunicorn
sudo systemctl start gunicorn
sudo systemctl status gunicorn
Install Caddy && Config CaddyFile
- Cady Installation
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
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
- Caddy Configuration
sudo nano /etc/caddy/Caddyfile
mdblog.peng.works {
handle_path /static/* {
root * /home/ec2-user/mdblog/static/
file_server
}
handle_path /media/* {
root * /home/ec2-user/mdblog/media/
file_server
}
reverse_proxy localhost:8000
}
node-app.peng.works {
reverse_proxy localhost:5000
}
# Refer to the Caddy docs for more information:
# https://caddyserver.com/docs/caddyfile
- Restart Caddy
sudo systemctl restart caddy
sudo systemctl status caddy
- Note: Make sure the port 443 is open and 'mdblog.peng.works' is in the ALLOWED_HOSTS in Django settings.py if there is a problem opening the site. Don't forget to set debug to False and close port 8000 after it works.
Bonus: Nginx Configuration
sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/mdblog.confsudo cp -r ~/mdblog/static /var/www/staticsudo nano /etc/nginx/sites-available/mdblog.conf
server {
server_name 54.168.187.222 peng.works www.peng.works;
location /static/ {
root /var/www;
}
location / {
include proxy_params;
proxy_pass http://localhost:8000;
}
}
sudo ln -s /etc/nginx/sites-available/mdblog.conf /etc/nginx/sites-enabled/mdblog.confsudo nginx -tsudo systemctl restart nginx- You should be able to open the site on a browser outside the host machine with
http://54.168.187.222. If you have pointed your.domain.com to this IP address and it has taken effect, you should also be able to openhttp://peng.worksorhttp://www.peng.works. - Assuming that we have uploaded ZeroSSL files(certificate.crt, ca_bundle.crt and private.key) onto the server now.
mv certificate.crt certificate_old.crt && cat certificate_old.crt ca_bundle.crt >> certificate.crt# Merge .crt Files for Nginxsudo mv certificate.crt /etc/ssl/certs/ && sudo mv private.key /etc/ssl/private/sudo nano /etc/nginx/sites-available/mdblog.conf
server {
server_name peng.works www.peng.works;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
ssl_certificate /etc/ssl/certs/certificate.crt;
ssl_certificate_key /etc/ssl/private/private.key;
server_name peng.works www.peng.works;
location /static/ {
root /var/www;
}
location / {
include proxy_params;
proxy_pass http://localhost:8000;
}
}
sudo systemctl restart nginx# Restart the Nginx service and it should work now.