我尝试在虚拟机中通过 psycopg2.connec 连接到容器的 PostgreSQL 数据库,以将 csv 文件作为表插入,但我不断遇到此错误:
Failed to connect to PostgreSQL: connection to server at "postgres" (container's IP), port 5432 failed: Connection refused
Is the server running on that host and accepting TCP/IP connections?
其中“postgres”是包含我的数据库的服务的名称。这是我的 docker-compose.yml:
version: "3.8"
services:
postgres:
image: postgres
restart: always
ports:
- "5432:5432"
environment:
- DATABASE_HOST=IP
- POSTGRES_USER=pids
- POSTGRES_PASSWORD=pids
ingesta:
build:
context: .
dockerfile: datos_est/Dockerfile
depends_on:
- postgres
其中DATABASE_HOST=IP是我的虚拟机的IP 这是内置在“ingesta”服务中的 Dockerfile:
FROM python:3.8
WORKDIR /app
COPY datos_est/example.py datos_est/example.csv /app/
RUN pip install psycopg2
CMD ["python3", "example.py"]
这些是我的 example.py 文件的 psycopg2.connect 命令的参数:
conexion = psycopg2.connect(
host="postgres",
database="postgres",
user="pids",
password="pids",
)
这是我的文件浏览器,这样您就不会迷失我的文件路径:
P3/
来源/
docker-compose.yml 数据_est/
Dockerfile 示例.csv 示例.py
我正在从我的虚拟机运行
docker compose up
我还将 depends_on
参数放入“ingesta”服务中,以便在“postgres”服务启动完成后启动。
我尝试在“conexion”变量之前添加一个time.sleep(10)
。它并不是 100% 的时候都有效。
我确保脚本中的主机名称与具有数据库的服务名称匹配。
我确保有一个干净的环境,这样我就不会遇到其他容器或图像的问题:
docker container rm -f $(docker container ls -aq)
docker image rm -f $(docker image ls -q)
我确保可以使用以下方式从终端访问数据库:
ubuntu@pids-vm:~/P3/src$ psql -h localhost -U pids -d pids -p 5432
Password for user pids:
psql (14.9 (Ubuntu 14.9-0ubuntu0.22.04.1), server 16.1 (Debian 16.1-1.pgdg120+1))
WARNING: psql major version 14, server major version 16.
Some psql features might not work.
Type "help" for help.
pids=#
我还检查了数据库是否正在监听 5432,看起来是这样:
ubuntu@pids-vm:~/P3/src$ netstat -nl |grep 5432
tcp 0 0 0.0.0.0:5432 0.0.0.0:* LISTEN
tcp6 0 0 :::5432 :::* LISTEN
您对出现的问题有什么建议吗?
您尚未在 docker-compose 文件中声明网络,因此您将无法通过主机名通过网络访问主机。
您已将 docker 主机的端口映射到 docker 容器,但无法使用“localhost”从 ingesta 内部访问该端口,因为在容器中“localhost”指的是容器本身,而不是容器的主机。因此,您必须通过 IP 地址从容器内部引用 docker 主机,传统上是 172.17.0.1。您的 psql 可以与“localhost”配合使用,只是因为您直接在 docker 主机上运行它。
其中DATABASE_HOST=IP是我的虚拟机的IP
据我所知,DATABASE_HOST 在 postgresql 映像中不执行任何操作。另外,当IP还没有分配时,你怎么知道会分配什么IP呢?