Django Application Implementement on Linux
Django is a mature Python web framework providing batteries-included functionality for rapid application development with built-in admin interface, ORM, authentication, and security features. Implementeing Django applications requires Python virtual environments, application servers like Gunicorn, Nginx reverse proxy, PostgreSQL database, static file serving, media file handling, and proper environment configuration. This guide covers production-ready Django deployment including virtual environment setup, Gunicorn configuration, Nginx proxy setup, PostgreSQL integration, static/media files, database migrations, and performance optimization for Linux servers.
Tabla de contenidos
- Django Architecture Overview
- Server Preparation
- Python Virtual Environment
- Django Application Setup
- PostgreSQL Database
- Gunicorn Application Server
- Nginx Reverse Proxy
- Static and Media Files
- Security Configuration
- Performance Optimization
- Conclusion
Django Architecture Overview
Django applications consist of projects containing multiple apps with models, views, URLs, and templates. Understanding the architecture helps with deployment configuration.
Request flow in Django:
- Nginx receives HTTP request
- Nginx forwards to Gunicorn via Unix socket
- Gunicorn worker process spawned
- Django receives request
- URL routing resolves to view
- View executes business logic
- Template rendered or JSON returned
- Response sent back to Nginx
- Nginx caches or returns to client
Key deployment considerations:
- Django runs as dedicated user (not root)
- Virtual environment isolates dependencies
- Static files collected and served by Nginx
- Media files stored outside web root
- Database migrations set up schema
- Secret key and debug mode configured
- Allowed hosts restricts access
- Logging configured for monitoring
Server Preparation
Prepare Linux server for Django deployment.
Update system:
sudo apt update
sudo apt upgrade -y
sudo apt install curl wget git zip unzip vim htop build-essential -y
Instale Python 3.11:
sudo apt install python3.11 python3.11-venv python3.11-dev -y
sudo apt install python3-pip -y
# Verify
python3 --version
pip3 --version
Instale PostgreSQL:
sudo apt install postgresql postgresql-contrib -y
sudo systemctl start postgresql
sudo systemctl enable postgresql
Instale Nginx:
sudo apt install nginx -y
sudo systemctl start nginx
sudo systemctl enable nginx
Cree application user:
sudo useradd -m -s /bin/bash django
sudo usermod -aG www-data django
# Create application directory
sudo mkdir -p /home/django/app
sudo chown -R django:www-data /home/django/app
Instale build dependencies:
# Required for compiling Python packages
sudo apt install libpq-dev libssl-dev libffi-dev -y
Python Virtual Environment
Isolate application dependencies using virtual environment.
Cree virtual environment:
sudo -u django python3.11 -m venv /home/django/venv
# Activate (for testing/installation)
source /home/django/venv/bin/activate
# Verify
python --version
Instale pip requirements:
# Upgrade pip in virtual environment
/home/django/venv/bin/pip install --upgrade pip setuptools wheel
# Install common Django packages
/home/django/venv/bin/pip install django gunicorn psycopg2-binary python-dotenv whitenoise
Cree requirements.txt:
# Generate from existing installation
/home/django/venv/bin/pip freeze > /home/django/app/requirements.txt
# Or create manually
cat > /home/django/app/requirements.txt << 'EOF'
Django==4.2.0
gunicorn==21.2.0
psycopg2-binary==2.9.6
python-dotenv==1.0.0
whitenoise==6.4.0
celery==5.2.7
redis==4.5.5
EOF
Django Application Setup
Instale and configure Django application.
Clone or create Django project:
cd /home/django/app
# Clone from repository
sudo -u django git clone https://github.com/yourname/django-app.git .
# Or create new project
/home/django/venv/bin/django-admin startproject config .
Instale project dependencies:
/home/django/venv/bin/pip install -r requirements.txt
Cree .env file:
sudo -u django cat > /home/django/app/.env << 'EOF'
DEBUG=False
SECRET_KEY=your-secret-key-here
ALLOWED_HOSTS=example.com,www.example.com
DATABASE_URL=postgresql://django_user:password@localhost/django_db
REDIS_URL=redis://127.0.0.1:6379/0
EOF
Generate secret key:
python3 << 'EOF'
import secrets
print(secrets.token_urlsafe(50))
EOF
# Update .env with generated key
Update Django settings:
sudo -u django nano /home/django/app/config/settings.py
Configure for production:
# security settings
DEBUG = False
ALLOWED_HOSTS = ['example.com', 'www.example.com']
SECRET_KEY = 'from .env file'
# Database
import os
from urllib.parse import urlparse
db_url = os.getenv('DATABASE_URL')
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'django_db',
'USER': 'django_user',
'PASSWORD': 'SecurePassword123!',
'HOST': 'localhost',
'PORT': '5432',
}
}
# Cache configuration
CACHES = {
'default': {
'BACKEND': 'django_redis.cache.RedisCache',
'LOCATION': 'redis://127.0.0.1:6379/1',
'OPTIONS': {
'CLIENT_CLASS': 'django_redis.client.DefaultClient',
}
}
}
# Static files
STATIC_URL = '/static/'
STATIC_ROOT = '/home/django/app/staticfiles/'
# Media files
MEDIA_URL = '/media/'
MEDIA_ROOT = '/home/django/app/media/'
# Security
SECURE_SSL_REDIRECT = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
SECURE_BROWSER_XSS_FILTER = True
SECURE_CONTENT_SECURITY_POLICY = {
'default-src': ("'self'",),
}
# Logging
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'file': {
'level': 'INFO',
'class': 'logging.FileHandler',
'filename': '/home/django/app/logs/django.log',
},
},
'root': {
'handlers': ['file'],
'level': 'INFO',
},
}
Cree logs directory:
sudo -u django mkdir -p /home/django/app/logs
sudo -u django touch /home/django/app/logs/django.log
PostgreSQL Database
Configure PostgreSQL database and user.
Connect to PostgreSQL:
sudo -u postgres psql
Cree database and user:
CREATE DATABASE django_db;
CREATE USER django_user WITH PASSWORD 'SecurePassword123!';
ALTER ROLE django_user SET client_encoding TO 'utf8';
ALTER ROLE django_user SET default_transaction_isolation TO 'read committed';
ALTER ROLE django_user SET default_transaction_deferrable TO on;
ALTER ROLE django_user SET timezone TO 'UTC';
GRANT ALL PRIVILEGES ON DATABASE django_db TO django_user;
\q
Run migrations:
cd /home/django/app
/home/django/venv/bin/python manage.py migrate
# Output shows: running migrations, applied migrations
Cree superuser:
/home/django/venv/bin/python manage.py createsuperuser
# Enter username, email, password when prompted
Collect static files:
/home/django/venv/bin/python manage.py collectstatic --noinput
# Copies all static files to STATIC_ROOT directory
Gunicorn Application Server
Configure Gunicorn to run Django application.
Cree Gunicorn configuration:
sudo -u django cat > /home/django/app/gunicorn_config.py << 'EOF'
import multiprocessing
# Server socket
bind = 'unix:/tmp/gunicorn.sock'
backlog = 2048
# Worker processes
workers = multiprocessing.cpu_count() * 2 + 1
worker_class = 'sync'
worker_connections = 1000
timeout = 30
keepalive = 5
# Logging
accesslog = '/home/django/app/logs/gunicorn_access.log'
errorlog = '/home/django/app/logs/gunicorn_error.log'
loglevel = 'info'
# Server mechanics
daemon = False
umask = 0
user = 'django'
group = 'www-data'
tmp_upload_dir = None
# Server hooks
def post_fork(server, worker):
server.log.info("Worker spawned (pid: %s)", worker.pid)
def pre_fork(server, worker):
pass
def pre_exec(server):
server.log.info("Forking new master process")
def when_ready(server):
server.log.info("Gunicorn server is ready. Spawning workers")
def on_exit(server):
server.log.info("Gunicorn exiting")
EOF
Cree systemd service:
sudo cat > /etc/systemd/system/gunicorn.service << 'EOF'
[Unit]
Description=Gunicorn application server
After=network.target
[Service]
Type=notify
User=django
Group=www-data
WorkingDirectory=/home/django/app
ExecStart=/home/django/venv/bin/gunicorn --config gunicorn_config.py config.wsgi
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable gunicorn
sudo systemctl start gunicorn
sudo systemctl status gunicorn
Verifique Gunicorn:
# Check if socket created
ls -la /tmp/gunicorn.sock
# Check logs
tail -f /home/django/app/logs/gunicorn_error.log
Nginx Reverse Proxy
Configure Nginx to proxy requests to Gunicorn.
Cree Nginx configuration:
sudo nano /etc/nginx/sites-available/django.conf
Apply configuration:
upstream gunicorn {
server unix:/tmp/gunicorn.sock fail_timeout=0;
}
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com www.example.com;
client_max_body_size 20M;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
access_log /var/log/nginx/django_access.log;
error_log /var/log/nginx/django_error.log;
# Security headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
# Static files
location /static/ {
alias /home/django/app/staticfiles/;
expires 30d;
add_header Cache-Control "public, immutable";
}
# Media files
location /media/ {
alias /home/django/app/media/;
expires 7d;
}
# Proxy to Gunicorn
location / {
proxy_pass http://gunicorn;
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;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}
Enable configuration:
sudo ln -s /etc/nginx/sites-available/django.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
Static and Media Files
Properly handle Django static and media files.
Collect static files:
cd /home/django/app
/home/django/venv/bin/python manage.py collectstatic --noinput
# Verify
ls -la /home/django/app/staticfiles/
Configure static file serving:
# Create symlink for web server access
sudo mkdir -p /var/www/django-static
sudo chown django:www-data /var/www/django-static
sudo ln -s /home/django/app/staticfiles/* /var/www/django-static/
Cree media directory:
sudo -u django mkdir -p /home/django/app/media
sudo chmod 755 /home/django/app/media
# Set permissions for uploads
sudo chmod 775 /home/django/app/media
Configure file uploads:
# In Django settings.py
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
# Maximum upload size
FILE_UPLOAD_MAX_MEMORY_SIZE = 20971520 # 20 MB
DATA_UPLOAD_MAX_MEMORY_SIZE = 20971520 # 20 MB
Security Configuration
Implement security best practices.
Set secure environment:
# Protect .env file
sudo chmod 600 /home/django/app/.env
# Verify permissions
ls -la /home/django/app/.env
Configure HTTPS enforcement:
# In settings.py
SECURE_SSL_REDIRECT = True
SECURE_HSTS_SECONDS = 31536000
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_PRELOAD = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
CSRF_COOKIE_HTTPONLY = True
Set allowed hosts:
ALLOWED_HOSTS = ['example.com', 'www.example.com']
Configure security headers via Nginx:
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "DENY" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
Optimización del rendimiento
Optimize Django application for production.
Enable database connection pooling:
sudo apt install pgbouncer -y
# Configure pgbouncer for connection pooling
sudo nano /etc/pgbouncer/pgbouncer.ini
Configure Celery for async tasks:
# Install Celery
/home/django/venv/bin/pip install celery redis
# Create Celery configuration in Django
cat > /home/django/app/config/celery.py << 'EOF'
import os
from celery import Celery
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
app = Celery('config')
app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks()
EOF
Cree Celery worker service:
sudo cat > /etc/systemd/system/celery.service << 'EOF'
[Unit]
Description=Celery Service
After=network.target
[Service]
Type=forking
User=django
Group=www-data
WorkingDirectory=/home/django/app
ExecStart=/home/django/venv/bin/celery -A config worker --loglevel=info
Restart=always
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable celery
sudo systemctl start celery
Monitor performance:
# Check Gunicorn workers
ps aux | grep gunicorn
# Monitor database
psql -U django_user -d django_db -c "SELECT count(*) FROM pg_stat_activity;"
# Check logs
tail -f /home/django/app/logs/gunicorn_error.log
tail -f /home/django/app/logs/django.log
Conclusión
Implementeing Django applications on Linux requires coordinated setup of Python virtual environments, Gunicorn application servers, Nginx reverse proxies, and PostgreSQL databases. This guide covers production-ready deployment with proper isolation, security hardening, static file handling, and performance optimization. Key focus areas are virtual environment setup ensuring dependency isolation, Gunicorn configuration for worker process management, Nginx reverse proxy for efficient request handling, PostgreSQL for reliable data persistence, and proper file permissions ensuring security. Regular monitoring of logs and application metrics ensures continued operation. Following these practices creates a robust Django deployment ready for production traffic.


