Running Django 1.9 on CentOS 7/Apache 2.4/Python 3.4
Question: I have successfully created my Django (1.9) site on my computer. And is now
trying to move it to a web server (CentOS 7). After sitting a whole day,
searching the web, I have found many guides on how to do this. But in the
midst of all of this, probably confused some of them together, since it seems
there is no "one-way" to make Django run on a webserver.

After a long struggle, I have actually managed to get the Apache (2.4.6)
running, but I am now seeing an Internal 500 error. I took a while but i found
the log files. For other readers in my case they were in
/etc/httpd/logs/error_log.

    
    
    [Wed Feb 24 18:00:05.475116 2016] [mpm_prefork:notice] [pid 4641] AH00163: Apache/2.4.6 (CentOS) mod_wsgi/3.4 Python/2.7.5 configured -- resuming normal operations
    [Wed Feb 24 18:00:05.475162 2016] [core:notice] [pid 4641] AH00094: Command line: '/usr/sbin/httpd -D FOREGROUND'
    [Wed Feb 24 18:00:12.867329 2016] [:error] [pid 4642] [client x:54699] mod_wsgi (pid=4642): Target WSGI script '/var/www/sites/mysite.com/mysite/wsgi.py' cannot be loaded as Python module.
    [Wed Feb 24 18:00:12.867484 2016] [:error] [pid 4642] [client x:54699] mod_wsgi (pid=4642): Exception occurred processing WSGI script '/var/www/sites/mysite.com/mysite/wsgi.py'.
    [Wed Feb 24 18:00:12.867570 2016] [:error] [pid 4642] [client x:54699] Traceback (most recent call last):
    [Wed Feb 24 18:00:12.867664 2016] [:error] [pid 4642] [client x:54699]   File "/var/www/sites/mysite.com/mysite/wsgi.py", line 12, in <module>
    [Wed Feb 24 18:00:12.868020 2016] [:error] [pid 4642] [client x:54699]     from django.core.wsgi import get_wsgi_application
    [Wed Feb 24 18:00:12.868109 2016] [:error] [pid 4642] [client x:54699] ImportError: No module named django.core.wsgi
    

I assume I need some kind of reference to the Django code, though I cannot
figure out why, how or where to put this.

Out of interest of any future readers, and also to see what I have done, I
will try to retrace my steps I have done to be able to see what I might have
missed or done incorrectly.

NB: I am not using virtualenv to run my Django project.

  1. Installed python 3.4
  2. Installed pip for python 3.4 (using curl)
  3. Installed Apache 2.4 (from yum)
  4. Installed mod_wsgi (from yum) (many sites said to compile it directly from code, did not venture into this, anyone recommending highly to do this?)
  5. Installed Django with pip (NB, without virtualenv)

After the above was done, I used SVN client to checkout my code on the server
to the folder /var/www/sites/mysite.com. Folder structure looks like this.
(Note still using sqllite, did not get to the migration to PostgreSQL yet,
this is next step, once i see my site online)

(Side note, I spend a lot of time figuring out where to put the Django code,
since everywhere i looked, it was placed differently. I ended up deciding to
put it directly in the /var/www since it is the site code, and it is needed
here, it seems. Any comments are welcome.)

    
    
    +---var
    |   \---www
    |       \---sites
    |          \---static
    |          \---mysite.com
    |             +---db.sqllite3
    |             +---manage.py
    |             \---.svn
    |             \---mysite
    |                +---settings.py
    |                +---urls.py
    |                +---wsgi.py
    |                +---...
    |             \---mysiteapp
    |                +---urls.py
    |                +---admin.py
    |                +---...
    

I have used "sudo python3.4 manage.py collectstatic" to move the static files
to the /var/www/sites/static/ folder. Since I did not want this to be inside
the folder where my .svn files are. I could ignore the folder, but for now
this is how it is.

The Apache installations is pretty much standard, I have changed a few things,
but not something which should have an impact, as far as I am concerned, so I
am just showing here the conf file I am using in the "/etc/httpd/conf.d"
folder. (please note I have replace name of the project with mysite)

    
    
    WSGIPythonPath /var/www/sites/mysite.com
    ServerName sub.server.com
    <VirtualHost *:80>
    
      Alias /static/ /var/www/sites/static/
      <Directory /var/www/sites/static/>
        Options -Indexes
        Require all granted
      </Directory>
    
      WSGIScriptAlias / /var/www/sites/mysite.com/mysite/wsgi.py
    
      <Directory /var/www/sites/mysite.com/mysite>
        <Files wsgi.py>
          Require all granted
        </Files>
      </Directory>
    
    </VirtualHost>
    

