Docker-compose up 在本地完美运行,但在 gcp 上出现错误无法将主机名 db 转换为地址:名称解析中的临时故障
Posted
技术标签:
【中文标题】Docker-compose up 在本地完美运行,但在 gcp 上出现错误无法将主机名 db 转换为地址:名称解析中的临时故障【英文标题】:Docker-compose up runs perfectly localy ,but on gcp i get error could not translate host name db to address: Temporary failure in name resolution 【发布时间】:2022-01-06 14:08:02 【问题描述】:第 187 行,在 get_new_connection connection = Database.connect(**conn_params) 文件“/usr/local/lib/python3.9/site-packages/psycopg2/init.py”中,行122、在connect conn = _connect(dsn, connection_factory=connection_factory, **kwasync) django.db.utils.OperationalError: could not translate host name "db" to address: Temporary failure in name resolution
在我的本地机器上一切正常。
我的 docker 文件
FROM python:3.9-slim-buster
# RUN apt-get update && apt-get install -y libpq-dev \
# gcc \
# postgresql-client
# set work directory
WORKDIR /opt/app
# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
# install dependencies
RUN pip install --upgrade pip
COPY ./requirements.txt /opt/app/requirements.txt
RUN chmod +x /opt/app/requirements.txt
RUN pip install -r requirements.txt
# copy project
COPY . /opt/app/
RUN chmod +x /opt/app/docker-entrypoint.sh
EXPOSE 8000
ENTRYPOINT [ "/opt/app/docker-entrypoint.sh" ]
这是我的 docker-compose.yml
version: '3.9'
services:
db:
image: postgres
restart: always
environment:
- POSTGRES_NAME=postgres
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
- POSTGRES_PASS=postgres
volumes:
- postgres_data:/var/postgres/data/
app:
restart: always
build:
context: .
dockerfile: Dockerfile
command: python manage.py runserver 0.0.0.0:8000
container_name: myproj
volumes:
- ./app/:/usr/src/app/
ports:
- "8000:8000"
depends_on:
- db
volumes:
postgres_data:
driver: local
我的入口点
echo "Apply database migrations"
python manage.py makemigrations
python manage.py migrate
echo "Starting server"
python manage.py runserver 0.0.0.0:8000
exec "$@"
我的数据库设置
'default':
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'postgres',
'USER': 'postgres',
'PASSWORD': 'postgres',
'HOST': 'db',
'PORT': "5432"
我尝试过的
-
单独推送db容器但启动失败
Cloud Run 错误:容器无法启动。无法启动并监听PORT环境变量定义的端口
我已设置端口为5432,尝试在80端口上运行仍然无法上线
我的应用容器无法启动,因为它无法连接到数据库容器
无法将主机名 db 转换为地址:名称解析暂时失败
【问题讨论】:
你读过这个答案吗:***.com/questions/51750715/…。在你的情况下,我猜你必须在CMD
而不是入口点中启动你的 python 应用程序。
试过了,同样的错误@Robert-JanKuyper
您可以尝试在 serverfault.com 上提出问题,这是解决此类问题的更好平台。
您有多个问题。 1) Cloud Run Managed 不提供容器名称解析(目前)。在本地运行时,Docker 可以将容器网络连接在一起。 Cloud Run Managed 无法做到这一点。 2) Cloud Run Managed 不支持容器数据库。存储不是持久的,需要 HTTP 服务器接口。查看此链接以获取有关您可以运行的内容的详细信息。 cloud.google.com/run/docs/reference/container-contract
【参考方案1】:
基于 John Hanley 的评论和容器数据库,也不建议在 Cloud Run 等服务上托管数据库服务(PostgreSQL、mysql 等)。您可以查看相关主题here 和here。总之,可以向上和向下扩展的无状态容器除了没有persistent storage 之外,还会干扰数据库的正常运行。由于您使用的是 GCP,因此您可以选择已经提供的其他服务,例如 CloudSQL。 Cloud SQL 允许您创建 PostgreSQL 实例,并且可以是 integrated with Cloud Run hosted apps。
【讨论】:
【参考方案2】:来自 john Hanley 的 cmets,这就是我所做的,
创建了一个云 sql postgresql 实例并设置了我的数据库(内部 ip)
用于数据库连接
DATABASES = 'default': env.db()
# # If the flag as been set, configure to use proxy
if os.getenv("USE_CLOUD_SQL_AUTH_PROXY", None):
DATABASES["default"]["HOST"] = "cloudsql-proxy"
DATABASES["default"]["PORT"] = 5432
运行gcloud run deploy --source .
部署当前项目(docker 文件见下文)
在云中运行编辑和部署容器下的新版本设置您的端口,默认为 8080,
在变量和连接下(如果您使用的是 env)设置您的 env 变量。例如SECRET_KEY
,DATABASE_URL
,GOOGLE_CLOUD_PROJECT
,GS_BUCKET_NAME
,
在连接下,
例如 .env 文件
SECRET_KEY=mysupersecretkey
GS_BUCKET_NAME=mybucket
GOOGLE_CLOUD_PROJECT=myprojid
DATABASE_URL=postgres://dbuser:<db pass>@//cloudsql/projid:us-central1:instancename/dbname
将您的实例连接到您在上面创建的 postgresql 实例
出于安全考虑,您可能需要更改服务帐户,但没有必要
-
点击部署,你的容器就会活起来。
这是我的示例 dockerfile
FROM python:3.9
WORKDIR /opt/app
# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
# install dependencies
RUN pip install --upgrade pip
COPY ./requirements.txt /opt/app/requirements.txt
RUN chmod +x /opt/app/requirements.txt
RUN pip install -r requirements.txt
RUN adduser --disabled-password --no-create-home django-user
# copy project
COPY . /opt/app/
RUN chmod +x /opt/app/docker-entrypoint.sh
EXPOSE 8000
ENTRYPOINT [ "/opt/app/docker-entrypoint.sh" ]
CMD exec
码头工人撰写
version: '3.9'
services:
app:
container_name: myname
build:
context: .
ports:
- "8000:8000"
volumes:
- ./src/:/usr/src/app/
- ./d_creds.json:/secrets/d_creds.json
env_file:
- ./.env
restart: always
# The proxy will help us connect to remote CloudSQL instance locally.
# Make sure to turn off any ***s for the proxy to work.
cloudsqlproxy:
container_name: cloudsql-proxy
image: gcr.io/cloudsql-docker/gce-proxy:1.19.1
volumes:
- ./d_creds.json:/secrets/cloudsql/d_creds.json
ports:
- "127.0.0.1:5432:5432"
command: /cloud_sql_proxy -instances="projid:zone:instance-name"=tcp:0.0.0.0:5432 -credential_file=/secrets/cloudsql/d_creds.json
restart: always
对于入口点 .sh
#!/bin/bash
python3 manage.py makemigrations
python3 manage.py migrate
exec "$@"
【讨论】:
以上是关于Docker-compose up 在本地完美运行,但在 gcp 上出现错误无法将主机名 db 转换为地址:名称解析中的临时故障的主要内容,如果未能解决你的问题,请参考以下文章
如何在系统启动时运行 docker-compose up -d?
`docker-compose up`超时使用UnixHTTPConnectionPool
使用 docker-compose up 运行时如何优雅地停止 Dockerized Python ROS2 节点?