python Django应用程序在容器内运行,但无法解析容器外的DB

cwtwac6a  于 2023-01-11  发布在  Python
关注(0)|答案(2)|浏览(162)

我有一个Django应用程序,我决定在container中设置如下:

#docker-compose.yml
version: "3.9"
services:
  web:
    build: .
    command: python /code/manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/code
    ports:
      - 8000:8000
    depends_on:
      - db
      
  db:
    image: postgres:13
    volumes:
      - postgres_data:/var/lib/postgresql/data/
    environment:
      - "POSTGRES_HOST_AUTH_METHOD=trust"

volumes:
  postgres_data:

设置中的数据库配置如下所示

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql",
        "NAME": "postgres",
        "USER": "postgres",
        "PASSWORD": "postgres",
        "HOST": "db",
        "PORT": 5432,
    }
}

当我运行容器时,应用程序可以正常工作,我可以将数据迁移并插入数据库。
但是,当我尝试通过以下步骤在容器外运行项目时:

  1. python -m venv venv
  2. source venv/bin/activate
  3. pip install -r requirements.txt
  4. python manage.py runserver
    我收到一个错误:
Traceback (most recent call last):
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/db/backends/base/base.py", line 244, in ensure_connection
    self.connect()
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/db/backends/base/base.py", line 225, in connect
    self.connection = self.get_new_connection(conn_params)
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/db/backends/postgresql/base.py", line 203, in get_new_connection
    connection = Database.connect(**conn_params)
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/psycopg2/__init__.py", line 122, 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

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/lib64/python3.10/threading.py", line 1016, in _bootstrap_inner
    self.run()
  File "/usr/lib64/python3.10/threading.py", line 953, in run
    self._target(*self._args, **self._kwargs)
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/utils/autoreload.py", line 64, in wrapper
    fn(*args, **kwargs)
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/core/management/commands/runserver.py", line 137, in inner_run
    self.check_migrations()
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/core/management/base.py", line 576, in check_migrations
    executor = MigrationExecutor(connections[DEFAULT_DB_ALIAS])
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/db/migrations/executor.py", line 18, in __init__
    self.loader = MigrationLoader(self.connection)
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/db/migrations/loader.py", line 58, in __init__
    self.build_graph()
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/db/migrations/loader.py", line 235, in build_graph
    self.applied_migrations = recorder.applied_migrations()
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/db/migrations/recorder.py", line 81, in applied_migrations
    if self.has_table():
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/db/migrations/recorder.py", line 57, in has_table
    with self.connection.cursor() as cursor:
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/db/backends/base/base.py", line 284, in cursor
    return self._cursor()
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/db/backends/base/base.py", line 260, in _cursor
    self.ensure_connection()
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/db/backends/base/base.py", line 243, in ensure_connection
    with self.wrap_database_errors:
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/db/utils.py", line 91, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/db/backends/base/base.py", line 244, in ensure_connection
    self.connect()
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/db/backends/base/base.py", line 225, in connect
    self.connection = self.get_new_connection(conn_params)
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/site-packages/django/db/backends/postgresql/base.py", line 203, in get_new_connection
    connection = Database.connect(**conn_params)
  File "/home/jdoni/code/work/tasks/venv/lib64/python3.10/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: Name or service not known

我真的不明白为什么django不能识别容器外的数据库主机,有什么想法吗?

0ejtzxu1

0ejtzxu11#

您需要使“db”容器在本地可用,只需Map一个本地端口,如下所示:

db:
    image: postgres:13
    volumes:
      - postgres_data:/var/lib/postgresql/data/
    ports:
      - '5432:5432'
    environment:
      - "POSTGRES_HOST_AUTH_METHOD=trust"

现在您可以检查连接:

psql -h localhost -p 5432

要从Django本地访问它,您需要更改一个配置为:

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql",
        "NAME": "postgres",
        "USER": "postgres",
        "PASSWORD": "postgres",
        "HOST": "localhost",   # <----- HERE IS THE CHANGE
        "PORT": 5432,
    }
}
zyfwsgd6

zyfwsgd62#

在Django的设置中,我会使用一个环境变量来指定数据库的位置,你可以为它设置一个默认值,我通常会使用一个开发人员友好的默认值。

DATABASES = {
  "default": {
    "HOST": os.getenv("PGHOST", "localhost"),
    ...
  }
}

只要您的数据库容器发布ports:,就可以将其用于基于主机的开发设置

docker-compose up -d db

. ./venv/bin/activate
./manage.py runserver

这意味着还需要在合成设置中设置环境变量。

version: '3.8'  # most recent 3.x Compose file version
services:
  web:
    build: .
    ports:
      - 8000:8000
    depends_on:
      - db
    environment:   # add
      PGHOST: db   # add
    # (should not need volumes: or command: override)

  db:
    image: postgres:13
    volumes:
      - postgres_data:/var/lib/postgresql/data/
    environment:
      - "POSTGRES_HOST_AUTH_METHOD=trust"
    ports:            # add
      - '5432:5432'   # add

volumes:
  postgres_data:

如果您的主机系统已经将端口5432用于不同的数据库,则需要将 firstports:编号更改为不冲突的其他编号;第二个端口必须固定在标准端口5432。您还需要以相同的方式配置数据库端口号。

相关问题