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 节点?

对于nginx容器,docker-compose up失败

`docker-compose up`无效的服务名称'...' - 只允许[a-zA-Z0-9 ._ - ]字符

docker-compose up Windows named pipe error:(code: 2)