Docker镜像未运行,数据库错误:django.db.utils.OperationalError无法将主机名“postgres”转换为地址:名称或服务未知

vcirk6k6  于 2023-04-05  发布在  Docker
关注(0)|答案(3)|浏览(171)

因此,我设法使用docker-compose build在本地构建了我的Docker镜像,并将镜像推送到我的Docker Hub存储库。
现在我尝试让它在DigitalOcean上工作,这样我就可以托管它了。我已经提取了正确版本的图像,我正在尝试使用以下命令运行它:
root@my-droplet:~# docker run --rm -it -p 8000:8000/tcp mycommand/myapp:1.1(是,1.1)
但我很快就犯了这两个错误:
一个一个
这可能是由于我将我的应用程序(使用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

下面是我的Dockerfile:

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 %

我不确定下一步该尝试什么,但我觉得我犯了一个简单的错误。为什么此时连接被拒绝?

djmepvbi

djmepvbi1#

当你启动一个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

(The特定错误消息could not translate host name "postgres" to address提示Docker网络设置问题:数据库客户端容器与数据库服务器不在同一个网络上,因此主机名解析失败。与“连接拒绝”类型错误相反,这意味着一个容器正在寻找另一个容器,但数据库尚未运行或端口号错误。)
在你的docker build示例中,Dockerfile中的代码永远无法连接到数据库。在机械层面上,没有办法像我们在docker run中所做的那样将其连接到Docker网络。在概念层面上,构建镜像会产生可重用的工件;如果我将映像docker push到注册表,然后在不同的主机上docker run,则不会设置数据库,或者类似地,如果我删除并在本地重新创建数据库容器。

iovurdzv

iovurdzv2#

我尝试使用以下命令运行它: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

为什么此时连接被拒绝?
也许是因为它没有在正确的时间完成。
我不是DjangoMaven,但你的第二次尝试看起来不错,而你的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
在本节中,您将为Django设置数据库连接。
在项目目录中,编辑composeexample/settings.py文件。
将DATABASE =...替换为以下内容:

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
uurv41yg

uurv41yg3#

我很长一段时间没有接触我的Django应用程序,我运行python manage.py createsuperuser,然后得到

django.db.utils.OperationalError: could not translate host name "postgres" to address: Name or service not known ```

相反,我需要用

docker-compose exec [Your Django App] python manage.py createsuperuser

需要在容器中运行,那么它就可以工作了!

相关问题