在一个文件夹中,我有 3 个文件:base.py、Dockerfile 和 docker-compose.yml。
base.py:
import psycopg2
conn = psycopg2.connect("dbname='base123' user='postgres' host='db' password='pw1234'")
Dockerfile:
FROM ubuntu:16.04
RUN apt-get update
RUN apt-get -y install python-pip
RUN apt-get update
RUN pip install --upgrade pip
RUN pip install psycopg2-binary
COPY base.py base.py
RUN python base.py
docker-compose.yml:
version: '3'
services:
db:
image: 'postgres:latest'
expose:
- "5432"
environment:
POSTGRES_PASSWORD: pw1234
POSTGRES_DB: base123
aprrka:
build: .
depends_on:
- db
运行
docker-compose up
后,出现以下错误:
Traceback (most recent call last):
File "base.py", line 5, in <module>
conn = psycopg2.connect("dbname='base123' user='postgres' host='db' password='pw1234'")
File "/usr/local/lib/python2.7/dist-packages/psycopg2/__init__.py", line 130, in connect
conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
psycopg2.OperationalError: could not translate host name "db" to address: Name or service not known
ERROR: Service 'aprrka' failed to build: The command '/bin/sh -c python base.py' returned a non-zero code: 1
我不知道为什么会出现这个错误。我公开了端口 5432。默认情况下,Compose 为应用程序设置单个网络。每个服务都加入默认网络,我认为我的应用程序与 postgres 应该一起工作。我是否写错了 docker-compose.yml?
问题是您不应该将
python base.py
作为 RUN
指令的一部分运行。
RUN
指令仅在构建镜像时执行。此时 postgres
容器尚未运行,网络也尚未创建。相反,您想使用 CMD
指令。
将
Dockerfile
更改为:
FROM ubuntu:16.04
RUN apt-get update
RUN apt-get -y install python-pip
RUN apt-get update
RUN pip install --upgrade pip
RUN pip install psycopg2-binary
COPY base.py base.py
CMD ["python", "base.py"]
上述内容应该会导致主机名
db
得到解析。但是,如果您的 python 代码没有任何用于连接到数据库的重新连接逻辑,则容器可能仍然会出错。这是因为 postgres
容器将运行,但数据库尚未准备好接受连接。
可以通过将
restart: always
添加到您的 docker-compose.yml
来暂时修复此问题。
version: '3'
services:
db:
image: 'postgres:latest'
expose:
- "5432"
environment:
POSTGRES_PASSWORD: pw1234
POSTGRES_DB: base123
aprrka:
restart: always
build: .
depends_on:
- db
希望这能让您启动并运行。
在 docker compose 文件中的同一网络上添加数据库和 Web 服务。另外链接 db 服务并在启动 db 服务后启动 Web 服务。
正确添加network、link和depends_on配置后,docker compose文件中的问题将得到解决。
配置示例:
services:
db:
container_name: db
networks:
- djangonetwork
web:
depends_on:
- db
links:
- db:db
networks:
- djangonetwork
networks:
djangonetwork:
driver: bridge
在我的 docker compose 文件中,我使用的网络名称为“djangonetwork”,您可以使用任何其他名称。
上述配置帮助我解决了“无法翻译主机名数据库”的问题。
如果您使用 docker-compose,请首先将此行添加到您的 .yml 中:
environment:
- "POSTGRES_HOST_AUTH_METHOD=trust"
之后你只启动你的db docker:
docker-compose up db
它应该正常启动,并显示如下消息:
Recreating db... done
Attaching to db
db_1 | ********************************************************************************
db_1 | WARNING: POSTGRES_HOST_AUTH_METHOD has been set to "trust". This will allow
db_1 | anyone with access to the Postgres port to access your database without
db_1 | a password, even if POSTGRES_PASSWORD is set. See PostgreSQL
db_1 | documentation about "trust":
db_1 | https://www.postgresql.org/docs/current/auth-trust.html
db_1 | In Docker's default configuration, this is effectively any other
db_1 | container on the same system.
db_1 |
db_1 | It is not recommended to use POSTGRES_HOST_AUTH_METHOD=trust. Replace
db_1 | it with "-e POSTGRES_PASSWORD=password" instead to set a password in
db_1 | "docker run".
db_1 | ********************************************************************************
建议:这样做并不安全。 如果您决定使用此解决方案,请确保在 .gitignore 中列出您的 docker 文件,这样您就不会将其推入生产环境。
如果您将其添加到 docker-compose.yml 中的数据库容器中,它应该可以解决问题
environment:
- "POSTGRES_HOST_AUTH_METHOD=trust"
另一种可能的情况,
检查端口是否被其他docker容器使用。 使用命令:
$ docker container ls --format "table {{.ID}}\t{{.Names}}\t{{.Ports}}" -a
然后在 docker-compose 文件中更改端口/暴露
我想我应该给出更新的答案,因为我最近发现了类似的问题。
我有一个类似的设置,应用程序可以从本地运行的 docker 正确连接,但在 Jenkins 中运行时会失败。
将
image: postgres:latest
更改为 image: postgres:13.4-alpine
解决了问题。
我检查了所有方法和解决方案,但无法解决问题。
docker文件: ` 来自 python:3.11.1-slim
工作目录/应用程序
ENV Python不写入字节码1 ENV Python 无缓冲 1
复制requirements.txt。 运行 pip install -rrequirements.txt
复制。 。 `
docker-compose.yml ` 应用程序: 建造: 。 命令: uvicorn app.main:app --host 0.0.0.0 --reload --workers 1 卷: - 。:/应用程序 环境: - DATABASE_URL=postgresql://postgres:S6ge9R53Ewn9SRtMZx@db/fastapi_app 依赖于取决于: - 分贝
ports:
- 8008:8000
db:
image: postgres:15-alpine
networks:
- BackendNetwork
volumes:
- postgres_data:/var/lib/postgresql/data/
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=S6ge9R53Ewn9SRtMZx
- POSTGRES_DB=fastapi_app
expose:
- 5432
`