My wsgi.py file is the standard one which Django creates when creating the
initial project. This works with Djangos own web server when running on my
computer, could not see if I might have to change something here to make it
work when using Apache?

    
    
    import os
    
    from django.core.wsgi import get_wsgi_application
    
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
    
    application = get_wsgi_application()
    

For the interested I have also included the settings.py file, to see what is
here.

    
    
    import os
    
    # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    
    # Quick-start development settings - unsuitable for production
    # See https://docs.djangoproject.com/en/1.9/howto/deployment/checklist/
    
    # SECURITY WARNING: keep the secret key used in production secret!
    SECRET_KEY = <removed>
    
    # SECURITY WARNING: don't run with debug turned on in production!
    DEBUG = True
    
    ALLOWED_HOSTS = []
    
    # Application definition
    
    INSTALLED_APPS = [
        'mysiteapp.apps.mysiteappConfig',
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
    ]
    
    MIDDLEWARE_CLASSES = [
        'django.middleware.security.SecurityMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
        'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
    ]
    
    ROOT_URLCONF = 'mysite.urls'
    
    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [os.path.join(BASE_DIR, 'templates')],
            'APP_DIRS': True,
            'OPTIONS': {
                'context_processors': [
                    'django.template.context_processors.debug',
                    'django.template.context_processors.request',
                    'django.contrib.auth.context_processors.auth',
                    'django.contrib.messages.context_processors.messages',
                ],
            },
        },
    ]
    
    WSGI_APPLICATION = 'mysite.wsgi.application'
    
    
    # Database
    # https://docs.djangoproject.com/en/1.9/ref/settings/#databases
    
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        }
    }
    
    
    # Password validation
    # https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators
    
    AUTH_PASSWORD_VALIDATORS = [
        {
            'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
        },
        {
            'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
        },
        {
            'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
        },
        {
            'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
        },
    ]
    
    
    # Internationalization
    # https://docs.djangoproject.com/en/1.9/topics/i18n/
    
    LANGUAGE_CODE = 'en-us'
    
    TIME_ZONE = 'CET'
    
    USE_I18N = True
    
    USE_L10N = True
    
    USE_TZ = True
    
    # Logging
    LOGGING = {
        'version': 1,
        'disable_existing_loggers': False,
        'filters': {
            'require_debug_false': {
                '()': 'django.utils.log.RequireDebugFalse'
            }
        },
        'handlers': {
            'mail_admins': {
                'level': 'ERROR',
                'filters': ['require_debug_false'],
                'class': 'django.utils.log.AdminEmailHandler'
            },
            'logfile': {
                'class': 'logging.handlers.WatchedFileHandler',
                'filename': '/var/log/django/error.log'
            },
        },
        'loggers': {
            'django.request': {
                'handlers': ['mail_admins'],
                'level': 'ERROR',
                'propagate': True,
            },
            'django': {
                'handlers': ['logfile'],
                'level': 'ERROR',
                'propagate': False,
            },
        }
    }
    
    # Static files (CSS, JavaScript, Images)
    # https://docs.djangoproject.com/en/1.9/howto/static-files/
    
    STATIC_ROOT = '/var/www/sites/static/'
    STATIC_URL = '/static/'
    

I hope someone can point me in the right direction. I appreciate any help I
can get, or comments to the setup. After a full day of trying to make this
work, and searching the web, I really miss a good guide on how to make Django
run on the server side. There are so many guides, but you need to combine a
lot of different once to get the full picture, since each guide makes so many
assumptions, and you more or less have to have prior knowledge to use them.

And when you do combine the guides, each guide is doing it a bit differently,
making your brain work overtime to piece it all together. :)


Answer: _(Posted on behalf of OP)._

Sometimes you just need to go away from things, and view it from a different
angle. It was just a reference that was missing. In the conf I needed to also
add the reference to the Django libs. To the WSGIPythonPath I added
"/usr/lib64/python3.4/site-packages:", so it now looks like the below. And
then it all worked. I hope this at least now will help someone else out there.

    
    
    WSGIPythonPath /usr/lib64/python3.4/site-packages:/var/www/sites/mysite
    

If anyone stumbles across this post, and feels like commenting on any of the
other questions I have asked, please feel free. I would still like to know, if
my approach could be improved, as this is just a staging server, and I have to
do it all again for production. Might as well learn to do it better.

