我无法在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)
成功连接。
答案 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在任何地方使用它进行连接