【问题标题】:Connect to database through docker通过docker连接数据库
【发布时间】:2021-06-21 20:47:41
【问题描述】:

我知道这是一个有很多答案的问题,但我尝试过的方法都没有解决我的问题。 我正在使用这个 Dockerfile 创建一个测试数据库:

FROM postgres
ENV POSTGRES_USER postgres
ENV POSTGRES_PASSWORD postgres
ENV POSTGRES_DB training_db
COPY create_test_database.sql /docker-entrypoint-initdb.d/
docker build -t my-postgres-image .
docker run -d --name training-db my-postgres-image
docker start training-db

创建并启动后,我可以通过 dbeaver 访问它,但不能从另一个项目访问它,Dockerfile 看起来像这样:

FROM 613615412341.dkr.ecr.ap-southeast-2.amazonaws.com/cv-image:latest

ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=Europe/Minsk
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

RUN apt-get update && apt-get install -y \
        python3-dev \
        python3-tk \
        python3-pip \
        libglib2.0-0\
        libsm6 \
        postgresql-server-dev-all \
        postgresql-common \
        openssh-client \
        libxext6 \
        nano \
        pkg-config \
        rsync \
        && \
    apt-get clean && \
    apt-get autoremove && \
    rm -rf /var/lib/apt/lists/*

RUN apt update && apt install -y git pkg-config libgl1-mesa-glx tcl libopencv-dev python-opencv

RUN pip3 install  --upgrade  setuptools
RUN pip3 install numpy
ADD requirements.txt /requirements.txt
RUN pip3 install -r /requirements.txt && rm /requirements.txt

ENV LC_ALL=C.UTF-8
ENV LANG=C.UTF-8

ADD . /code
WORKDIR /code

RUN echo $(ip -4 route list match 0/0 | cut -d' ' -f3)

使用 docker-compose:

  version: '2.3'
  services:
    training_pipeline:
      build:
        context: .
        dockerfile: Dockerfile.service
      runtime: nvidia
      environment:
        - AWS_DEFAULT_REGION=ap-southeast-2
        - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}
        - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}

      network_mode: host
      ports:
        - "5432:5432"
      entrypoint: ["python3", "main.py"]
   training-db:
     image: postgres
     environment:
       POSTGRES_PASSWORD: postgres
       POSTGRES_USER: postgres
       POSTGRES_DB: training_db
     volumes:
       - postgres:/var/lib/postgresql/data
  volumes:
    postgres:

但是,我不断得到:

training_pipeline_1  |     args.func(args)  # call the default function
training_pipeline_1  |   File "/code/functions.py", line 46, in label_batch
training_pipeline_1  |     pre_labeling = PreLabeling(site, connection_config, detector_config)
training_pipeline_1  |   File "/code/pre_label/label.py", line 43, in __init__
training_pipeline_1  |     connection_config, set_isolation_level=True, set_profiles=True
training_pipeline_1  |   File "/code/helpers/data_base_connection.py", line 37, in __init__
training_pipeline_1  |     database=config["database"],
training_pipeline_1  |   File "/usr/local/lib/python3.6/dist-packages/psycopg2/__init__.py", line 127, in connect
training_pipeline_1  |     conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
training_pipeline_1  | psycopg2.OperationalError: could not connect to server: Connection refused
training_pipeline_1  |  Is the server running on host "172.17.0.1" and accepting
training_pipeline_1  |  TCP/IP connections on port 5432?

这是我的数据连接器类的一个 sn-p(跳过不必要的方法):

import logging
from typing import Any, Dict, List, Optional

import psycopg2




class DataBaseConnection:
    """
    Class to perform transactions with training database.
    """


    def __init__(
        self,
        config: dict,
    ):
        """
        Args:
            config: configuration file to connect to the database where annotations are stored.
        """
        self._connection = psycopg2.connect(
            user=config["user"],
            password=config["password"],
            host=config["host"],
            port=config["port"],
            database=config["database"],
        )
        self._cursor = None
        self._next = None

if __name__=="__main__":
    config = {
       "database": "training_db",
       "host": "172.17.0.1",
       "password": "postgres",
       "port": 5432,
       "user": "postgres"
    }
    data_connector: DataBaseConnection = DataBaseConnection(
        config
    )
    

【问题讨论】:

    标签: python postgresql docker


    【解决方案1】:

    如我所见,您有 2 个容器

    • 一个用于数据库 (training-db)
    • 一个用于应用程序(培训管道)

    Docker-compose 允许您在同一网络中运行多个容器,它为您创造了奇迹。最简单的方法是更新 docker-compose 以包含数据库:

    版本:'2.3'
    服务:
      培训管道:
        建造:
          语境: 。
          dockerfile: Dockerfile.service
        运行时:英伟达
        环境:
          - AWS_DEFAULT_REGION=ap-southeast-2
          - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}
          - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}
    
        网络模式:主机
        端口:
          - “5432:5432”
        入口点:[“python3”,“main.py”]
      训练数据库:
        图片:postgres
        环境:
          POSTGRES_PASSWORD:我的密码
          POSTGRES_USER:我的用户
          POSTGRES_DB:mydb
        卷:
          - postgres:/var/lib/postgresql/data
    
    卷:
      postgres:
    

    您可以使用以下命令启动数据库:docker-compose up -d training-db。 而且,在 python 中,数据库将通过 DNS training-db 提供。

    另一种解决方案是手动创建网络并在网络内运行您的容器:

    docker network create training-network
    docker run -d --name training-db --net training-network my-postgres-image
    

    并且,在 docker-compose 文件中,将网络添加为外部(别名,不由 compose 管理):

    version: '2.4'
    services:
      training_pipeline:
        [...]
        networks:
          - training-network
    
    networks:
      training-network:
        external: true
    

    【讨论】:

    • 嗨@jmaitrehenry。首先,感谢您的回答。我没有理解“你有一个容器”的意思,因为我有两个不同的 docker 文件,正如你在第一段中所说的那样:一个用于应用程序,一个用于创建数据库。
    • 啊,是的,我只看到您的 docker-compose 仅​​包含一个容器,并且您在 docker 映像中安装了一些 postgres 工具(如 postgresql-common 和 postgresql-server-dev-all)。我会更新我的答案
    • 是的,它也不起作用。仍然得到同样的错误。
    • @pceccon 可以在尝试连接数据库时添加代码 sn-p 吗?并添加新的 docker-compose 文件来帮助你。
    猜你喜欢
    • 2022-11-11
    • 1970-01-01
    • 2019-07-10
    • 2017-06-14
    • 2012-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-25
    相关资源
    最近更新 更多