psycopg2无法连接到dockerized Python-Flask应用程序中的postgres数据库

时间:2019-07-07 16:48:50

标签: postgresql docker flask sqlalchemy psycopg2

我正在一个Python-Flask项目中,该项目有一个用于Web应用程序的docker容器和另一个用于postgres数据库的docker容器。我使用virtualenv来管理所有依赖项。在安装psycopg2时遇到了一些初始问题之后,我现在安装了所有依赖项。 但是,每当我尝试从命令行运行psycopg2时,都会出现flask db migrate错误。看到以下错误的摘要:

File "/home/myuser/Workspace/GroupName/MyApp/env/lib/python3.7/site-packages/psycopg2/__init__.py", line 126, in connect
    conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
psycopg2.OperationalError: could not translate host name "postgres" to address: Temporary failure in name resolution


The above exception was the direct cause of the following exception:
  File "/home/myuser/Workspace/GroupName/MyApp/env/lib/python3.7/site-packages/psycopg2/__init__.py", line 126, in connect
    conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) could not translate host name "postgres" to address: Temporary failure in name resolution

这是我的docker-compose.yml

services:
 postgres:
   restart: always
   image: postgres:latest
   environment:
     POSTGRES_USER: MyApp
     POSTGRES_PASSWORD: fakepassword
     POSTGRES_DB: MyApp-dev
   volumes:
     - ./container_data/postgres:/var/lib/postgresql/data
   ports:
     - "5432:5432"

 web:
   restart: always
   build:
      context: .
      args:
      - DOCKER_BUILD_ENV
      dockerfile: ./dockerfiles/web/Dockerfile
   environment:
     AWS_ACCESS_KEY_ID: "${AWS_ACCESS_KEY_ID}"
     AWS_SECRET_ACCESS_KEY: "${AWS_SECRET_ACCESS_KEY}"
     AWS_DEFAULT_REGION: "${AWS_DEFAULT_REGION}"
     S3_BUCKET_NAME: "${S3_BUCKET_NAME}"
     APPROVE_REGISTRATIONS: "${APPROVE_REGISTRATIONS}"
     FLASK_APP: app
     FLASK_ENV: "${FLASK_ENV:-development}"
   volumes:
     - ./MyApp/:/usr/src/app/MyApp/:z
   links:
     - postgres:postgres
   expose:
     - "3000"
   command: scripts/entrypoint.sh
   ports:
     - "3000:3000"

以下是dockerfile中与requirements.txt和数据库相关的摘录。

.....
RUN pip3 install --no-cache-dir virtualenv
RUN virtualenv /ve
ENV PATH=/ve/bin:$PATH
........

USER www-data

COPY requirements.txt dev-requirements.txt /usr/src/app/
RUN pip3 install --no-cache-dir -r requirements.txt

ARG DOCKER_BUILD_ENV
RUN test "${DOCKER_BUILD_ENV}" = production || pip3 install --no-cache-dir -r dev-requirements.txt

CMD ["/bin/bash"]
COPY package.json /usr/src/app/
RUN yarn

COPY create_db.py test_data.py /usr/src/app/
EXPOSE 3000

ENV PATH="/usr/src/app/geckodriver:${PATH}"
ENV SECRET_KEY *************
ENV SQLALCHEMY_DATABASE_URI postgresql://MyApp:fakepassword@postgres/MyApp-dev

WORKDIR /usr/src/app/MyApp

CMD ["scripts/entrypoint.sh"]

这里是entrypoint.sh。我不认为这会导致错误,因为我从命令行而不是从此脚本运行flask db migrate时遇到了错误。

#!/bin/bash
if [ "${DOCKER_BUILD_ENV:-}" == "production" ]; then
    flask run --host=0.0.0.0 --port=3000
else
    yarn build
    yarn watch &
    flask run --host=0.0.0.0 --port=3000
fi

我查找了类似的问题,例如psycopg2 can't see my PostgreSQL instance,但是我的代码中没有任何地方明确使用psycopg2创建连接。最接近的是位于models.py顶部的位置,

db = SQLAlchemy()

我运行了docker ps,并确认两个服务都在运行。

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
a1e6891161d1        myapp_web   "scripts/entrypoint.…"   57 minutes ago      Up 57 minutes       0.0.0.0:3000->3000/tcp   myapp_web_1
bfa83d282ac7        postgres:latest     "docker-entrypoint.s…"   2 weeks ago         Up 57 minutes       0.0.0.0:5432->5432/tcp   myapp_postgres_1

有什么想法为什么我在virtualenv中不能从命令行运行flask db migrateflask db stamp head

1 个答案:

答案 0 :(得分:0)

docker-library/postgres GitHub issues #681中报告了一个重大更改,导致了这一情况。我的解决方案是按照docker日志中的说明进行操作:

   Error: Database is uninitialized and superuser password is not specified.
   You must specify POSTGRES_PASSWORD for the superuser. Use
   "-e POSTGRES_PASSWORD=password" to set it in "docker run".

   You may also use POSTGRES_HOST_AUTH_METHOD=trust to allow all connections
   without a password. This is *not* recommended. See PostgreSQL
   documentation about "trust":
   https://www.postgresql.org/docs/current/auth-trust.html

在docker compose中,我添加了以下环境变量:

  postgres:
    restart: always
    image: postgres:latest
    environment:
      POSTGRES_HOST_AUTH_METHOD=trust
    ports:
      - "5432:5432"

后一个环境变量允许任何人连接到数据库,因此建议设置密码,因为这是不安全的解决方法。