Docker image not running, db error: django.db.utils.OperationalError could not translate host name "postgres" to address: Name or service not known
Docker image not running, db error: django.db.utils.OperationalError could not translate host name "postgres" to address: Name or service not known
所以我设法使用 docker-compose build
在本地构建了我的 Docker 图像,并将图像推送到我的 Docker Hub 存储库。
现在我正在尝试让它在 DigitalOcean 上运行,以便我可以托管它。我已经提取了正确版本的图像,我正在尝试使用以下命令 运行 它:
root@my-droplet:~# docker run --rm -it -p 8000:8000/tcp mycommand/myapp:1.1
(是的,1.1)
然而我很快运行陷入这两个错误:
...
File "/usr/local/lib/python3.8/dist-packages/django/db/backends/postgresql/base.py",
line 185, in get_new_connection
connection = Database.connect(**conn_params) File "/usr/local/lib/python3.8/dist-packages/psycopg2/__init__.py", line
127, in connect
conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
psycopg2.OperationalError: could not translate host name "postgres" to address: Name or service not known ```
...
File "/usr/local/lib/python3.8/dist-packages/django/db/backends/base/base.py",
line 197, in connect
self.connection = self.get_new_connection(conn_params) File "/usr/local/lib/python3.8/dist-packages/django/utils/asyncio.py", line
26, in inner
return func(*args, **kwargs) File "/usr/local/lib/python3.8/dist-packages/django/db/backends/postgresql/base.py",
line 185, in get_new_connection
connection = Database.connect(**conn_params) File "/usr/local/lib/python3.8/dist-packages/psycopg2/__init__.py", line
127, in connect
conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
django.db.utils.OperationalError: could not translate host name "postgres" to address: Name or service not known ```
这可能是由于我如何将我的应用程序(使用 docker-compose,yml
)划分为两个服务,并且自 以来只推送应用程序的图像。这是我的 docker-compose.yml
文件:
这是我的 docker-compose.yml 文件:
version: '3'
services:
db:
image: postgres
environment:
- POSTGRES_DB=postgres
- POSTGRES_USER=(adminname)
- POSTGRES_PASSWORD=(adminpassword)
- CLOUDINARY_URL=(cloudinarykey)
app:
build: .
ports:
- "8000:8000"
depends_on:
- db
这是我的Docker文件:
FROM (MY FRIENDS ACCOUNT)/django-npm:latest
RUN mkdir usr/src/mprova
WORKDIR /usr/src/mprova
COPY frontend ./frontend
COPY backend ./backend
WORKDIR /usr/src/mprova/frontend
RUN npm install
RUN npm run build
WORKDIR /usr/src/mprova/backend
ENV DJANGO_PRODUCTION=True
RUN pip3 install -r requirements.txt
EXPOSE 8000
CMD python3 manage.py collectstatic && \
python3 manage.py makemigrations && \
python3 manage.py migrate && \
gunicorn mellon.wsgi --bind 0.0.0.0:8000
这是我的 settings.py
文件的片段:
...
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'postgres',
'USER': 'admin',
'PASSWORD': '[THE PASSWORD]',
'HOST': 'db',
'PORT': 5432,
}
}
...
我该如何解决这个问题?我环顾四周,但看不出我做错了什么。
根据我在网上看到的,我将以下内容添加到我的项目中,但它也不起作用:
这是我的base.py
(新文件):
import psycopg2
conn = psycopg2.connect("dbname='postgres' user='admin' host='db' password='[THE PASSWORD]'")
对 Dockerfile
的补充:
FROM (MY FRIENDS ACCOUNT)/django-npm:latest
RUN pip3 install psycopg2-binary
COPY base.py base.py
RUN python3 base.py
...
但是构建由于以下错误而失败:
Traceback (most recent call last): File "base.py", line 3, in
<module>
conn = psycopg2.connect("dbname='postgres' user='admin' host='db' password='[THE PASSWORD]'")
File "/usr/local/lib/python3.8/dist-packages/psycopg2/__init__.py", line
127, in connect
conn = _connect(dsn, connection_factory=connection_factory, **kwasync) psycopg2.OperationalError: could not connect to server: Connection refused
Is the server running on host "db" ([SOME-IP-ADDRESS]) and accepting
TCP/IP connections on port 5432?
ERROR: Service 'app' failed to build: The command '/bin/sh -c python3 base.py' returned a non-zero code: 1
me@My-MacBook-Pro-5 mellon %
我不确定接下来要尝试什么,但我觉得我犯了一个简单的错误。为什么此时连接被拒绝?
I am trying to run it with the following command: root@my-droplet:~#
docker run --rm -it -p 8000:8000/tcp mycommand/myapp:1.1 (yes, 1.1)
Docker-compose 允许创建多个容器的组合。
运行 带有 docker run
的 django 容器违背了它的目的。
你想要的是 运行 :
docker-compose build
docker-compose up
或在单个命令中:
docker-compose up --build
Why is the connection being refused at the moment?
可能是因为时机不对。
我不是 Django 专家,但您的第二次尝试看起来不错,而您的 Django 服务在 compose 声明中缺少 Dockerfile 属性(我认为是输入错误)。
第一次尝试,出现错误:
django.db.utils.OperationalError: could not translate host name "postgres" to address: Name or service not known ```
意味着 django 使用“postgres”作为数据库的主机。
但是根据您的撰写,可以使用名为“db”的主机访问数据库。这些不匹配。
关于您定义数据库属性的第二次尝试,它看起来不错并且也符合 the official doc states :
In this section, you set up the database connection for Django.
In your project directory, edit the composeexample/settings.py file.
Replace the DATABASES = ... with the following:
settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'postgres',
'USER': 'postgres',
'PASSWORD': 'postgres',
'HOST': 'db',
'PORT': 5432,
} } These settings are determined by the postgres Docker image specified in docker-compose.yml.
第二次尝试,出现错误:
conn = _connect(dsn, connection_factory=connection_factory, **kwasync) psycopg2.OperationalError: could not connect to server: Connection refused
Is the server running on host "db" ([SOME-IP-ADDRESS]) and accepting
TCP/IP connections on port 5432?
可能意味着当 Django 尝试初始化连接时,Postgres DB 侦听器尚未准备好。
您的撰写属性:depends_on:
定义了容器启动的顺序,但不等待容器后面的应用程序“准备就绪”。
这里有两种方法可以解决这种情况:
- 在启动 django 服务之前添加几秒钟的睡眠
- 或者将您的 django compose conf 设置为在失败时重新启动。
对于第一种方式,使用 CMD 配置您的 django 服务,例如(未尝试):
app:
build: .
ports:
- "8000:8000"
depends_on:
- db
command: /bin/bash -c "sleep 30; python3 manage.py collectstatic && python3 manage.py makemigrations && python3 manage.py migrate && gunicorn mellon.wsgi --bind 0.0.0.0:8000 "
对于第二种方式,尝试类似的方法:
app:
build: .
ports:
- "8000:8000"
depends_on:
- db
restart: on-failure
当您启动 docker-compose.yml
文件时,Compose 会自动为您创建一个 Docker 网络并将容器附加到它。如果文件中没有任何特定的 networks:
声明,Compose 会将网络命名为 default
,然后 Compose 创建的大多数内容都以当前目录名称为前缀。此设置在 Networking in Compose.
中有更详细的描述
docker run
根本不查看 Compose 设置,因此您使用 docker run
手动执行的任何操作都需要复制 docker-compose.yml
已经或将自动生成的设置。要使 docker run
容器连接到 Compose 网络,您需要执行以下操作:
docker network ls # looking for somename_default
docker run \
--rm -it -p 8000:8000/tcp \
--net somename_default \ # <-- add this option
mycommand/myapp:1.1
(特定的错误消息 could not translate host name "postgres" to address
暗示 Docker 网络设置问题:数据库客户端容器与数据库服务器不在同一网络上,因此主机名解析失败。对比出现“连接被拒绝”类型错误,这表明一个容器正在寻找另一个容器,但数据库尚未 运行 或端口号错误。)
在您的 docker build
示例中,Docker 文件中的代码永远无法连接到数据库。在机械层面上,无法像我们对 docker run
所做的那样将其附加到 Docker 网络。在概念层面上,构建图像会产生可重用的工件;如果我 docker push
镜像到注册表并 docker run
它在不同的主机上,那将不会有数据库设置,或者类似地,如果我删除并在本地重新创建数据库容器。
所以我设法使用 docker-compose build
在本地构建了我的 Docker 图像,并将图像推送到我的 Docker Hub 存储库。
现在我正在尝试让它在 DigitalOcean 上运行,以便我可以托管它。我已经提取了正确版本的图像,我正在尝试使用以下命令 运行 它:
root@my-droplet:~# docker run --rm -it -p 8000:8000/tcp mycommand/myapp:1.1
(是的,1.1)
然而我很快运行陷入这两个错误:
... File "/usr/local/lib/python3.8/dist-packages/django/db/backends/postgresql/base.py", line 185, in get_new_connection connection = Database.connect(**conn_params) File "/usr/local/lib/python3.8/dist-packages/psycopg2/__init__.py", line 127, in connect conn = _connect(dsn, connection_factory=connection_factory, **kwasync) psycopg2.OperationalError: could not translate host name "postgres" to address: Name or service not known ```
... File "/usr/local/lib/python3.8/dist-packages/django/db/backends/base/base.py", line 197, in connect self.connection = self.get_new_connection(conn_params) File "/usr/local/lib/python3.8/dist-packages/django/utils/asyncio.py", line 26, in inner return func(*args, **kwargs) File "/usr/local/lib/python3.8/dist-packages/django/db/backends/postgresql/base.py", line 185, in get_new_connection connection = Database.connect(**conn_params) File "/usr/local/lib/python3.8/dist-packages/psycopg2/__init__.py", line 127, in connect conn = _connect(dsn, connection_factory=connection_factory, **kwasync) django.db.utils.OperationalError: could not translate host name "postgres" to address: Name or service not known ```
这可能是由于我如何将我的应用程序(使用 docker-compose,yml
)划分为两个服务,并且自 docker-compose.yml
文件:
这是我的 docker-compose.yml 文件:
version: '3'
services:
db:
image: postgres
environment:
- POSTGRES_DB=postgres
- POSTGRES_USER=(adminname)
- POSTGRES_PASSWORD=(adminpassword)
- CLOUDINARY_URL=(cloudinarykey)
app:
build: .
ports:
- "8000:8000"
depends_on:
- db
这是我的Docker文件:
FROM (MY FRIENDS ACCOUNT)/django-npm:latest
RUN mkdir usr/src/mprova
WORKDIR /usr/src/mprova
COPY frontend ./frontend
COPY backend ./backend
WORKDIR /usr/src/mprova/frontend
RUN npm install
RUN npm run build
WORKDIR /usr/src/mprova/backend
ENV DJANGO_PRODUCTION=True
RUN pip3 install -r requirements.txt
EXPOSE 8000
CMD python3 manage.py collectstatic && \
python3 manage.py makemigrations && \
python3 manage.py migrate && \
gunicorn mellon.wsgi --bind 0.0.0.0:8000
这是我的 settings.py
文件的片段:
...
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'postgres',
'USER': 'admin',
'PASSWORD': '[THE PASSWORD]',
'HOST': 'db',
'PORT': 5432,
}
}
...
我该如何解决这个问题?我环顾四周,但看不出我做错了什么。
根据我在网上看到的,我将以下内容添加到我的项目中,但它也不起作用:
这是我的base.py
(新文件):
import psycopg2
conn = psycopg2.connect("dbname='postgres' user='admin' host='db' password='[THE PASSWORD]'")
对 Dockerfile
的补充:
FROM (MY FRIENDS ACCOUNT)/django-npm:latest
RUN pip3 install psycopg2-binary
COPY base.py base.py
RUN python3 base.py
...
但是构建由于以下错误而失败:
Traceback (most recent call last): File "base.py", line 3, in <module> conn = psycopg2.connect("dbname='postgres' user='admin' host='db' password='[THE PASSWORD]'") File "/usr/local/lib/python3.8/dist-packages/psycopg2/__init__.py", line 127, in connect conn = _connect(dsn, connection_factory=connection_factory, **kwasync) psycopg2.OperationalError: could not connect to server: Connection refused Is the server running on host "db" ([SOME-IP-ADDRESS]) and accepting TCP/IP connections on port 5432? ERROR: Service 'app' failed to build: The command '/bin/sh -c python3 base.py' returned a non-zero code: 1 me@My-MacBook-Pro-5 mellon %
我不确定接下来要尝试什么,但我觉得我犯了一个简单的错误。为什么此时连接被拒绝?
I am trying to run it with the following command: root@my-droplet:~#
docker run --rm -it -p 8000:8000/tcp mycommand/myapp:1.1 (yes, 1.1)
Docker-compose 允许创建多个容器的组合。
运行 带有 docker run
的 django 容器违背了它的目的。
你想要的是 运行 :
docker-compose build
docker-compose up
或在单个命令中:
docker-compose up --build
Why is the connection being refused at the moment?
可能是因为时机不对。
我不是 Django 专家,但您的第二次尝试看起来不错,而您的 Django 服务在 compose 声明中缺少 Dockerfile 属性(我认为是输入错误)。
第一次尝试,出现错误:
django.db.utils.OperationalError: could not translate host name "postgres" to address: Name or service not known ```
意味着 django 使用“postgres”作为数据库的主机。
但是根据您的撰写,可以使用名为“db”的主机访问数据库。这些不匹配。
关于您定义数据库属性的第二次尝试,它看起来不错并且也符合 the official doc states :
In this section, you set up the database connection for Django.
In your project directory, edit the composeexample/settings.py file.
Replace the DATABASES = ... with the following:
settings.py
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'postgres', 'USER': 'postgres', 'PASSWORD': 'postgres', 'HOST': 'db', 'PORT': 5432, } } These settings are determined by the postgres Docker image specified in docker-compose.yml.
第二次尝试,出现错误:
conn = _connect(dsn, connection_factory=connection_factory, **kwasync) psycopg2.OperationalError: could not connect to server: Connection refused
Is the server running on host "db" ([SOME-IP-ADDRESS]) and accepting
TCP/IP connections on port 5432?
可能意味着当 Django 尝试初始化连接时,Postgres DB 侦听器尚未准备好。
您的撰写属性:depends_on:
定义了容器启动的顺序,但不等待容器后面的应用程序“准备就绪”。
这里有两种方法可以解决这种情况:
- 在启动 django 服务之前添加几秒钟的睡眠
- 或者将您的 django compose conf 设置为在失败时重新启动。
对于第一种方式,使用 CMD 配置您的 django 服务,例如(未尝试):
app:
build: .
ports:
- "8000:8000"
depends_on:
- db
command: /bin/bash -c "sleep 30; python3 manage.py collectstatic && python3 manage.py makemigrations && python3 manage.py migrate && gunicorn mellon.wsgi --bind 0.0.0.0:8000 "
对于第二种方式,尝试类似的方法:
app:
build: .
ports:
- "8000:8000"
depends_on:
- db
restart: on-failure
当您启动 docker-compose.yml
文件时,Compose 会自动为您创建一个 Docker 网络并将容器附加到它。如果文件中没有任何特定的 networks:
声明,Compose 会将网络命名为 default
,然后 Compose 创建的大多数内容都以当前目录名称为前缀。此设置在 Networking in Compose.
docker run
根本不查看 Compose 设置,因此您使用 docker run
手动执行的任何操作都需要复制 docker-compose.yml
已经或将自动生成的设置。要使 docker run
容器连接到 Compose 网络,您需要执行以下操作:
docker network ls # looking for somename_default
docker run \
--rm -it -p 8000:8000/tcp \
--net somename_default \ # <-- add this option
mycommand/myapp:1.1
(特定的错误消息 could not translate host name "postgres" to address
暗示 Docker 网络设置问题:数据库客户端容器与数据库服务器不在同一网络上,因此主机名解析失败。对比出现“连接被拒绝”类型错误,这表明一个容器正在寻找另一个容器,但数据库尚未 运行 或端口号错误。)
在您的 docker build
示例中,Docker 文件中的代码永远无法连接到数据库。在机械层面上,无法像我们对 docker run
所做的那样将其附加到 Docker 网络。在概念层面上,构建图像会产生可重用的工件;如果我 docker push
镜像到注册表并 docker run
它在不同的主机上,那将不会有数据库设置,或者类似地,如果我删除并在本地重新创建数据库容器。