Overview
This guide covers deploying OSINT Hub to a production environment with a robust stack:
- Gunicorn as the WSGI application server
- nginx as the reverse proxy
- PostgreSQL as the production database
- Redis for Celery task queue
- WhiteNoise for static file serving
- Systemd for process management
Never deploy with DEBUG=True in production. This exposes sensitive information and creates security vulnerabilities.
Prerequisites
Before starting, ensure you have:
- Ubuntu 20.04+ or similar Linux distribution
- Python 3.12+
- PostgreSQL 12+
- Redis server
- Domain name pointed to your server
- ExifTool installed (
sudo apt install libimage-exiftool-perl)
System Preparation
Update system packages
sudo apt update && sudo apt upgrade -y
Install required system packages
sudo apt install -y python3.12 python3.12-venv python3-pip \
postgresql postgresql-contrib redis-server nginx \
libimage-exiftool-perl git
Configure PostgreSQL
Create a database and user for OSINT Hub:In the PostgreSQL prompt:CREATE DATABASE osint_hub;
CREATE USER osint_user WITH PASSWORD 'your_secure_password';
ALTER ROLE osint_user SET client_encoding TO 'utf8';
ALTER ROLE osint_user SET default_transaction_isolation TO 'read committed';
ALTER ROLE osint_user SET timezone TO 'UTC';
GRANT ALL PRIVILEGES ON DATABASE osint_hub TO osint_user;
\q
Start and enable Redis
sudo systemctl start redis
sudo systemctl enable redis
Application Setup
Create application user
sudo useradd -m -s /bin/bash osinthub
sudo su - osinthub
Clone the repository
git clone https://github.com/Nakajito/osint_hub.git
cd osint_hub
Create and activate virtual environment
python3.12 -m venv venv
source venv/bin/activate
Install Python dependencies
pip install --upgrade pip
pip install -r requirements.txt
Configure environment variables
Create a .env file with production settings:Add the following configuration (adjust values accordingly):SECRET_KEY=your-very-long-random-secret-key-here
DEBUG=False
ALLOWED_HOSTS=yourdomain.com,www.yourdomain.com
CSRF_TRUSTED_ORIGINS=https://yourdomain.com,https://www.yourdomain.com
DATABASE_URL=postgres://osint_user:your_secure_password@localhost:5432/osint_hub
Generate a secure SECRET_KEY:python -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())"
Collect static files
python manage.py collectstatic --no-input
Static files are served by WhiteNoise, which is already configured in settings.py.Create superuser (optional)
python manage.py createsuperuser
Gunicorn Configuration
Create Gunicorn systemd service
Exit the osinthub user and return to your sudo user:Create the service file:sudo nano /etc/systemd/system/osinthub.service
Add service configuration
[Unit]
Description=OSINT Hub Gunicorn Daemon
After=network.target
[Service]
User=osinthub
Group=osinthub
WorkingDirectory=/home/osinthub/osint_hub
Environment="PATH=/home/osinthub/osint_hub/venv/bin"
EnvironmentFile=/home/osinthub/osint_hub/.env
ExecStart=/home/osinthub/osint_hub/venv/bin/gunicorn \
--workers 3 \
--bind unix:/home/osinthub/osint_hub/osinthub.sock \
--timeout 120 \
--access-logfile /var/log/osinthub/access.log \
--error-logfile /var/log/osinthub/error.log \
osint_hub.wsgi:application
[Install]
WantedBy=multi-user.target
Create log directory
sudo mkdir -p /var/log/osinthub
sudo chown osinthub:osinthub /var/log/osinthub
Start and enable Gunicorn
sudo systemctl start osinthub
sudo systemctl enable osinthub
sudo systemctl status osinthub
Celery Worker Configuration
Create Celery worker service
sudo nano /etc/systemd/system/osinthub-celery.service
Add the following:[Unit]
Description=OSINT Hub Celery Worker
After=network.target redis.service
[Service]
Type=forking
User=osinthub
Group=osinthub
WorkingDirectory=/home/osinthub/osint_hub
Environment="PATH=/home/osinthub/osint_hub/venv/bin"
EnvironmentFile=/home/osinthub/osint_hub/.env
ExecStart=/home/osinthub/osint_hub/venv/bin/celery -A osint_hub worker \
--loglevel=info \
--logfile=/var/log/osinthub/celery.log \
--pidfile=/var/run/celery/worker.pid
ExecStop=/bin/kill -s TERM $MAINPID
Restart=always
[Install]
WantedBy=multi-user.target
Create PID directory
sudo mkdir -p /var/run/celery
sudo chown osinthub:osinthub /var/run/celery
Start and enable Celery worker
sudo systemctl start osinthub-celery
sudo systemctl enable osinthub-celery
sudo systemctl status osinthub-celery
Nginx Configuration
Create nginx site configuration
sudo nano /etc/nginx/sites-available/osinthub
Add nginx configuration
upstream osinthub_app {
server unix:/home/osinthub/osint_hub/osinthub.sock fail_timeout=0;
}
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
client_max_body_size 50M;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://osinthub_app;
}
location /static/ {
alias /home/osinthub/osint_hub/staticfiles/;
expires 30d;
add_header Cache-Control "public, immutable";
}
location /media/ {
alias /home/osinthub/osint_hub/media/;
expires 7d;
}
location /.well-known/security.txt {
alias /home/osinthub/osint_hub/static/.well-known/security.txt;
}
location /robots.txt {
alias /home/osinthub/osint_hub/static/robots.txt;
}
location /sitemap.xml {
alias /home/osinthub/osint_hub/static/sitemap.xml;
}
}
Enable the site and test configuration
sudo ln -s /etc/nginx/sites-available/osinthub /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
SSL/TLS with Let’s Encrypt
Install Certbot
sudo apt install -y certbot python3-certbot-nginx
Obtain SSL certificate
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
Follow the prompts to complete the certificate installation.Enable automatic renewal
Certbot automatically creates a cron job for renewal. Test it:sudo certbot renew --dry-run
After enabling SSL, update your .env file to use HTTPS in CSRF_TRUSTED_ORIGINS.
Security Hardening
OSINT Hub includes built-in security features that are automatically enabled when DEBUG=False:
Django Security Settings
The following settings are automatically configured in osint_hub/settings.py:141-150:
- HSTS (HTTP Strict Transport Security): Forces HTTPS for 1 year
- Secure Cookies: Session and CSRF cookies only sent over HTTPS
- XSS Protection: Browser-level XSS filtering enabled
- Content Type Nosniff: Prevents MIME type sniffing
- Clickjacking Protection: X-Frame-Options set to DENY
Content Security Policy (CSP)
Configured via django-csp middleware in osint_hub/settings.py:186-234:
- Restricts script sources to self and trusted CDNs (Bootstrap, jQuery)
- Allows styles from self and Google Fonts
- Permits images from self, data URIs, and OpenStreetMap tiles
- Blocks inline scripts by default (use nonces for exceptions)
Additional Recommendations
Configure firewall
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
Set up fail2ban
sudo apt install -y fail2ban
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
Restrict file permissions
sudo chmod 600 /home/osinthub/osint_hub/.env
Regular security updates
Keep your system and dependencies up to date:sudo apt update && sudo apt upgrade -y
pip install --upgrade -r requirements.txt
Monitoring and Logs
Application Logs
View Gunicorn logs:
sudo journalctl -u osinthub -f
View Celery logs:
sudo journalctl -u osinthub-celery -f
Nginx Logs
Access logs:
sudo tail -f /var/log/nginx/access.log
Error logs:
sudo tail -f /var/log/nginx/error.log
Database Backups
Create automated PostgreSQL backups:
sudo -u postgres pg_dump osint_hub > backup_$(date +%Y%m%d).sql
Set up a cron job for daily backups:
Add:
0 2 * * * /usr/bin/pg_dump -U postgres osint_hub > /backups/osint_hub_$(date +\%Y\%m\%d).sql
Troubleshooting
Service won’t start
Check service status and logs:
sudo systemctl status osinthub
sudo journalctl -u osinthub -n 50
Static files not loading
Ensure staticfiles were collected and nginx has read permissions:
sudo su - osinthub
cd osint_hub
source venv/bin/activate
python manage.py collectstatic --no-input
exit
sudo chmod -R 755 /home/osinthub/osint_hub/staticfiles/
Database connection errors
Verify PostgreSQL is running and credentials are correct:
sudo systemctl status postgresql
sudo -u postgres psql -c "\l"
Test connection:
psql -U osint_user -h localhost -d osint_hub
Celery tasks not running
Check Redis connectivity:
Verify Celery worker is active:
sudo systemctl status osinthub-celery
Gunicorn Workers
Calculate optimal worker count:
workers = (2 × CPU cores) + 1
For a 4-core server:
PostgreSQL Tuning
Edit /etc/postgresql/{version}/main/postgresql.conf:
shared_buffers = 256MB
effective_cache_size = 1GB
maintenance_work_mem = 64MB
work_mem = 8MB
Restart PostgreSQL:
sudo systemctl restart postgresql
Redis Optimization
Edit /etc/redis/redis.conf:
maxmemory 512mb
maxmemory-policy allkeys-lru
Restart Redis:
sudo systemctl restart redis
Updates and Maintenance
Pull latest changes
sudo su - osinthub
cd osint_hub
git pull origin main
Update dependencies
source venv/bin/activate
pip install --upgrade -r requirements.txt
Collect static files
python manage.py collectstatic --no-input
Restart services
exit
sudo systemctl restart osinthub
sudo systemctl restart osinthub-celery
Next Steps