What am I missing? This is my first time trying to use Django. The server that is built into Django will serve the file locally just fine, but I can't get Apache to do the same. The following is what I'm doing from a brand new, clean, Linux 2 instance.
sudo yum update
sudo yum install -y python3
sudo yum install httpd-devel
sudo yum install -y mod_wsgi
cd /etc/httpd/modules (verify that mod_wsgi is there)
cd /var/www/
sudo mkdir myApp
sudo chown ec2-user myApp
cd myApp
sudo pip3 install virtualenv
virtualenv myprojectenv
source myprojectenv/bin/activate
sudo pip3 install django==2.1.1
django-admin startproject myApp
cd myApp
python manage.py migrate
python manage.py runserver
wget http://127.0.0.1:8000/ (works correctly as it should and I receive test page)
python manage.py startapp hello
cd myApp
vim settings.py
settings.py: edit this part to look like this:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'hello.apps.HelloConfig',
]
.
vim urls.py
urls.py: entire file looks like this:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('hello.urls')),
]
.
cd ..
cd hello
vim views.py
views.py: entire file looks like this
from django.shortcuts import render
# Create your views here.
# hello/views.py
from django.http import HttpResponse
def homePageView(request):
return HttpResponse('Hello, World!')
.
vim urls.py
hello/urls.py: entire file looks like this:
# hello/urls.py
from django.urls import path
from .views import homePageView
urlpatterns = [
path('', homePageView, name='home')
]
.
cd ..
python manage.py runserver
wget http://127.0.0.1:8000/ (works correctly as it should, now gets “Hello World!”)
Now for the Apache part:
sudo vim /etc/httpd/conf/httpd.conf
Paste the following to the bottom of httpd.conf:
WSGIScriptAlias / /var/www/myApp/myApp/myApp/wsgi.py
WSGIPythonHome /var/www/myApp/myprojectenv
WSGIPythonPath /var/www/myApp
<Directory /var/www/myApp/myApp/myApp>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
.
sudo service httpd restart
wget http://127.0.0.1
Connecting to 127.0.0.1:80... connected. HTTP request sent, awaiting response...
and that is all it does until it times out. Connecting to the public IP address through a browser does the same thing; it connects and just sits there waiting for a response.
Apache error log (/var/log/httpd/error_log) says this:
Django ImportError: No module named site
A quick search suggests that this is because mod_wsgi is using a different version of python than my virtual environment. I'm using python3.7
cd /etc/httpd/modules
ldd mod_wsgi.so
outputs
linux-vdso.so.1 (0x00007ffd7dec3000)
libpython2.7.so.1.0 => /lib64/libpython2.7.so.1.0 (0x00007fe35815d000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fe357f3f000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007fe357d3b000)
libutil.so.1 => /lib64/libutil.so.1 (0x00007fe357b38000)
libm.so.6 => /lib64/libm.so.6 (0x00007fe3577f8000)
libc.so.6 => /lib64/libc.so.6 (0x00007fe35744d000)
/lib64/ld-linux-x86-64.so.2 (0x00007fe358755000)
Clearly that is a different version. I've uninstalled it, and installed it again while in the python3.7 virtual environment, but the result is the same. It still says "libpython2.7.so.1.0 => /lib64/libpython2.7.so.1.0".
Ultimately, the problem here was a matter of getting Python to use the correct/new version of sqlite3. The error log located at /var/log/httpd/error_log proved very useful for troubleshooting (surprise).
In searching through other Q&A I found a lot of answers that involved LD_LIBRARY_PATH and LD_RUN_PATH. However, with deeper research I found that these are not the preferred method for instructing the compiler as to library paths. As shown below, ldconfig is used instead, along with a .conf file placed in the /etc/ld.so.conf.d/ directory.
The following is the step-by-step instructions for getting the latest Django served up by Apache; beginning with a fresh Linux 2 EC2 instance.
sudo yum update
sudo su
yum groupinstall "Development Tools"
crtl-d
sudo yum -y install libffi-devel
sudo yum install -y openssl-devel
sudo vim /etc/ld.so.conf.d/usrlocal.conf
In this empty file you created, add:
/usr/local/lib
/usr/local/lib64
next:
sudo ldconfig -v
cd ~
mkdir downloads
cd downloads
wget https://sqlite.org/2020/sqlite-autoconf-3320300.tar.gz
tar -xvf sqlite-autoconf-3320300.tar.gz
cd sqlite-autoconf-3320300
./configure --prefix=/usr/local
make -L
sudo make install
sudo ldconfig -v
cd ~downloads
wget https://www.python.org/ftp/python/3.7.7/Python-3.7.7.tgz
tar -xvf Python-3.7.7.tgz
cd Python-3.7.7
./configure --enable-shared --enable-optimizations --with-threads --enable-loadable-sqlite-extensions --with-openssl=/usr/local/lib64
sudo make -L
sudo make altinstall (altinstall keeps old 2.7 version)
sudo ldconfig -v
python 3.7 (to verify installation ctrl-d to quit)
>>>import sqlite3
>>> sqlite3.sqlite_version
ctrl-d
sudo chown -R ec2-user /usr/local/lib/python3.7
sudo chown ec2-user /usr/local/bin
sudo chown ec2-user /usr/local/lib
sudo yum install httpd-devel
sudo ldconfig -v
cd /var/www/
sudo mkdir django
sudo chown ec2-user django
cd django
pip3.7 install virtualenv
virtualenv myprojectenv
source myprojectenv/bin/activate
python -c 'import sys; print(sys.prefix)'
pip3.7 install mod_wsgi
mod_wsgi-express module-config
That will output something like the following. You will copy that and paste it to the bottom of your httpd.conf file. sudo vim /etc/httpd/conf/httpd.conf
LoadModule wsgi_module "/var/www/django/myprojectenv/lib/python3.7/site-packages/mod_wsgi/server/mod_wsgi-py37.cpython-37m-x86_64-linux-gnu.so"
WSGIPythonHome "/var/www/django/myprojectenv"
next:
pip3.7 install Django==3.0.7
django-admin startproject myApp
cd myApp
python manage.py migrate
python manage.py startapp hello
cd myApp
vim wsgi.py
edit to look like the following (add ‘import sys’ and ‘sys.path…….’)
import os
import sys
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myApp.settings')
sys.path.append('/var/www/myApp/myApp/myApp')
sys.path.append('/var/www/myApp/myApp')
application = get_wsgi_application()
next:
vim settings.py
edit to look like the following, substituting your EC2 instance public IP
ALLOWED_HOSTS = ['xx.xxx.xx.xxx'] (substitute your EC2 public IP address)
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'hello.apps',
]
vim urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('hello.urls')),
]
next:
cd ../hello
vim views.py
Edit to look like the following. These are Python files. So, mind your indentations
from django.shortcuts import render
# Create your views here.
# hello/views.py
from django.http import HttpResponse
def homePageView(request):
return HttpResponse('Hello, World!')
This next file you will create.
vim urls.py
Paste:
# hello/urls.py
from django.urls import path
from .views import homePageView
urlpatterns = [
path('', homePageView, name='home')
]
Now back to Apache:
sudo vim /etc/httpd/conf/httpd.conf
Paste the following to the bottom of httpd.conf:
WSGIScriptAlias / /var/www/django/myApp/myApp/wsgi.py
WSGIPythonPath /var/www/django
<Directory /var/www/django/myApp/myApp>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
.
sudo service httpd start
At this point you should be able to make a request to the public IP of your instance and get the “Hello World!” response.
Finally:
sudo su
vim /var/log/httpd/error_log
and viola, you have some new issues to address!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With