Deployment Guide (DigitalOcean, Ubuntu)
This guide is aligned with your current production model:
- Ubuntu droplet
- Nginx reverse proxy
- Gunicorn for Django
- PostgreSQL
- Redis + Celery
- static/media from Django paths
1) Server prerequisites
- Python 3.10+
- PostgreSQL
- Redis
- Nginx
- systemd
2) Clone and environment setup
cd /home/appleveil
git clone <repo-url> ferma
cd ferma
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
Create env file (or export vars):
cp .env.example roads/.env
# Edit values in roads/.env
3) Database and migrations
python manage.py migrate --settings=roads.settings.production
4) Static files
python manage.py collectstatic --noinput --settings=roads.settings.production
If CSS appears stale after deploy, restart Gunicorn.
5) Gunicorn systemd service (example)
/etc/systemd/system/gunicorn.service
[Unit]
Description=gunicorn daemon for cpms_ferma
After=network.target
[Service]
User=appleveil
Group=www-data
WorkingDirectory=/home/appleveil/ferma
Environment="DJANGO_SETTINGS_MODULE=roads.settings.production"
ExecStart=/home/appleveil/ferma/venv/bin/gunicorn roads.wsgi:application --bind 127.0.0.1:8000 --workers 3
Restart=always
[Install]
WantedBy=multi-user.target
Commands:
sudo systemctl daemon-reload
sudo systemctl enable gunicorn
sudo systemctl restart gunicorn
sudo systemctl status gunicorn
6) Nginx site config (example)
/etc/nginx/sites-available/cpmsferma
server {
listen 80;
server_name cpmsferma.com www.cpmsferma.com;
location /static/ {
alias /home/appleveil/ferma/staticfiles/;
}
location /media/ {
alias /home/appleveil/ferma/media/;
}
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Enable/reload:
sudo ln -s /etc/nginx/sites-available/cpmsferma /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
7) Celery worker (systemd example)
/etc/systemd/system/celery.service
[Unit]
Description=Celery Worker for CPMS FERMA
After=network.target redis.service
[Service]
Type=simple
User=appleveil
Group=www-data
WorkingDirectory=/home/appleveil/ferma
Environment="DJANGO_SETTINGS_MODULE=roads.settings.production"
ExecStart=/home/appleveil/ferma/venv/bin/celery -A roads worker -l info
Restart=always
[Install]
WantedBy=multi-user.target
8) Deployment checklist
- Pull code.
- Activate venv.
- Install/upgrade deps.
- Run migrations.
- Run
collectstatic. - Restart gunicorn.
- Reload nginx.
- Restart celery if changed.
- Smoke test key pages and static assets.
9) Post-deploy verification
curl -I https://cpmsferma.com/static/website/css/style.css
curl -I https://cpmsferma.com/
Expected CSS check:
- HTTP 200
- non-zero
Content-Length
10) Common pitfall encountered
- Symptom: CSS URL returns 200 but with
Content-Length: 0. - Cause: stale process/static state after deployment.
- Fix: rerun collectstatic and restart gunicorn.