Docker Community Forums

Share and learn in the Docker community.

Docker-compose django and postgresql


(Michiel van Es) #1

Hello,

I am trying to hook my django app to my postgresql container.
I confirmed that the container of my django app (ironman) can resolve the pgsql-container (db2) and connect to it via nc -vv db2 5432 by using the sqlite database by default to start the container.
If I change my settings.py to something like this:

Database Configuration

DATABASES = {
‘default’: {
‘ENGINE’: ‘django.db.backends.postgresql_psycopg2’,
‘NAME’: ‘djangodb’,
‘USER’: ‘djangoadm’,
‘PASSWORD’: ‘******’,
‘HOST’: ‘db2’,
‘PORT’: ‘5432’,
}
}

I get the following error during the build of the django app (ironman) container:

    self.connection = self.get_new_connection(conn_params)

File “/usr/local/lib/python2.7/dist-packages/django/db/backends/postgresql_psycopg2/base.py”, line 176, in get_new_connection
connection = Database.connect(**conn_params)
File “/usr/lib/python2.7/dist-packages/psycopg2/init.py”, line 179, in connect
connection_factory=connection_factory, async=async)
django.db.utils.OperationalError: could not translate host name “db2” to address: Name or service not known

And all other builds stop during the docker-compose build && docker-compose up.

My docker-compose.yml:

nginx:
restart: always
build: /usr/local/docker-builds/IRONMAN/nginx-container
links:
- letschat
- ironman
ports:
- “80:80”
- "443:443"
db2:
restart: always
build: /usr/local/docker-builds/IRONMAN/pgsql-container
ports:
- "5432:5432"
ironman:
restart: always
build: /usr/local/docker-builds/IRONMAN/ironman-container
links:
- db2
ports:
- "3031:3031"
letschat:
restart: always
build: /usr/local/docker-builds/IRONMAN/lets-chat
links:
- db:db
ports:
- "5000:5000"
db:
restart: always
image: mongo:latest
ports:
- “27017:27017”

If I use the sqlite database it will work (since it runs in the same container) but if I want to link my django app (ironman) to my pgsql container (db2) it can not resolve it.
I can resolve it when using the sqlite database.

I am guessing that since I am using docker-compose build && docker-compose up it first tries to build the containers succesfully and THEN start the containers and sqlite will work and the resolve will work since the containers are started with the correct linked hostnames.
If the build is running and the pgsql container is not started, the manage.py syncdb command will not able to resolve the db2 hostname.

Following https://docs.docker.com/compose/django/ expects that the syncdb is done after both containers are succesfully started and thus being able to resolve.

How can I solve this or what am I doing wrong?

Cheers,

Michiel


(Michiel van Es) #2

To answer to my own problem: I am guessing I have to manually run the syncdb and create admin command AFTER both containers are started.
Or I could create an AT job that fires after 1 minute after the containers have been started.
I do find it curious that for example the lets-chat container is able to start succesful with a mongodb but that is perhaps because it does not run any db related stuff during the build.


(Michiel van Es) #3

I got it!

Instead of running CMD ["/usr/bin/supervisor"] I run CMD ["/root/startup.sh"] which contains:

cd /home/django/ironman
python manage.py syncdb --noinput
python manage.py collectstatic --noinput
echo “from django.contrib.auth.models import User; User.objects.create_superuser(‘admin’, ‘admin@example.com’, ‘pass’)” | python manage.py shell 1>/dev/null 2>&1
/usr/bin/supervisord

Now my database tables are created, admin user added and supervisord takes care of the rest.
Since I export the pgsql port I can pgdump the content of the database and always restore my django app contents (app + db dump are on the host).

It was a bit tricky to find a correct way of doing it but the only thing I have to do is ‘docker-compose up’ and be done with it :smile:

Nice!