Skip to content

Django production dev

Michael Hulse edited this page Jul 2, 2019 · 39 revisions

I’m on (USED TO BE ON, they were bought by GoDaddy, so currently looking (July 2019) for new hosting … Probably do an Amazon box …) a WebFaction server, using Apache, mod_wsgi 4.2.8/Python 3.4.

WebFaction control panel setup

Follow these steps:

virtualenv and virtualenvwrapper

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

USE Python3.4 pyvenvinstead of the following …

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

First, ssh to server and clone repo:

$ git clone https://[email protected]/repower/repower.git

Next, follow these steps via the terminal:

$ PYTHONVER=3.3
$ PYTHON=python${PYTHONVER}
$ mkdir -p $HOME/{bin,tmp,lib/$PYTHON,.virtualenvs}
$ easy_install-${PYTHONVER} pip
$ pip3 install virtualenv --no-use-wheel
$ pip3 install --install-option="--user" virtualenvwrapper --no-use-wheel

Add this to your .bashrc file:

# https://community.webfaction.com/questions/4253/simple-virtualenv-usage-with-django/10797
PATH="$HOME/bin:$PATH"
TEMP="$HOME/tmp"
alias python=${PYTHON}
export PYTHON=${PYTHON}
export WORKON_HOME="$HOME/.virtualenvs"
export VIRTUALENVWRAPPER_TMPDIR="$WORKON_HOME/tmp"
export VIRTUALENVWRAPPER_VIRTUALENV=`which virtualenv`
export VIRTUALENVWRAPPER_VIRTUALENV_ARGS='--no-site-packages'
export VIRTUALENVWRAPPER_PYTHON=`which python3`
export PIP_VIRTUALENV_BASE=$WORKON_HOME
export PIP_RESPECT_VIRTUALENV=true
if [[ -r `which virtualenvwrapper.sh` ]]; then
	source `which virtualenvwrapper.sh`
else
	echo "WARNING: Can't find virtualenvwrapper.sh"
fi

And reload things:

source $HOME/.bashrc
hash -r

Make a virtualenv:

$ mkvirtualenv --python=/usr/local/bin/python3 repower --no-site-packages

Add a sitecustomize.py to your virtualenv:

$ touch ~/.virtualenvs/repower/sitecustomize.py

While you're in there, append this to the activate file inside your virtualenv:

export DJANGO_SETTINGS_MODULE="repower.settings.production"
echo $DJANGO_SETTINGS_MODULE

Activate your virtualenv:

$ workon repower

Clone git repo

$ cd ~/webapps/appname_root
$ git clone [email protected]:user/repo.git

Default Django settings file

IF USING BITBUCKET

Do this:

Django project/app setup

Navigate to your version controlled git-installed project and enable your virtual environment:

$ repower

Now you can safely install your Django project's required modules:

$ pip install -r requirements.txt

Restart apache:

$ ../apache2/bin/restart
# Or, if using custom alias:
$ arest

Right about now is a good time to ssh into the server via a new terminal tab and run:

$ tail -f logs/user/error_repower.log
# Or, if using custom alias:
$ herr

Keep this tab open and keep tabs on server errors as this will help you debug your setup.

Apache setup

Server setup stuffs follow …

httpd.conf

ServerRoot "/home/mhulse/webapps/repower_root/apache2"

LoadModule dir_module        modules/mod_dir.so
LoadModule env_module        modules/mod_env.so
LoadModule log_config_module modules/mod_log_config.so
LoadModule mime_module       modules/mod_mime.so
LoadModule rewrite_module    modules/mod_rewrite.so
LoadModule setenvif_module   modules/mod_setenvif.so
LoadModule wsgi_module       modules/mod_wsgi.so

LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
CustomLog /home/mhulse/logs/user/access_repower_root.log combined
ErrorLog /home/mhulse/logs/user/error_repower_root.log
KeepAlive Off
Listen 13171
MaxSpareThreads 3
MinSpareThreads 1
ServerLimit 1
SetEnvIf X-Forwarded-SSL on HTTPS=1
ThreadsPerChild 5
WSGIPythonPath /home/mhulse/webapps/repower_root:/home/mhulse/webapps/repower_root/repower:/home/mhulse/webapps/repower_root/lib/python3.4
WSGIDaemonProcess repower_root processes=2 threads=12 python-path=/home/mhulse/webapps/repower_root:/home/mhulse/webapps/repower_root/repower:/home/mhulse/webapps/repower_root/lib/python3.4
WSGIProcessGroup repower_root
WSGIRestrictEmbedded On
WSGILazyInitialization On
WSGIScriptAlias / /home/mhulse/webapps/repower_root/repower/repower/wsgi.py

Important:

  1. Make sure Listen 13171 is using the port of your WebFaction application
  2. Change username to match yours
  3. Change application repower_root to match yours
  4. Change Django project name to match yours

WSGI

This works:

"""
WSGI config for repower project.

This module contains the WSGI application used by Django's development server
and any production WSGI deployments. It should expose a module-level variable
named ``application``. Django's ``runserver`` and ``runfcgi`` commands discover
this application via the ``WSGI_APPLICATION`` setting.

Usually you will have the standard Django WSGI application here, but it also
might make sense to replace the whole Django WSGI application with a custom one
that later delegates to the Django one. For example, you could introduce WSGI
middleware here, or combine a Django application with an application of another
framework.
"""

import os
import site
import sys

lazy_path = lambda p1, p2: os.path.abspath(os.path.join(p1, p2))

# Dynamically resolve paths.
VIRTUALENV_PATH = '~/.virtualenvs'
SITE_PACKAGES_PATH = lazy_path(VIRTUALENV_PATH, 'repower/lib/python3.4/site-packages') 

WORKING_PATH = os.path.abspath(os.path.dirname(__file__))
ROOT_PATH = lazy_path(WORKING_PATH, '../')

site.addsitedir(SITE_PACKAGES_PATH)
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'repower.settings.production')

# check virtualenv site-packages FIRST!
sys.path.insert(0, SITE_PACKAGES_PATH)
sys.path.append(ROOT_PATH)
sys.path.append(lazy_path(ROOT_PATH, 'repower'))

# This application object is used by any WSGI server configured to use this
# file. This includes Django's development server, if the WSGI_APPLICATION
# setting points here.
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()

# Apply WSGI middleware here.
# from helloworld.wsgi import HelloWorldApplication
# application = HelloWorldApplication(application)

Put the above in your project's wsgi.py.

Restart apache:

$ ../apache2/bin/restart
# Or, if using custom alias:
$ arest

And it couldn't hurt to reload your profile:

$ source ~/.bash_profile

Static files

THIS PART WAS COMPLETED IN ABOVE STEPS

Create a Static only (no .htaccess) app:

screen shot 2015-01-06 at 10 31 39 pm

And add it to your existing website (no trailing slash on /static:

screen shot 2015-01-06 at 10 31 39 pm

After a few minutes, you should be able to visit http://site.com/static

In your "common" or "base" settings file, use:

STATIC_ROOT = join(dirname(dirname(SITE_ROOT)), 'repower_static')

Next, run:

$ python manage.py collectstatic

Boom!

Note: You can use --dry-run to test collectstatic before anything gets copied.

Database

Assuming you already created that and have your secrets.py setup properly:

$ python manage.py migrate

User

Finally, create a super user so you can login to your admin:

$ python manage.py createsuperuser

… and follow on-screen instructions.

Other?

From here, it's a matter of pushing/pulling Git changes and running $ python manage.py migrate appname (on production) or $ python manage.py makemigrations appname (on local)!

WOOT!

Next, check out:

Clone this wiki locally