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

line 187, in get_new_connection connection = Database.connect(**conn_params) File "/usr/local/lib/python3.9/site-packages/psycopg2/init.py", line 122, in 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"
    }

我试过的

  1. 单独推送db容器但是启动失败

Cloud Run error: Container failed to start. Failed to start and then listen on the port defined by the PORT environment variable

我设置了5432端口,试了运行80端口还是上不去

我的应用程序容器无法启动,因为它无法连接到数据库容器

could not translate host name db to address: Temporary failure in name resolution

基于 John Hanley 的评论和容器数据库,也不建议在 Cloud 运行 等服务上托管数据库服务(PostgreSQL、MySQL 等)。您可以查看相关话题 and here. In summary, stateless containers which can scale up and down, in addition to not having persistent storage, would interfere with how a database properly functions. Since you are using GCP, you can opt for other services which are already offered, such as CloudSQL. Cloud SQL lets you create PostgreSQL instances, and can be integrated with Cloud Run hosted apps

根据 john Hanley 的评论,这就是我所做的,

  1. 创建了一个云 sql postgresql 实例并设置了我的数据库(内部 ip)

  2. 用于数据库连接

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
  1. 运行 gcloud run deploy --source . 部署当前项目(参见下面的 docker 文件)

  2. 在云端运行在容器下编辑&部署新版本设置你的端口,默认是8080, 在变量和连接下(如果您使用的是 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 实例

出于安全考虑,您可能想要更改服务帐户,但没有必要

  1. 点击部署,您的容器就会启动。

这是我的示例 docker文件



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


docker撰写


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 VPNs 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 "$@"