Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.5k views
in Technique[技术] by (71.8m points)

django - Could not connect to postgres server in a docker from a dockerized app

I would like to run a dockerized Django app with a dockerized postgres.

I run the dockerized Django app by using:

docker run --rm --env-file /path/to/variables -d -p 8000:8000 django_app:test

I run a dockerized postgres by using:

docker run --rm -d --env-file /path/to/secrets/variables -p 5432:5432 
    -v "$PWD/my-postgres.conf":/etc/postgresql/postgresql.conf 
    --mount src=/path/to/db/data,dst=/var/lib/postgresql/data,type=bind 
    postgres:alpine -c 'config_file=/etc/postgresql/postgresql.conf'

my postgres config is the default config that is suggested in the postgres docker container documentation. It is essentially a config file that contains listen_addresses = '*'

I use the same environment variables for both containers:

DJANGO_SETTINGS_MODULE=settings.module
PROJECT_KEY=xxyyzzabcdefg
DB_ENGINE=django.db.backends.postgresql
POSTGRES_DB=db_name
POSTGRES_USER=db_user
POSTGRES_PASSWORD=verydifficultpassword
POSTGRES_HOST=localhost # I've also tried to use 0.0.0.0
POSTGRES_PORT=5432

My Django settings module for the database is:

 DATABASES = {
    'default': {
        'ENGINE': os.environ.get('DB_ENGINE'),
        'NAME': os.environ.get('POSTGRES_DB'),
        'USER': os.environ.get('POSTGRES_USER'),
        'PASSWORD': os.environ.get('POSTGRES_PASSWORD'),
        'HOST': os.environ.get('POSTGRES_HOST'),
        'PORT': os.environ.get('POSTGRES_PORT')
        }
  }

However, I keep on getting:

django.db.utils.OperationalError: could not connect to server: Connection refused
    Is the server running on host "0.0.0.0" and accepting
    TCP/IP connections on port 5432?

The Dockerfiles for my django app looks like:

FROM python:alpine3.7
COPY --from=installer /app /app
# required for postgres
COPY --from=installer /usr/lib /usr/lib
COPY --from=installer /usr/local/bin /usr/local/bin
COPY --from=installer /usr/local/lib /usr/local/lib
ARG SETTINGS_MODULE
WORKDIR /app
ENTRYPOINT python manage.py migrate &&
           python manage.py test &&
           python manage.py create_default_groups &&
           python manage.py set_screen_permissions &&
           python manage.py create_test_users &&
           python manage.py init_core &&
           python manage.py runserver 0.0.0.0:8000

Another interesting fact is that if I run the app locally python manage.py runserver and have the postgres container running, the app seems to be working.

Can anyone help me try to figure out why am I getting a connection refused? Thanks in advance!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Just make use of user-defined bridge networking. First, leverage your knowledge with reading a short explanation of different types of networks in Docker: https://docs.docker.com/network/bridge/

Second, define your own network

docker network create foo

Next, run your containers connected to this network:

docker run --rm --env-file /path/to/variables -d --network foo django_app:test
docker run --rm -d ... --network foo postgres:alpine ...

Notice in both commands --network foo. Also you dont need to expose ports in this case - inside user-defined networks it is done automatically:

Containers connected to the same user-defined bridge network automatically expose all ports to each other, and no ports to the outside world. This allows containerized applications to communicate with each other easily, without accidentally opening access to the outside world.

Third, give your containers human readable host names with --name bar

docker run ... --network foo --name my-django django_app:test ...
docker run ... --network foo --name my-postgres postgres:alpine ...

And finally fix the connection string - change from localhost to container name, like my-postgres:

...
POSTGRES_HOST=my-postgres
...

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...