0

I'm an intern trying to deploy a Django application on a cPanel server, and I've run into a persistent "Internal Server Error" coupled with an Apache redirect loop. I've been troubleshooting for over two days with various AI helpers, but I can't pinpoint the exact cause. Any fresh perspectives ??


My Setup:

  • Server OS : AlmaLinux 9.6 (Sage Margay)
  • Hosting Environment: cPanel (My cPanel account does not have the "Setup Python App" option, which is why I'm using a manual Apache/mod_wsgi configuration.)
  • Django Deployment: Apache + mod_wsgi
  • No .htaccess content at all.
  • Project Structure: I have two Django instances (production and staging) for CI/CD,

each with its own settings, environment variables, database, and domain.

  • validator/settings/base.py

  • validator/settings/production.py (inherits from base)

  • validator/settings/staging.py (inherits from base)

  • Environment files are stored in /etc/validator/envs

  • WSGI files are stored in /etc/validator/wsgi/

  • Django project roots: /home/<username>/<app_name>/ (prod) and /home/<username>/<app_name_test>/ (staging).

  • Python Version: My virtual environments are running Python 3.12.9, and my WSGI files assert this.


The Problem:

When I try to access either domain.in (production) or test.domain.in (staging), I receive an "Internal Server Error". My Apache error log (specifically /var/log/httpd/error_log) shows the following critical error message:

[Fri May 30 00:26:38.624027 2025] [core:error] [pid 253617:tid 253705] [client 45.115.89.80:26970] AH00124: Request exceeded the limit of 10 internal redirects due to probable configuration error. Use 'LimitInternalRecursion' to increase the limit if necessary. Use 'LogLevel debug' to get a backtrace.

This started after a server expiration/renewal and then when I configured new databases for staging and production, updating the respective .env files. Previously, it worked (sharing a database).


My Apache configuration:

I understand cPanel uses a "Direct Include Style" for Apache configs, where httpd.conf includes files from directories like /etc/apache2/conf.d/userdata/.... My custom Django configurations are placed in these included directories.

  1. Production Domain Custom Apache Config (/etc/apache2/conf.d/userdata/std/2_4/<username>/<domain.in>/<filename>.conf):
ServerName <domain>.in
ServerAlias www.<domain>.in
ServerAlias <server_ip>
WSGIDaemonProcess django_app python-home=/home/<username>/app/venv python-path=/home/<username>/app user=<apache_user> group=<group_user>
WSGIProcessGroup app
WSGIScriptAlias / /etc/validator/wsgi/production.wsgi 
Alias /static/ /home/<username>/app/staticfiles/
<Directory /home/<username>/app/staticfiles>
 Require all granted
</Directory>
<Directory /etc/validator/wsgi>
 <Files production.wsgi>
 Require all granted
 </Files>
</Directory>
ErrorLog /home/<username>/app/error.log
CustomLog /home/<username>/app/access.log combined
  1. Staging Domain Custom Apache Config (similar path for test.domain.in):
ServerName test.<domain>.in
ServerAlias www.test.<domain>.in
WSGIDaemonProcess test_app python-home=/home/<username>/app_test/venv python-path=/home/<username>/app_test user=<apache_user> group=<group_user>
WSGIProcessGroup app_test
WSGIScriptAlias / /etc/validator/wsgi/staging.wsgi 
Alias /static/ /home/<username>/app_test/staticfiles/
<Directory /home/<username>/app_test/staticfiles>
 Require all granted
</Directory>
<Directory /etc/validator/wsgi>
 <Files production.wsgi>
 Require all granted
 </Files>
</Directory>
ErrorLog /home/<username>/app_test/error.log
CustomLog /home/<username>/app_test/access.log combined

3.Production Environment File (/etc/validator/envs/production.env):

DBUSER=<dbuser>
DBPASSWORD=<dbpasswd>
DBNAME=<dbname>
DBHOST=localhost
DBPORT=3306
  1. Production WSGI File (/etc/validator/wsgi/production.wsgi):
import os
import sys
from pathlib import Path
from dotenv import load_dotenv
ENV_FILE = Path('/etc/validator/envs/production.env')
load_dotenv(dotenv_path=ENV_FILE)
os.environ.setdefault('DJANGO_SETTINGS_MODULE', '<django_root_app>.settings.production')
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
  1. Django settings/prod.py (similar structure for settings/staging.py):
import os
from .base import *
DEBUG = False
ALLOWED_HOSTS = [
 "domain",
 "www.domain",
 "server_ip",
]
DATABASES = {
 "default": {
 "ENGINE": "django.db.backends.<sql>",
 "USER": os.environ["DBUSER"],
 "PASSWORD": os.environ["DBPASSWORD"],
 "NAME": os.environ["DBNAME"],
 "HOST": os.environ["DBHOST"],
 "PORT": os.environ["DBPORT"],
 }
}

Troubleshooting Steps I've Already Taken:

  1. Checked Apache Error Logs: The main Apache log (/var/log/httpd/error_log) consistently shows the "Request exceeded the limit of 10 internal redirects" error. My Django app's custom logs (/home//app/error.log and _test/error.log) are empty or show no relevant errors, often indicating a problem before Django's logger can even kick in.

  2. Permissions: I've meticulously checked and set chown -R medivali:webapps and chmod permissions (755 for directories, 644 for files, 664 for logs) on /home//app/, /home//app_test/, /etc/validator/envs/, and /etc/validator/wsgi/.

  3. WSGIDaemonProcess User/Group: I've tried user=nobody group=webapps (as in config) and user=medivali group=medivali. Neither resolves the issue.

  4. Python Version Assertion: Confirmed venv/bin/python --version is 3.12+ for both environments.

  5. proxy_fcgi_module Conflict: I've added <FilesMatch ".(phtml|php[0-9]*)$">SetHandler None to my validator_conf.conf files to try and prevent the cPanel PHP-FPM handler from interfering.

  6. DocumentRoot vs. WSGIScriptAlias: I understand WSGIScriptAlias / should override DocumentRoot for Django, but I've also tried creating an index.html in /home/medivali/public_html (the default DocumentRoot in the main VHost) to test basic Apache serving, but it still leads to the redirect loop or internal server error.

  7. Database Credentials: I've triple-checked the DBUSER, DBPASSWORD, DBNAME, DBHOST, DBPORT in both .env files. I can connect to the databases directly from the server using mysql client.

  8. ALLOWED_HOSTS: Confirmed correct domain names are in ALLOWED_HOSTS for both production and staging settings.

  9. AI Consultations: Spent 2.5 days consulting ChatGPT, Gemini, Claude, and DeepSeek, trying various suggestions, but without success.

asked May 30, 2025 at 8:35
2
  • Try setting LogLevel debug to see if there's more logs. This is generally caused by a RewriteRule somewhere in your apache config. Commented May 31, 2025 at 18:50
  • Thanks for the suggestion! ’ve checked my .htaccess and main Apache configs, and I don’t see any RewriteRule directives defined anywhere. I’ll keep digging :) Commented Jun 1, 2025 at 4:45

1 Answer 1

1

It was a Python build issue. I figured it out — some C-extension modules (like for pickle) were not properly built, which caused the internal server error. After rebuilding the environment properly, the issue was resolved. Thank you!

answered Jun 1, 2025 at 13:18
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.