PYTHON 1 month ago

How to Deploy a Django Website on DigitalOcean, lightsail

gabriel / Author
How to Deploy a Django Website on DigitalOcean, lightsail

Hi there,

In this guide i have provide a step-by-step process for deploying a Django website on a DigitalOcean droplet or AWS lightsail using Ubuntu, MySQL, Gunicorn, and Nginx, with SSL configuration via Certbot.

the process of deploying a website on ubuntu machine is basically the same it doesnt matter if its digital ocean or AWS. in the guide i will be using digital ocean.

Prerequisites

Git - Access to Git Bash

Django code on GitHub or any Git version control system of your choice, e.g., GitLab, Bitbucket, etc.

A DigitalOcean account.

A domain name (optional, for custom domain setup).

Basic familiarity with Linux commands and SSH.( don't worry about this i will be explaning all the need linux commands)

step 1: Set Up a DigitalOcean Droplet

Log in to your DigitalOcean account.

Create a new droplet:

Choose an Ubuntu image (e.g., Ubuntu 22.04 LTS).

Select a plan and region.

Set up SSH key-based authentication (recommended) or use a root password.

Note the droplet's public IP address (e.g., 157.245.130.252).

Step 2: Access the Droplet using Git Bash terminal

open the Git Bash terminal and SSH into the droplet

ssh root@your-droplet-ip

Update the system packages:

sudo apt update
sudo apt upgrade

Step 3: Basic Linux Commands

Familiarize yourself with these common Linux commands for navigation and setup:

cd // -Move to the root directory.

cd /opt - Move to the /opt directory (common for project files).

mkdir directory_name - Create a new directory.

Step 4: Clone Your Repository

Create a directory for your project:

cd /opt
mkdir sq_analysis
cd sqanalysis

Clone your GitHub repository:

git clone https://github.com//.git .

Step 5: Install and Configure MySQL

Install MySQL:

sudo apt install mysql-server

Start the MySQL service:

systemctl start mysql

Secure the MySQL installation:

sudo mysql_secure_installation

Follow the prompts:

Set up the VALIDATE PASSWORD component (recommended: choose 2 for STRONG).

Set a root password.

Answer remaining questions (remove anonymous users, disallow remote root login, etc.).

Log in to MySQL to configure the root user:

mysql
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '';
exit

Verify MySQL is running:

systemctl status mysql.service

output

● mysql.service - MySQL Community Server
Loaded: loaded (/usr/lib/systemd/system/mysql.service; enabled; preset: enabled)
Active: active (running) since Sat 2025-08-02 21:22:41 UTC; 28min ago
Invocation: 8537cd221b4a47b7a23a05dd6bdfd463
Process: 2802 ExecStartPre=/usr/share/mysql/mysql-systemd-start pre (code=exited, status=0/SUCCESS)
Main PID: 2811 (mysqld)
Status: "Server is operational"
Tasks: 38 (limit: 1110)
Memory: 353.5M (peak: 378M)
CPU: 14.507s
CGroup: /system.slice/mysql.service
└─2811 /usr/sbin/mysqld

Create a database for your Django project:

sudo mysql -u root -p

CREATE DATABASE database_name;


exit

Step 6: Set Up a Python Virtual Environment

Install required packages:

sudo apt install python3-venv python3-dev nginx curl

Create and activate a virtual environment:

python3 -m venv my_env
source my_env/bin/activate

Install Gunicorn:

pip install gunicorn

Install mysqlclient dependencies:

sudo apt-get install python3-dev default-libmysqlclient-dev build-essential pkg-config
pip install mysqlclient

Install project dependencies from requirements.txt:

pip install -r requirements.txt

Step 7: Configure Django Settings

Create a .env file for sensitive settings:

touch .env
nano .env

Add environment variables (e.g., database credentials):

DATABASE_NAME=
DATABASE_USER=root
DATABASE_PASSWORD=
DATABASE_HOST=localhost

Save and exit (Ctrl+O, Enter, Ctrl+X).

Update settings.py:

ALLOWED_HOSTS = ["localhost", "0.0.0.0", "", "sqanalysis.com", "www.sqanalysis.com"]

Run migrations and collect static files:


python manage.py migrate
python manage.py createsuperuser
python manage.py collectstatic

Step 8: Test the Django Application

Run the Django development server:


python manage.py runserver 0.0.0.0:8000

Open http://:8000 in a browser to verify the site loads.

Test Gunicorn:

gunicorn --bind 0.0.0.0:8000 .wsgi

Verify the site loads again at http://:8000

Deactivate the virtual environment:

deactivate

Step 9: Configure Gunicorn as a Service

Create a Gunicorn socket file:

sudo nano /etc/systemd/system/gunicorn.socket

[Unit]
Description=gunicorn socket

[Socket]
ListenStream=/run/gunicorn.sock

[Install]
WantedBy=sockets.target

Save and exit (Ctrl+O, Enter, Ctrl+X).

sudo nano /etc/systemd/system/gunicorn.service

[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target

[Service]
Type=notify
User=root
Group=www-data
Environment="PATH=/opt/sqanalysis/my_env/bin"
WorkingDirectory=/opt/sqanalysis
ExecStart=/opt/sqanalysis/my_env/bin/gunicorn .wsgi:application
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID
KillMode=mixed
TimeoutStopSec=5
PrivateTmp=true

[Install]
WantedBy=multi-user.target

Replace with your Django project's name. Save and exit.

Start and enable the Gunicorn socket:

sudo systemctl start gunicorn.socket
sudo systemctl enable gunicorn.socket

Verify the socket is running:

sudo systemctl status gunicorn.socket

output

● gunicorn.service - gunicorn daemon
Loaded: loaded (/etc/systemd/system/gunicorn.service; disabled; preset: enabled)
Active: active (running) since Sun 2025-08-03 12:59:17 UTC; 44s ago
Invocation: 41c154839f894c95b82aa0137baf1bbc
TriggeredBy: ● gunicorn.socket
Main PID: 62969 (gunicorn)
Status: "Gunicorn arbiter booted"
Tasks: 2 (limit: 1110)
Memory: 61M (peak: 61.2M)
CPU: 1.514s
CGroup: /system.slice/gunicorn.service
├─62969 /opt/sqanalysis/my_sq_env/bin/python3 /opt/sqanalysis/my_sq_env/bin/gunicorn config.wsgi:application
└─62970 /opt/sqanalysis/my_sq_env/bin/python3 /opt/sqanalysis/my_sq_env/bin/gunicorn config.wsgi:application

Aug 03 12:59:17 sq-analysis10 systemd[1]: Starting gunicorn.service - gunicorn daemon...
Aug 03 12:59:17 sq-analysis10 gunicorn[62969]: [2025-08-03 12:59:17 +0000] [62969] [INFO] Starting gunicorn 23.0.0
Aug 03 12:59:17 sq-analysis10 gunicorn[62969]: [2025-08-03 12:59:17 +0000] [62969] [INFO] Listening at: unix:/run/gunicorn.sock (62969)
Aug 03 12:59:17 sq-analysis10 gunicorn[62969]: [2025-08-03 12:59:17 +0000] [62969] [INFO] Using worker: sync
Aug 03 12:59:17 sq-analysis10 systemd[1]: Started gunicorn.service - gunicorn daemon.
Aug 03 12:59:17 sq-analysis10 gunicorn[62970]: [2025-08-03 12:59:17 +0000] [62970] [INFO] Booting worker with pid: 62970

file /run/gunicorn.sock

Test socket activation:

curl --unix-socket /run/gunicorn.sock localhost

Verify the Gunicorn service:

sudo systemctl status gunicorn

If errors occur, check logs:

sudo journalctl -u gunicorn.socket
sudo journalctl -u gunicorn

Reload and restart if changes are made:

sudo systemctl daemon-reload
sudo systemctl restart gunicorn

Step 10: Configure Nginx

Create an Nginx server block:

sudo nano /etc/nginx/sites-available/sqanalysis

server {
listen 80;
server_name sqanalysis.com www.sqanalysis.com;

location /static/ {
alias /opt/sqanalysis/staticfiles/;
}

location /media/ {
alias /opt/sqanalysis/sqanalysisapps/media/;
}

location / {
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
}
}

Save and exit.

Enable the server block:

sudo ln -s /etc/nginx/sites-available/sqanalysis /etc/nginx/sites-enabled

Test and restart Nginx:

sudo nginx -t
sudo systemctl restart nginx

Step 11: Configure Domain and DNS

Log in to your domain registrar (e.g., Porkbun) and update the nameservers to DigitalOcean’s:

ns1.digitalocean.com

ns2.digitalocean.com

ns3.digitalocean.com

In the DigitalOcean control panel, add your domain:

Go to Networking > Domains.

Add sqanalysis.com and select your droplet.

Create an A record pointing to your droplet’s IP.

Update ALLOWED_HOSTS in settings.py:

ALLOWED_HOSTS = ["sqanalysis.com", "www.sqanalysis.com"]

Step 12: Enable SSL with Certbot

Install Certbot:

sudo apt install certbot python3-certbot-nginx

Run Certbot to obtain and install an SSL certificate:

sudo certbot --nginx -d sqanalysis.com -d www.sqanalysis.com

Provide an email address.

Agree to the Terms of Service.

Choose whether to share your email with EFF.

Verify the certificate installation:

Check https://sqanalysis.com in a browser.

Verify auto-renewal:

sudo systemctl status certbot.timer
sudo certbot renew --dry-run

Step 13: Final Testing

Visit https://sqanalysis.com and https://www.sqanalysis.com to ensure the site is live.

If changes are made, restart services:

sudo systemctl restart gunicorn
sudo systemctl daemon-reload
sudo systemctl restart gunicorn.socket gunicorn.service
sudo nginx -t && sudo systemctl restart nginx

Troubleshooting

Gunicorn Issues: Check logs with sudo journalctl -u gunicorn or sudo journalctl -u gunicorn.socket.

Nginx Issues: Verify configuration with sudo nginx -t and check logs with sudo journalctl -u nginx.

Database Issues: Ensure MySQL is running (systemctl status mysql) and credentials are correct in .env.

Conclusion

Your Django website is now deployed on DigitalOcean with Gunicorn, Nginx, MySQL, and SSL. Regularly monitor logs and update your application as needed.

All comments (2)

1 month ago

very good

4 weeks, 1 day ago

Thank you for sharing