Heroku, Debian, Python3, Django and Mezzanine

Ok, to start, is this ready for prime-time?
No, it's still Beta/Testing.
Because of the conflict with Boto and Python3, I would not recommend Python3 on Heroku at this time. A big part is Debian's "stability" or lag behind current packages. Might be worth trying on Ubuntu or Mint.

So, Postgres and Python3 on Debian?
No. Postgres is LATIN1 by default on Debian, not lang_UTF-8. I'm pretty sure this is a LC_LANG setting error, so I "dpkg-reconfigure locales" and it still didn't work. ("python3 manage test" throws a UTF-8 error)

So Mezzanine?
Looks nice, pity it is not really being tested, you need to get the fundamentals right first.

Please replace; myapp, db_user, db_name.db, somthinglongandrandom and bucketname with your values.

These are my changes to the Heroku Python2 setup.

Debian and Python3

By default Debian comes with Python 2.7, I wanted 3.3. Why? Because around Christmas I believe we went past 2->3 tipping point. I also wanted to do this and then forget it for a while, this is much easier if your dependancies are as new as possible.

So to start I installed (updated) python3.3 and pip. Because the package splitting in Debian I had to update pip. I could have just used pip3 all the time but that is a pain.

sudo apt-get install python3.3 python3-pip

sudo pip3 install -U pip

This takes the python2 pip and upgrades it within python3, which makes pip3 the default and called as pip.

Pip

The I hit the first problem, "python3 -m venv myapp" wants to alter root dirs, Debian doesn't like this. That right, on Debian the default behaviour is to effect the system outside the virtual environment! This is probably a Debian "feature".

So no venv.

Then I installed the packages I wanted,

sudo pip install mezzanine gunicorn pillow future static3 urllib3

created a project,

django-project myapp

and tweaked the settings in settings.py

ADMINS = (
    ('Your Name', 'your_email@domain.com'),
)
MANAGERS = ADMINS

ALLOWED_HOSTS = ['*']

TIME_ZONE = "Australia/Sydney"

and a few local_settings.py

    "ENGINE": "django.db.backends.postgresql_psycopg2",
    # DB name or path to database file if using sqlite3.
    "NAME": "db_name.db",
    # Not used with sqlite3.
    "USER": "db_user",
    # Not used with sqlite3.
    "PASSWORD": "somthinglongandrandom",

Asside : I use urandom to generate my passwords. [:graph:] can cause problems with special characters so if you use graph you have to check for ' " $ and any other problem character in Bash/Postgres.

tr -dc [:alnum:]< /dev/urandom | head -c 32 | xargs -0
or
genpasswd() {
    local l=$1
    [ "$l" == "" ] && l=32
    tr -dc [:graph:] < /dev/urandom | head -c ${l} | xargs -0
}

TODO : mezzanine app and django container!

Debian and Postgres

Then I installed postgres on Debian and used --user to 'install' it with pip not messing with Debian users or Debian's directory layout.

apt-get install postgresql-9.3 postgresql-client-9.3 postgresql-client-common python3-psycopg2 postgresql-contrib

pip install --user psycopg2

you then need to

sudo su - postgres 

createuser db_user -dPRs
createdb --owner db_user db_name.db

and edit you setting.py (different to Heroku site docs, https://pypi.python.org/pypi/django-herokuapp)

import dj_database_url
DATABASES = {
    "default": dj_database_url.config(default='postgres://localhost'),
}

BEFORE

$ python3 manage.py createdb
$ python3 manage.py syncdb

Heroku settings and changes.

Set runtime

cat > runtime.txt
python-3.3.3

pip freeze > requirements.txt

point git to the app

vi .git/config
[remote "heroku"]
        url = git@heroku.com:myapp.git
        fetch = +refs/heads/*:refs/remotes/heroku/*

Once these are working check with foreman start. I had to set DATABASES = {} in setting.py locally for this to work but Heroku needs it set as above.

Then you push and sync locally and remotely

git push heroku master
python3 manage.py 
syncdb python3 migrate

heroku run python3 manage.py syncdb
heroku run python3 manage.py migrate

Django, staticfiles and Boto.

Ok, Heroku doesn't want you using up valuable disk space with static files, so suggests to not use a ./static directory but AWS S3. This is fine for Python 2 but for python 3, boto throws sufficient errors to break your app. I've looked into static3 and dj-static/botocore but haven't finalised a solution. My workaround is making your S3 container anonymously readable and direct linking by editing your setting.py

STATIC_URL = "https://s3.amazonaws.com/bucketname/"

I'm still looking for a good solution for this.

Well I have a working app on heroku with a number of TODO's and bugs still in the works.

Michael - 20140318

http://michal.karzynski.pl/blog/2013/06/09/django-nginx-gunicorn-virtualenv-supervisor/
http://www.appneta.com/blog/s3-list-get-bucket-default/