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://
Test Gunicorn:
gunicorn --bind 0.0.0.0:8000 .wsgi
Verify the site loads again at http://
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
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)
very good
Thank you for sharing