Search code examples
djangoheroku

Docker + Django + Postgres Add-on + Heroku


So I'm running through the following:

  • Created a Dockerfile and a docker-compose.yml to develop a django app locally, nothing to do here, everything works just fine.

  • Dockerfile

    FROM python:3
    ENV PYTHONUNBUFFERED 1
    RUN mkdir /code
    WORKDIR /code
    ADD requirements.txt /code/
    RUN pip install -r requirements.txt
    ADD . /code/

  • All it does is fetches python3 image, copies the code from my source folder to the docker image

  • Then I'm trying to deploy this to heroku, so I added postgres add-on on heroku apps, and configured it using dj_database_url, with the following command on my settings.py file : DATABASES = {} DATABASES['default'] = dj_database_url.config()

  • After that I pushed my application to heroku using heroku container:push web and it got pushed to my app no problem at all...

  • The final piece is when I open my application using heroku open it says I got an error: Application error An error occurred in the application and your page could not be served. If you are the application owner, check your logs for details.

  • This is what get printed on the heroku website

  • Now, when I log using heroku logs -t, it says that exited with code 0, then it crashes

What am I missing?

  • Plus: when I run heroku run web python manage.py migrate it migrates the data on the heroku app
  • Plus 2: when I run heroku run web python manage.py runserver it says is running on 127.0.0.1:8000

EDIT 1: If you want to reproduce the problem you can clone all my code in the following git repo: https://github.com/giovanniKleinCampigoto/djangoherokuproblem.git

EDIT 2:

In this official tutorial: https://devcenter.heroku.com/articles/deploying-python , says to use virtualenv, but I'm using docker, so I don't really know how to proceed...

EDIT 3: Also, I noticed that when I push the image to heroku using: heroku container:push web, the server re-deploys, but instead of running whatever is on the procfile it just logs this: Starting process with command python3]

EDIT 4: When running heroku local web, and editing the Procfile to run docker-compose up works just fine, the problem is with the upload to heroku's server...not sure if I should edit the file to just python manage.py runserver...

docker-compose.yml

version: '2'

services:
  web:
    build: .
    env_file: composeexample/.env
    command: python3 manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/code
    ports:
      - "8000:8000"

Solution

  • Since I did not receive any answers to this I'm answering my own question, so others can use my solution...

    Ok so after a lot of testing, coming and goings I have discovered the problem.

    So what happened was the following: for local development you should use docker-compose, mount volumes and all that yummy stuff, however when going on production with heroku you need to set a command for server starting. So if you ever plan to setup a project with docker + django + postgres add-on on heroku. Do the following steps.

    First off:

    DATABASES = {}

    DATABASES['default'] = dj_database_url.config(default='DATABASE_URL')

    • This DATABASE_URL is a environment variable that you can get in your heroku app, go to your dashboard on heroku, find your app, go to settings, and Config Variables, click on reveal, and you should get the DATABASE_URL, the default variable is needed to /admin on django work...(This is only a work around, you should find a way to get the DATABASE_URL from a environment var)
    • Modify your Dockerfile to run the command to put the django server up adding to the last line: CMD python3 manage.py runserver 0.0.0.0:$PORT
    • The $PORT variable is the application port provided by heroku, so your application can run
    • Last but not least add your heroku app url to ALLOWED_HOSTS, as our friend Alejandro Sánchez said
    • And you're golden, your application should be running at the heroku app url

    EDIT 1:

    You don't need gunicorn as a dependency, the only command you should have in your Procfile is: web: python3 manage.py runserver

    EDIT 2

    As user: https://stackoverflow.com/users/1949328/sam pointed out runserver should not be ran in the PRODUCTION environment, use it at your own risk THIS SHOULD ONLY BE USED TO SETUP SOME SMALL TEST PROJECT.