【问题标题】:Connecting django app to postgres container将 django 应用程序连接到 postgres 容器
【发布时间】:2023-03-31 04:26:01
【问题描述】:

我很难将我的 Django 容器应用程序连接到我的 Postgres 容器。 Postgres 应用的 docker compose 语句如下:

version: '3'
services:
  database:
    image: "postgres" # use latest official postgres version
    restart: unless-stopped
    env_file:
      - ./database.env # configure postgres
    networks:
      - djangonetwork
    ports:
      - "5433:5432"
    volumes:
      - database-data:/var/lib/postgresql/data/ # persist data even if container shuts down

volumes:
  database-data: # named volumes can be managed easier using docker-compose
  
networks:
  djangonetwork:
    driver: bridge

Django 应用的 compose 语句如下:


services:
  app:
    build: .
    container_name: app
    command: >
      bash -c "python manage.py makemigrations &&
               python manage.py migrate &&
               python manage.py runserver 0.0.0.0:8000"
    networks:
      - djangonetwork
    ports:
      - 10555:8000
    environment:
      aws_access_key_id: ${aws_access_key_id}
      aws_secret_access_key: ${aws_secret_access_key}

networks:
  djangonetwork:
    driver: bridge

在执行 docker compose up 语句时出现了困难。我尝试了许多不同的 POSTGRES_HOST 值(注意它们是从 Amazon Secrets Manager 中成功检索到的)。我收到以下日志输出:

[+] Running 1/0
 ⠿ Container app  Created                                                                                                                                                                              0.0s
