无法连接到Python Shell外部的Docker容器中的postgres

时间:2019-02-03 16:24:45

标签: python-3.x postgresql docker psycopg2

我无法在Python外壳之外的Docker容器中连接到Postgres映像。

我有一个脚本,该脚本下载并推出Postgres Docker映像。步骤之一是,我想在数据库中创建一些表。

如果我运行setup.py,它将下载映像并将Docker容器安装在本地计算机上并等待连接。如果接下来,我将打开Python Shell并尝试连接到数据库-一切正常。

我的Dockerfile

FROM postgres:11.1
RUN apt-get update
EXPOSE 5432
ENV POSTGRES_DB monitoring
ENV POSTGRES_USER process_monitor

我的setup.py文件:

import subprocess
import psycopg2


def update_apt():
    subprocess.run(['sudo', 'apt-get', '-y', 'update'])

def install_docker():
    subprocess.run(['sudo', 'apt-get', '-y', 'install', 'docker.io'])

def install_docker_image():
    subprocess.run(['sudo','docker', 'build', '-t', 'postgres-image', '.'])

def docker_run():
    subprocess.run(['sudo', 'docker', 'run', '-p', '5432:5432', '-v', '/var/run/postgresql:/var/run/postgresql', '-d', 'postgres-image'])


if __name__ == "__main__":
    update_apt()
    install_docker()
    install_docker_image()
    docker_run()

运行此命令时,这是cli中的内容:

Successfully built d7a66c60b43e
Successfully tagged postgres-image:latest
2d1c667a84513943dad359b73962b6314590b1bf79ab4376aa7b513684629e5f

--- Successul built and ran container ---

(venv) simon@simon-HP-EliteBook-840-G2:~/Desktop/Projects/x5-test-task$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
2d1c667a8451        postgres-image      "docker-entrypoint.s…"   7 seconds ago       Up 5 seconds        0.0.0.0:5432->5432/tcp   loving_shtern

-- Check if it works ----

(venv) simon@simon-HP-EliteBook-840-G2:~/Desktop/Projects/x5-test-task$ python3
Python 3.6.7 (default, Oct 22 2018, 11:32:17)
[GCC 8.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import psycopg2
>>> conn = psycopg2.connect(dbname='monitoring', user='process_monitor')
>>> cur = conn.cursor()
>>> cur.execute('SELECT datname FROM pg_database')
>>> cur.fetchall()
[('postgres',), ('monitoring',), ('template1',), ('template0',)]
>>> exit()

--- as you can see, there is a monitoring database I need ---

请参见,从Python shell成功连接。

但是当我尝试添加在shell中检查的相同代码时,出现错误:

if __name__ == "__main__":
    update_apt()
    install_docker()
    install_docker_image()
    docker_run()
    conn = psycopg2.connect(dbname='monitoring', user='process_monitor')
Traceback (most recent call last):
  File "setup.py", line 58, in <module>
    conn = psycopg2.connect(dbname='monitoring', user='process_monitor')
  File "/home/simon/Desktop/Projects/x5-test-task/venv/lib/python3.6/site-packages/psycopg2/__init__.py", line 130, in connect
    conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
psycopg2.OperationalError: could not connect to server: No such file or directory
        Is the server running locally and accepting
        connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?

不知道为什么我无法从同一脚本进行连接。我应该增加一些睡眠时间吗?

Edit1 :看来这是时间问题。尝试sleep(60)成功连接。

3 个答案:

答案 0 :(得分:1)

问题是您尝试在启动数据库启动后立即进行连接。从容器启动到数据库开始接受连接之间需要一段时间。您可以使用sleep等待固定的时间,也可以创建循环来检查数据库端口是否打开。

答案 1 :(得分:0)

检查官方文档后,我发现:

  

如果在容器中启动postgres时没有数据库,则   postgres将为您创建默认数据库。虽然这是   postgres的预期行为,这意味着它将不接受   在这段时间内传入的连接。这可能会导致问题   使用自动化工具,例如docker-compose,可以启动多个   容器。

这意味着,在容器启动后的几秒钟内,您将无法连接到postgres。

答案 2 :(得分:0)

检查此链接以获取带有Postgres的docker Setup PythonAPI: https://github.com/ajayrawat12/DockerPythonFalconPostgres

您可以在docker-compose.yml文件中公开db端口,然后可以使用dbclient作为127.0.0.1:5432在任何地方使用它进行连接