无法使用Postgres,Docker Compose和Psycopg2将主机名“ db”转换为地址

时间:2018-08-08 15:43:19

标签: python postgresql docker docker-compose psycopg2

在一个文件夹中,我有3个文件:base.py,Dockerfile和docker-compose.yml。

base.py:

import psycopg2

conn = psycopg2.connect("dbname='base123' user='postgres' host='db' password='pw1234'")

Dockerfile:

FROM ubuntu:16.04

RUN apt-get update
RUN apt-get -y install python-pip
RUN apt-get update
RUN pip install --upgrade pip
RUN pip install psycopg2-binary

COPY base.py base.py

RUN python base.py

docker-compose.yml:

version: '3'
services:
  db:
    image: 'postgres:latest'
    expose:
      - "5432"
    environment:
      POSTGRES_PASSWORD: pw1234
      POSTGRES_DB: base123
  aprrka:
    build: .    
    depends_on:
      - db

运行docker-compose up后,出现以下错误:

Traceback (most recent call last):
  File "base.py", line 5, in <module>
conn = psycopg2.connect("dbname='base123' user='postgres' host='db' password='pw1234'")
   File "/usr/local/lib/python2.7/dist-packages/psycopg2/__init__.py", line 130, in connect
    conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
psycopg2.OperationalError: could not translate host name "db" to address: Name or service not known

ERROR: Service 'aprrka' failed to build: The command '/bin/sh -c python base.py' returned a non-zero code: 1

我不知道为什么会有这个错误。我暴露了端口5432。默认情况下,Compose为应用设置单个网络。每个服务都加入默认网络,我认为我的应用程序和postgres应该可以一起工作。我写错了docker-compose.yml吗?

6 个答案:

答案 0 :(得分:8)

在docker compose文件中添加网络,链接和Depends_on 配置。

类似这样的东西:

  services:
      db:
          build: .
          container_name: db
          networks:
              - djangonetwork
      web:
          build: .
          depends_on:
             - db
          links:
             - db:db
          networks:
             - djangonetwork

  networks:
      djangonetwork:
          driver: bridge

上面的配置帮助我解析了主机名以连接到数据库。

答案 1 :(得分:6)

如果将其添加到docker-compose.yml中的db容器中,它将解决此问题

WHERE (
    (([Production Table].[Production Date]) >=#7/1/2018#) 
    and ([Production Table].[Production Date]) < #" + yesterday + "#) 
    and [JITL NUMBER] = 60 

答案 2 :(得分:5)

问题是您不应该将python base.py作为RUN指令的一部分来运行。

RUN伪指令仅在构建映像时执行。 postgres容器目前尚未运行,也未创建网络。相反,您想使用CMD指令。

Dockerfile更改为此:

FROM ubuntu:16.04

RUN apt-get update
RUN apt-get -y install python-pip
RUN apt-get update
RUN pip install --upgrade pip
RUN pip install psycopg2-binary

COPY base.py base.py

CMD ["python", "base.py"]

以上内容将导致解析主机名db。但是,如果您的python代码没有用于连接数据库的任何重新连接逻辑,则该容器很可能仍会出错。这是因为postgres容器将在运行,但是数据库将无法接受连接。

可以通过在您的restart: always中添加docker-compose.yml来临时解决此问题。

version: '3'
services:
  db:
    image: 'postgres:latest'
    expose:
      - "5432"
    environment:
      POSTGRES_PASSWORD: pw1234
      POSTGRES_DB: base123
  aprrka:
    restart: always
    build: .    
    depends_on:
      - db

希望这会让您启动并运行。

答案 3 :(得分:5)

如果您使用的是docker-compose,请首先将此行添加到您的.yml:

environment:
  - "POSTGRES_HOST_AUTH_METHOD=trust"

此后,仅启动数据库docker:

docker-compose up db

它通常应以以下消息开头:

Recreating db... done
Attaching to db
db_1           | ********************************************************************************
db_1           | WARNING: POSTGRES_HOST_AUTH_METHOD has been set to "trust". This will allow
db_1           |          anyone with access to the Postgres port to access your database without
db_1           |          a password, even if POSTGRES_PASSWORD is set. See PostgreSQL
db_1           |          documentation about "trust":
db_1           |          https://www.postgresql.org/docs/current/auth-trust.html
db_1           |          In Docker's default configuration, this is effectively any other
db_1           |          container on the same system.
db_1           | 
db_1           |          It is not recommended to use POSTGRES_HOST_AUTH_METHOD=trust. Replace
db_1           |          it with "-e POSTGRES_PASSWORD=password" instead to set a password in
db_1           |          "docker run".
db_1           | ********************************************************************************

答案 4 :(得分:0)

将主机从“ db”更改为“ postgres”对我来说很有效。

还使用postgres默认的用户名和密码

username: postgres
password:

答案 5 :(得分:0)

另一种可能的情况,

检查端口是否已被其他Docker容器使用。 使用命令:

$ docker container ls --format "table {{.ID}}\t{{.Names}}\t{{.Ports}}" -a

然后在docker-compose文件中更改端口/暴露