pythondjangopostgresqldockeraptible

How to connect a Docker container to PostgreSQL running on the localhost using a DATABASE_URL?


I'm following the Aptible Django Quickstart Tutorial which described how to create and deploy an app Aptible's PaaS. I would also like to be able to run the Docker container with the Django app locally and connect to a local PostgreSQL database, however, and it is unclear to me how to do this.

The Dockerfile for the Django app is:

FROM python:3.6

# System prerequisites
RUN apt-get update \
 && apt-get -y install build-essential libpq-dev \
 && rm -rf /var/lib/apt/lists/*

# If you require additional OS dependencies, install them here:
# RUN apt-get update \
#  && apt-get -y install imagemagick nodejs \
#  && rm -rf /var/lib/apt/lists/*

# Install Gunicorn. If Gunicorn is already present in your requirements.txt,
# you don't need that (but if won't hurt).
RUN pip install gunicorn

ADD requirements.txt /app/
WORKDIR /app
RUN pip install -r requirements.txt

ADD . /app

EXPOSE 8000

CMD ["gunicorn", "--access-logfile=-", "--error-logfile=-", "--bind=0.0.0.0:8000", "--workers=3", "mysite.wsgi"]

where mysite is the name of the Django app. Its settings.py uses dj-database-url as follows:

import dj_database_url
DATABASES = {'default': dj_database_url.config()}

In order to connect to a local instance of PostgreSQL, it would seem I should follow the Docker for Mac Solution on Allow docker container to connect to a local/host postgres database:

docker run -e DB_PORT=5432 -e DB_HOST=docker.for.mac.host.internal

However, if I try this I still get an error ending with

  File "/usr/local/lib/python3.6/site-packages/psycopg2/__init__.py", line 130, in connect
    conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
django.db.utils.OperationalError: could not connect to server: Connection refused
    Is the server running on host "localhost" (127.0.0.1) and accepting
    TCP/IP connections on port 5432?
could not connect to server: Cannot assign requested address
    Is the server running on host "localhost" (::1) and accepting
    TCP/IP connections on port 5432?

It would seem to me that the app as currently configured is not 'doing anything' with the DB_PORT and DB_HOST environment variables, because it is reading these in one go from the DATABASE_URL. Is this the problem? If so, how could I fix this while still using DATABASE_URL as this appears to be the 'interface' to Aptible?


Solution

  • I managed to fix the problem by changing the DATABASE_URL in the .env file from

    DATABASE_URL=postgres://my_app:my_password@localhost/my_database
    

    to

    DATABASE_URL=postgres://my_app:my_password@docker.for.mac.host.internal/my_database
    

    and running the container, which I tagged lucy_web, like so:

    docker run -p 8000:8000 --env-file .env lucy_web
    

    It was not necessary to change listen_addresses to '*' in my postgresql.conf; this was still at its default, localhost. (I believe this is because the -p 8000:8000 argument maps port 8000 on localhost to the container).