Attaching to app
app  | /usr/local/lib/python3.10/site-packages/django/core/management/commands/makemigrations.py:105: RuntimeWarning: Got an error checking a consistent migration history performed for database connection 'default': could not translate host name "postgres" to address: Name or service not known
app  | 
app  |   warnings.warn(
app  | No changes detected
app  | Traceback (most recent call last):
app  |   File "/usr/local/lib/python3.10/site-packages/django/db/backends/base/base.py", line 230, in ensure_connection
app  |     self.connect()
app  |   File "/usr/local/lib/python3.10/site-packages/django/utils/asyncio.py", line 25, in inner
app  |     return func(*args, **kwargs)
app  |   File "/usr/local/lib/python3.10/site-packages/django/db/backends/base/base.py", line 211, in connect
app  |     self.connection = self.get_new_connection(conn_params)
app  |   File "/usr/local/lib/python3.10/site-packages/django/utils/asyncio.py", line 25, in inner
app  |     return func(*args, **kwargs)
app  |   File "/usr/local/lib/python3.10/site-packages/django/db/backends/postgresql/base.py", line 199, in get_new_connection
app  |     connection = Database.connect(**conn_params)
app  |   File "/usr/local/lib/python3.10/site-packages/psycopg2/__init__.py", line 122, in connect
app  |     conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
app  | psycopg2.OperationalError: could not translate host name "postgres" to address: Name or service not known
app  | 
app  | 
app  | The above exception was the direct cause of the following exception:
app  | 
app  | Traceback (most recent call last):
app  |   File "/code/manage.py", line 22, in <module>
app  |     main()
app  |   File "/code/manage.py", line 18, in main
app  |     execute_from_command_line(sys.argv)
app  |   File "/usr/local/lib/python3.10/site-packages/django/core/management/__init__.py", line 425, in execute_from_command_line
app  |     utility.execute()
app  |   File "/usr/local/lib/python3.10/site-packages/django/core/management/__init__.py", line 419, in execute
app  |     self.fetch_command(subcommand).run_from_argv(self.argv)
app  |   File "/usr/local/lib/python3.10/site-packages/django/core/management/base.py", line 373, in run_from_argv
app  |     self.execute(*args, **cmd_options)
app  |   File "/usr/local/lib/python3.10/site-packages/django/core/management/base.py", line 417, in execute
app  |     output = self.handle(*args, **options)
app  |   File "/usr/local/lib/python3.10/site-packages/django/core/management/base.py", line 90, in wrapped
app  |     res = handle_func(*args, **kwargs)
app  |   File "/usr/local/lib/python3.10/site-packages/django/core/management/commands/migrate.py", line 75, in handle
app  |     self.check(databases=[database])
app  |   File "/usr/local/lib/python3.10/site-packages/django/core/management/base.py", line 438, in check
app  |     all_issues = checks.run_checks(
app  |   File "/usr/local/lib/python3.10/site-packages/django/core/checks/registry.py", line 77, in run_checks
app  |     new_errors = check(app_configs=app_configs, databases=databases)
app  |   File "/usr/local/lib/python3.10/site-packages/django/core/checks/model_checks.py", line 34, in check_all_models
app  |     errors.extend(model.check(**kwargs))
app  |   File "/usr/local/lib/python3.10/site-packages/django/db/models/base.py", line 1307, in check
app  |     *cls._check_indexes(databases),
app  |   File "/usr/local/lib/python3.10/site-packages/django/db/models/base.py", line 1699, in _check_indexes
app  |     connection.features.supports_covering_indexes or
app  |   File "/usr/local/lib/python3.10/site-packages/django/utils/functional.py", line 48, in __get__
app  |     res = instance.__dict__[self.name] = self.func(instance)
app  |   File "/usr/local/lib/python3.10/site-packages/django/db/backends/postgresql/features.py", line 84, in is_postgresql_11
app  |     return self.connection.pg_version >= 110000
app  |   File "/usr/local/lib/python3.10/site-packages/django/utils/functional.py", line 48, in __get__
app  |     res = instance.__dict__[self.name] = self.func(instance)
app  |   File "/usr/local/lib/python3.10/site-packages/django/db/backends/postgresql/base.py", line 339, in pg_version
app  |     with self.temporary_connection():
app  |   File "/usr/local/lib/python3.10/contextlib.py", line 135, in __enter__
app  |     return next(self.gen)
app  |   File "/usr/local/lib/python3.10/site-packages/django/db/backends/base/base.py", line 614, in temporary_connection
app  |     with self.cursor() as cursor:
app  |   File "/usr/local/lib/python3.10/site-packages/django/utils/asyncio.py", line 25, in inner
app  |     return func(*args, **kwargs)
app  |   File "/usr/local/lib/python3.10/site-packages/django/db/backends/base/base.py", line 270, in cursor
app  |     return self._cursor()
app  |   File "/usr/local/lib/python3.10/site-packages/django/db/backends/base/base.py", line 246, in _cursor
app  |     self.ensure_connection()
app  |   File "/usr/local/lib/python3.10/site-packages/django/utils/asyncio.py", line 25, in inner
app  |     return func(*args, **kwargs)
app  |   File "/usr/local/lib/python3.10/site-packages/django/db/backends/base/base.py", line 229, in ensure_connection
app  |     with self.wrap_database_errors:
app  |   File "/usr/local/lib/python3.10/site-packages/django/db/utils.py", line 90, in __exit__
app  |     raise dj_exc_value.with_traceback(traceback) from exc_value
app  |   File "/usr/local/lib/python3.10/site-packages/django/db/backends/base/base.py", line 230, in ensure_connection
app  |     self.connect()
app  |   File "/usr/local/lib/python3.10/site-packages/django/utils/asyncio.py", line 25, in inner
app  |     return func(*args, **kwargs)
app  |   File "/usr/local/lib/python3.10/site-packages/django/db/backends/base/base.py", line 211, in connect
app  |     self.connection = self.get_new_connection(conn_params)
app  |   File "/usr/local/lib/python3.10/site-packages/django/utils/asyncio.py", line 25, in inner
app  |     return func(*args, **kwargs)
app  |   File "/usr/local/lib/python3.10/site-packages/django/db/backends/postgresql/base.py", line 199, in get_new_connection
app  |     connection = Database.connect(**conn_params)
app  |   File "/usr/local/lib/python3.10/site-packages/psycopg2/__init__.py", line 122, in connect
app  |     conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
app  | django.db.utils.OperationalError: could not translate host name "postgres" to address: Name or service not known
app  | 
app exited with code 1

我很茫然。我应该使用什么 POSTGRES_HOST 值?我应该以不同的方式建立网络设置吗?

【问题讨论】:

  • 因为你有 2 个 docker-compose 文件,所以你有 2 个独立的网络。将数据库和应用服务放在同一个 compose 文件中,使它们在同一个网络上。当您这样做时,您可以使用服务名称作为主机名连接到数据库,即“数据库”。
  • 我试图避免在单个文件中执行它们,因为我想分别建立和维护它们。如果必须,我会这样做。但我希望可以在不创建单个撰写文件的情况下链接网络。谢谢。
  • 尝试 database 作为 Postgres 主机名,因为这是在 docker-compose 文件中调用服务的方式。
  • 当你同时运行两个容器时,如果你这样做docker network ls,你应该会看到两个名称以“djangonetwork”结尾的网络。您可以让容器连接到同一个网络,但是您必须将网络定义为 external 并在使用 docker network create 启动容器之前手动创建网络。
  • 我不得不清理旧的旧网络。手动创建网络,然后从每个网络作为“外部”加入它是成功的。我将在下面粘贴我的新 yaml 脚本。谢谢你的帮助。

标签: python django postgresql docker


【解决方案1】:

手动创建网络,然后为每个独立容器使用外部连接是成功的。在 shell 中启动网络的脚本:

docker network create --driver=bridge dbnet 

修订后的 Postgres yaml(注意我在这个版本中修改了端口设置以简化):

version: '3'
services:
  database:
    image: "postgres" # use latest official postgres version
    restart: unless-stopped
    env_file:
      - ./database.env # configure postgres
    networks:
      - dbnet
    ports:
      - "5432:5432"
    volumes:
      - database-data:/var/lib/postgresql/data/ # persist data even if container shuts down

volumes:
  database-data: # named volumes can be managed easier using docker-compose

networks:
  dbnet:
    external: true

修改后的 Django yaml 脚本:

version: '3'

services:
  app:
    build: .
    container_name: app
    command: >
      bash -c "python manage.py makemigrations &&
               python manage.py migrate &&
               python manage.py runserver 0.0.0.0:8000"
    networks:
      - dbnet
    ports:
      - 10555:8000
    environment:
      aws_access_key_id: ${aws_access_key_id}
      aws_secret_access_key: ${aws_secret_access_key}

networks:
  dbnet:
    external: true

【讨论】:

    猜你喜欢
    • 2019-12-15
    • 2019-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-26
    • 2017-04-11
    • 2013-01-10
    相关资源
    最近更新 更多