Menu
User

DropVPS Team

Writer: Cooper Reagan

How to install Django on RHEL 9 /8 ?

How to install Django on RHEL 9 /8 ?

Publication Date

10/24/2025

Category

Articles

Reading Time

4 Min

Table of Contents

To install Django on RHEL 8 or RHEL 9, use the following dnf commands to set up dependencies, create a virtual environment, and run a sample project. Both development and production setups are outlined briefly, with notes on handling common issues such as SELinux and firewall configurations.

Verify RHEL version and update packages

Confirm the OS version and refresh repositories. Having sudo/root is required.

cat /etc/redhat-release
sudo dnf -y update
sudo dnf -y install sudo curl tar git

Example output:

Red Hat Enterprise Linux release 9.x (Plow)

Install Python 3 and pip from AppStream

Use RHEL modules to select a supported Python stream, then install pip and headers.

sudo dnf module list python
# RHEL 9 (recommended):
sudo dnf module enable -y python:3.9
# Optional on RHEL 9 if you prefer newer:
# sudo dnf module enable -y python:3.11

# RHEL 8 (use the highest available, often 3.9 on newer 8.x):
# sudo dnf module enable -y python:3.9

sudo dnf -y install python3 python3-pip python3-devel gcc

Verify versions:

python3 --version
pip3 --version

Create a dedicated Django user (optional)

Run Django under an unprivileged account to reduce risk and keep files organized.

sudo useradd --create-home --shell /bin/bash django
# Lock password-based login if using SSH keys only:
sudo passwd -l django

Create and activate a Python virtual environment

Isolate project dependencies to avoid system-wide conflicts.

# As root or your admin user:
sudo -iu django
python3 -m venv ~/venvs/djangoenv
source ~/venvs/djangoenv/bin/activate
python -V
pip install --upgrade pip setuptools wheel

Install Django with pip

Install an LTS or the latest stable series. Pinning improves reproducibility.

# LTS (stable for long-term):
pip install "Django>=4.2,<4.3" # Or current stable (example): # pip install "Django>=5.1,<5.2"

python -m django --version

Create a new Django project

Initialize a clean project skeleton and apply initial migrations.

django-admin startproject mysite ~/apps/mysite
cd ~/apps/mysite
python manage.py migrate

Run the development server

Launch the built-in server for quick validation. Bind to 0.0.0.0 to test remotely.

python manage.py runserver 0.0.0.0:8000

Example output:

Starting development server at http://0.0.0.0:8000/

Allow port 8000 in the firewall (temporary for dev)

Open the port to access from your browser. Close after testing or move behind a reverse proxy.

sudo firewall-cmd --add-port=8000/tcp --permanent
sudo firewall-cmd --reload

Install Gunicorn for production

Use Gunicorn as the WSGI HTTP server. Keep it inside the same virtual environment.

# Inside the venv:
pip install "gunicorn>=21.2,<22"
# Quick test:
cd ~/apps/mysite
gunicorn --bind 0.0.0.0:8000 mysite.wsgi:application

Create a systemd service for Gunicorn

Run Gunicorn as a managed service that restarts on failure.

sudo tee /etc/systemd/system/gunicorn-mysite.service >/dev/null <<'EOF'
[Unit]
Description=Gunicorn for Django mysite
After=network.target

[Service]
User=django
Group=django
WorkingDirectory=/home/django/apps/mysite
Environment="PATH=/home/django/venvs/djangoenv/bin"
ExecStart=/home/django/venvs/djangoenv/bin/gunicorn --workers 3 --bind unix:/run/gunicorn-mysite.sock mysite.wsgi:application
RuntimeDirectory=gunicorn
RuntimeDirectoryMode=0755
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable --now gunicorn-mysite
sudo systemctl status gunicorn-mysite --no-pager

Install and configure Nginx as reverse proxy

Terminate HTTP and proxy to the Gunicorn UNIX socket. SELinux remains enforcing-friendly.

sudo dnf -y install nginx
sudo tee /etc/nginx/conf.d/mysite.conf >/dev/null <<'EOF'
server {
    listen 80;
    server_name _;

    access_log /var/log/nginx/mysite_access.log;
    error_log  /var/log/nginx/mysite_error.log;

    location / {
        proxy_pass http://unix:/run/gunicorn-mysite.sock;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
EOF

sudo nginx -t
sudo systemctl enable --now nginx

Adjust SELinux and firewall for Nginx

Allow Nginx to connect to Gunicorn and expose HTTP/HTTPS.

sudo setsebool -P httpd_can_network_connect on
sudo firewall-cmd --add-service=http --permanent
sudo firewall-cmd --add-service=https --permanent
sudo firewall-cmd --reload

Collect static files (production)

Prepare static assets for efficient serving via Nginx.

# In settings.py set: STATIC_ROOT = "/home/django/apps/mysite/static/"
# Then:
sudo -iu django bash -lc 'source ~/venvs/djangoenv/bin/activate && cd ~/apps/mysite && python manage.py collectstatic --noinput'
# Point an Nginx location /static to that directory if desired.

For more guides, visit dropvps.com — You can also explore DropVPS for server purchases, support, and more technical resources.

Linux VPS
U
Loading...

Related Posts