Production Deployment Guide
This guide walks through deploying DripEmails.org to a production server with best practices for security, performance, and reliability.
💡 Pro Tip: Test your deployment on a staging environment before going to production.
Prerequisites
- Linux server (Ubuntu 20.04+ recommended)
- Domain name pointed to your server
- SSH access to server
- Root or sudo privileges
- Basic command line knowledge
System Requirements
Minimum:
- 2 CPU cores
- 4GB RAM
- 20GB storage
- Ubuntu 20.04 or later
Recommended:
- 4+ CPU cores
- 8GB+ RAM
- 50GB+ SSD storage
- Ubuntu 22.04 LTS
Step 1: Server Setup
Update system and install dependencies:
sudo apt update && sudo apt upgrade -y
sudo apt install python3-pip python3-venv nginx postgresql redis-server -y
sudo apt install supervisor git -y
sudo apt install python3-pip python3-venv nginx postgresql redis-server -y
sudo apt install supervisor git -y
Step 2: Create Application User
sudo adduser --disabled-password --gecos '' dripemails
sudo usermod -aG www-data dripemails
sudo usermod -aG www-data dripemails
Step 3: Clone Repository
sudo su - dripemails
git clone https://github.com/yourusername/dripemails.git
cd dripemails/web
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
git clone https://github.com/yourusername/dripemails.git
cd dripemails/web
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
Step 4: Configure Environment
Create .env file:
DEBUG=False
SECRET_KEY=your-secret-key-here
ALLOWED_HOSTS=yourdomain.com,www.yourdomain.com
DATABASE_URL=postgresql://user:password@localhost/dripemails
REDIS_URL=redis://localhost:6379/0
EMAIL_HOST=smtp.sendgrid.net
EMAIL_PORT=587
EMAIL_USE_TLS=True
EMAIL_HOST_USER=apikey
EMAIL_HOST_PASSWORD=your-api-key
SECRET_KEY=your-secret-key-here
ALLOWED_HOSTS=yourdomain.com,www.yourdomain.com
DATABASE_URL=postgresql://user:password@localhost/dripemails
REDIS_URL=redis://localhost:6379/0
EMAIL_HOST=smtp.sendgrid.net
EMAIL_PORT=587
EMAIL_USE_TLS=True
EMAIL_HOST_USER=apikey
EMAIL_HOST_PASSWORD=your-api-key
⚠️ Important: Generate a strong SECRET_KEY: `python -c 'from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())'`
Step 5: Database Setup
sudo -u postgres psql
CREATE DATABASE dripemails;
CREATE USER dripuser WITH PASSWORD 'yourpassword';
ALTER ROLE dripuser SET client_encoding TO 'utf8';
ALTER ROLE dripuser SET default_transaction_isolation TO 'read committed';
ALTER ROLE dripuser SET timezone TO 'UTC';
GRANT ALL PRIVILEGES ON DATABASE dripemails TO dripuser;
\q
CREATE DATABASE dripemails;
CREATE USER dripuser WITH PASSWORD 'yourpassword';
ALTER ROLE dripuser SET client_encoding TO 'utf8';
ALTER ROLE dripuser SET default_transaction_isolation TO 'read committed';
ALTER ROLE dripuser SET timezone TO 'UTC';
GRANT ALL PRIVILEGES ON DATABASE dripemails TO dripuser;
\q
Step 6: Run Migrations
python manage.py migrate
python manage.py collectstatic --noinput
python manage.py createsuperuser
python manage.py collectstatic --noinput
python manage.py createsuperuser
Step 7: Gunicorn Setup
Create /etc/supervisor/conf.d/dripemails.conf:
[program:dripemails]
command=/home/dripemails/dripemails/web/venv/bin/gunicorn dripemails.wsgi:application --bind 127.0.0.1:8000
directory=/home/dripemails/dripemails/web
user=dripemails
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/var/log/dripemails/gunicorn.log
command=/home/dripemails/dripemails/web/venv/bin/gunicorn dripemails.wsgi:application --bind 127.0.0.1:8000
directory=/home/dripemails/dripemails/web
user=dripemails
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/var/log/dripemails/gunicorn.log
Step 8: Celery Setup
Create /etc/supervisor/conf.d/celery.conf:
[program:celery]
command=/home/dripemails/dripemails/web/venv/bin/celery -A dripemails worker -l info
directory=/home/dripemails/dripemails/web
user=dripemails
autostart=true
autorestart=true
command=/home/dripemails/dripemails/web/venv/bin/celery -A dripemails worker -l info
directory=/home/dripemails/dripemails/web
user=dripemails
autostart=true
autorestart=true
Step 9: Nginx Configuration
Create /etc/nginx/sites-available/dripemails:
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
location /static/ {
alias /home/dripemails/dripemails/web/staticfiles/;
}
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
listen 80;
server_name yourdomain.com www.yourdomain.com;
location /static/ {
alias /home/dripemails/dripemails/web/staticfiles/;
}
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
Step 10: SSL Certificate
Install Let's Encrypt SSL:
sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
sudo certbot renew --dry-run
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
sudo certbot renew --dry-run
Step 11: Start Services
sudo mkdir -p /var/log/dripemails
sudo chown dripemails:dripemails /var/log/dripemails
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start all
sudo nginx -t
sudo systemctl restart nginx
sudo chown dripemails:dripemails /var/log/dripemails
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start all
sudo nginx -t
sudo systemctl restart nginx
Post-Deployment Checklist
- ✅ Website loads at https://yourdomain.com
- ✅ Admin panel accessible at /admin
- ✅ Static files loading correctly
- ✅ Can send test email
- ✅ Celery tasks running
- ✅ SSL certificate valid
- ✅ Database backups configured
- ✅ Monitoring set up
Monitoring and Maintenance
- Logs: /var/log/dripemails/
- Supervisor: sudo supervisorctl status
- Nginx: sudo nginx -t && sudo systemctl status nginx
- Database: Regular backups with pg_dump
- Updates: git pull && pip install -r requirements.txt
Security Best Practices
- Enable firewall (ufw) and allow only necessary ports
- Keep system and packages updated
- Use strong passwords for all services
- Disable DEBUG in production
- Regularly backup database and media files
- Monitor logs for suspicious activity
- Set up fail2ban for brute force protection