62
votes

I'm new to heroku and gunicorn so I'm not sure how this works. But I've done some searching and I think I'm close to deploying my Django app (1.5.1). So I know I need a Procfile which has

web: gunicorn app.wsgi

Because my directories are a bit different. I can't run gunicorn in the root directory

app_project
    requirements/
    contributors/
    app/
        app/
            settings/
            wsgi.py
        # Normally Procfile goes here
    Procfile

Normally app/ would be the root directory, but I decided to structure my folders this way to separate my django app from some other things. Since I have to put the Procfile in the root directory for heroku to recognize it, what should I put in the Procfile and/or what parameters should I place in the gunicorn command?

Note:

web: gunicorn app.wsgi # won't work because Procfile is in a directory above
                       # I also want to keep the directories as is
                       # I also don't want to create a secondary git inside the app folder just for heroku
web: gunicorn app.app.wsgi # won't work because I don't want to convert the folder into a python module
4
I'm curious... why is it that you don't want add an init.py file to the top level app/ folder?eikonomega
I've tried to add __init__.py to the top level directory in the same project layout and it doesn't resolve all errors. Even though you pass the project import error, then there comes settings import error, because they are not in python path. So Graham's solution is the probably the best available.Serge Mosin

4 Answers

75
votes

Try:

web: gunicorn --pythonpath app app.wsgi
61
votes

As @Graham Dumpleton stated in his answer, the OP's problem could be solved by modifying his Procfile to the following:

web: gunicorn --pythonpath app app.wsgi

Why this works:

  • Remember, that the Procfile is simply used by Heroku to start processes. In this case, gunicorn processes.
  • Gunicorn's --pythonpath argument allows you to dynamically attach a directory to the list of directories that the Python runtime searches for when do module look-ups.
  • By adding --pythonpath app to the gunicorn command, the interpreter was basically told 'look inside of the app directory for a package (also) called app which contains a module called wsgi.`

The generic names of the folders in the OP's question can obscure the syntax of the command, which is as follows: gunicorn --pythonpath <directory_containing_package> <package>.<module>

More Info:
Gunicorn Documentation

6
votes

I made a ugly hack for getting this working. So I'm going to post my answer, but I hope you guys can come up with a better solution

Procfile

web: sh ./app/run.sh

app_project/app/run.sh

#!/bin/bash

cd app
gunicorn app.wsgi
4
votes

If your file is nested in folders, the following will make more sense.

Instead of adding the path to the PYTHONPATH environmental variable, instead I referenced it like you would reference modules in a package:

In my case, the app object was in a scriptC.py, inside folderB, which is inside the folderA.

web: gunicorn folderA.folderB.scriptC:app