我想运行带有dockerized postgres的dockerized Django应用。
我使用以下命令运行dockerized Django应用程序:
docker run --rm --env-file /path/to/variables -d -p 8000:8000 django_app:test
我使用以下命令运行dockerized postgres:
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'
我的postgres配置是postgres docker container documentation中建议的默认配置。它实际上是一个包含listen_addresses = '*'
我对两个容器都使用了相同环境变量:
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
我的数据库Django设置模块是:
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')
}
}
但是,我不断得到:
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?
我的django应用程序的Dockerfile看起来像:
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
另一个有趣的事实是,如果我在本地python manage.py runserver
上运行该应用程序并运行postgres容器,则该应用程序似乎可以正常工作。
谁能帮助我找出为什么我的连接被拒绝了吗?预先感谢!
答案 0 :(得分:1)
只需使用用户定义的桥接网络即可。首先,利用您的知识,阅读有关Docker中不同类型网络的简短说明:https://docs.docker.com/network/bridge/
第二,定义您自己的网络
docker network create foo
接下来,运行已连接到该网络的容器:
docker run --rm --env-file /path/to/variables -d --network foo django_app:test
docker run --rm -d ... --network foo postgres:alpine ...
两个命令--network foo
中的注意事项。另外,在这种情况下,您不需要公开端口-在用户定义的网络内,它是自动完成的:
连接到同一用户定义网桥网络的容器 自动将所有端口公开给彼此,而没有端口公开给 外面的世界。这允许容器化的应用程序进行通信 彼此之间轻松互通,而不会意外打开对 外部世界。
第三,使用--name bar
docker run ... --network foo --name my-django django_app:test ...
docker run ... --network foo --name my-postgres postgres:alpine ...
最后修复连接字符串-从localhost
更改为容器名称,例如my-postgres
:
...
POSTGRES_HOST=my-postgres
...
答案 1 :(得分:1)
在带有Django的docker容器中,没有在本地主机上运行的Postgres。您需要通过指定容器名称而不是localhost 来指向Postgres docker容器 另外,Postgres容器和您的应用程序必须位于同一网络中。参见https://docs.docker.com/network/
要创建网络,请运行:
docker network create --driver bridge my-network
要在网络中运行docker容器,请使用:
docker run --network my-network -it container_name
要使用Django在容器中设置Postgres,
POSTGRES_HOST=postgres-container-name
答案 2 :(得分:0)
在您的情况下,您未指定容器名称。设置POSTGRES_HOST=localhost
时,您要告诉django容器连接到自身。这自然会失败,因为django容器中没有Postgres服务器。
您的两个容器正在使用默认的bridge
网络(docker0)。在网桥网络中,容器名称用作主机名。
这意味着从django
容器中,您可以使用其名称作为主机名来访问postgres
容器。
要能够从您的Django应用连接到Postgres,您需要:
--name option
为容器命名。示例:docker run --rm --name mypostgresdb -d ... postgres:alpine -c ...
POSTGRES_HOST
env变量应接收 postgres 容器的名称作为值。示例:POSTGRES_HOST=mypostgresdb
要检查与您的postgres容器的连接,可以从django容器ping它。