【问题标题】:docker-compose to run django with mongodbdocker-compose 用 mongodb 运行 django
【发布时间】:2015-03-04 12:24:51
【问题描述】:

我在使用 docker-compose 将 django 容器与 postgres 和 mongo 容器链接时遇到问题?我正在尝试使用“docker-compose up”来启动 mongo 和 postgres 容器(因为我需要链接两者)但 django 应用程序仍然无法在默认设置下连接到 mongodb。我的 django-compose.yml 文件内容复制如下:

    db1:
      image: postgres
    db2:
      image: mongo
      ports:
        - "27017:27017"
    web:
      build: .
      command: python manage.py runserver 0.0.0.0:8000
      volumes:
        - .:/code
      ports:
        - "8000:8000"
      links:
        - db1
        - db2

它确实使用默认设置与 postgres 连接。我也可以在本地远程登录到 mongodb 端口。不过,我在启动 Web 容器时收到此错误:

文件 "/usr/local/lib/python2.7/site-packages/mongoengine/connection.py", 第 124 行,在 get_connection web_1 |引发连接错误(“不能 连接到数据库 %s :\n%s" % (别名, e)) web_1 | mongoengine.connection.ConnectionError:无法连接到数据库 默认:web_1 | [Errno 111] 连接被拒绝

PS:我已经在我的本地主机上成功启动了一个 django-postgres 连接的应用程序,但它无法连接到 AWS 实例上的 db。这是我仍然需要解决的另一个问题。

【问题讨论】:

    标签: django mongodb docker


    【解决方案1】:

    我遇到了类似的问题,但使用了另一个服务(不是 MongoDB)。我不确定我做错了什么,但这就是我可以解决的方法:

    import os
    import mongoengine
    
    MONGODB_HOST = os.environ.get('DB2_PORT_27017_TCP_ADDR', '127.0.0.1')
    mongoengine.connect(host=MONGODB_HOST)
    
    • DB2docker-compose.yml 中的服务名称
    • 27017 是公开服务的端口。
    • More about docker-compose environment variables
    • 我会把它放在我的设置文件中。但您可以根据您的项目架构随意将其放在您认为合适的任何位置

    更新

    现在,其他服务可以使用与其别名相似的主机名访问 docker-compose 容器。 link documentation

    链接服务的容器可以通过主机名访问 与别名相同,如果未指定别名,则与服务名称相同。

    这样你就可以像这样连接到 MongoDB:

    import mongoengine
    
    mongoengine.connect(host="db2")
    

    【讨论】:

    • 在主机上执行docker-compose run yourappname env,查找与您的数据库映像相关的IP地址,这就是您用来连接到容器中运行的数据库的IP地址。
    • 这对我来说就像一个魅力,只是为了记录,当对 PORT 使用相同的策略时,记得用 int 转换它,比如:...port=int(MONGODB_PORT)...
    • 编写此代码的规范位置在哪里?在 settings.py 中?
    【解决方案2】:

    您应该像在 docker compose 文件中一样指定主机名,而不是 IP 地址。

    我在从 Tornado Web 应用程序连接到 Mongo DB 时遇到了类似的问题。这是我的 docker-compose.yml:

    web:
      build: .
      ports:
       - "8888:8888"
      volumes:
       - .:/code
      links:
       - db
    db:
      image: mongo:3.0
    

    这是我的连接字符串:

    motorengine.connect("db", host='db', port=27017, io_loop=io_loop)
    

    我的错误是在 docker compose 文件中指定 IP 地址而不是主机名 (db)。

    【讨论】:

      【解决方案3】:

      您面临的问题是应用程序容器和数据库容器彼此独立启动,最重要的是,应用程序容器不会等到数据库容器启动。从 docker compose 1.1.0 开始,没有允许考虑此类依赖项的功能。

      这是一个众所周知的问题,并且已经是discussed。共识似乎是,这不应该在 docker compose 级别上解决,而应该在 docker 本身中解决。 docker 的基础工作已经有一个proposal

      就我而言,我只是在应用程序本身中构建了这种智能。我检查端口连接直到成功,然后启动应用程序的其余部分。

      【讨论】:

      • 感谢 vanthome 的回复。在发布此消息后不久,我也意识到了这个问题,并进行了调整以检查 mongo 容器是否在 django 容器连接到它之前准备好。这可能是另一个问题,但我仍然无法连接。我可以连接的唯一可能方法是不使用 docker-compose。我刚刚独立启动了这两个容器,在我的 django 设置中指定了 mongo 容器的 ip。它适用于这种情况。但是 docker-compose 有什么用呢?
      • Docker compose 服务于不同的方面。它不是一个编排器,它只是一种以简单的方式启动和链接一堆容器的方法。
      • 我遇到了与@anuprag 类似的问题,而且似乎也不是解决方案。如果我docker-compose run web /bin/bashping 172.17.0.52(这是DB_1_PORT 环境变量的IP),我得到92 bytes from 209d72d65b0c (172.17.0.53): Destination Host Unreachable,这意味着它是整个mongodb 容器没有启动。
      • 我无法独立启动它:docker-compose -p 27017: 27017 mongo mongo 返回相同的错误
      【解决方案4】:

      我能够将 Django 和 MongoDB 容器化,连接两个容器。 我使用 Dockerfiles 来构建容器和 docker run 来启动容器并连接它们。只需按照repo 中的步骤操作即可。因为最新版本的 Django 和 mongoengine 不兼容,所以我有必要使用 Dockerfiles 对所需库的已安装版本有更多的权力。 稳定的工作版本是

      Django==1.10.0
      pymongo==2.7.1
      six==1.10.0
      mongoengine==0.9.0
      

      【讨论】:

        【解决方案5】:

        我设法通过以下配置建立了这种联系:

        docker-compose.yml

        version: "3.9"
        services:
        mongodb:
          environment:
            MONGO_INITDB_DATABASE: mydatabase
            MONGO_INITDB_ROOT_USERNAME: root
            MONGO_INITDB_ROOT_PASSWORD: password
          hostname: mongodb
          image: mongo
          ports:
            - "27017:27017"
          volumes: 
            - ./data-mongodb:/data/db
          
        api:
          build: .
          command: "python manage.py runserver 0.0.0.0:8000"
          volumes:
            - .:/code
          ports:
            - "8000:8000"
          depends_on:
            - mongodb
        

        Dockerfile

        # syntax=docker/dockerfile:1
        FROM python:3
        ENV PYTHONUNBUFFERED=1
        WORKDIR /code
        COPY requirements.txt /code/
        RUN pip install --upgrade pip
        RUN pip install -r requirements.txt
        COPY . /code/
        

        requirements.txt

        asgiref==3.4.1
        Django==3.2.7
        django-annoying==0.10.6
        djangorestframework==3.12.4
        djongo==1.3.6
        psycopg2==2.9.1
        psycopg2-binary==2.9.1
        pymongo==3.12.1
        pytz==2021.3
        six==1.16.0
        sqlparse==0.2.4
        

        settings.py

        DATABASES = {
            'default': {
              'ENGINE': 'djongo',
              'NAME': 'mydatabase',
              'CLIENT': {
                  'host': 'mongodb://mongodb:27017',
                  'username': 'root',
                  'password': 'password',
                  'authSource': 'admin',
                  'authMechanism': 'SCRAM-SHA-1',
              }
          }
        }
        

        这里使用的模型来自 Djongo 而不是from django.db import models

        models.py

        from djongo import models
        

        build之后,需要进入api容器,运行./manage.py migrate

        【讨论】:

          猜你喜欢
          • 2021-08-04
          • 1970-01-01
          • 1970-01-01
          • 2023-01-04
          • 1970-01-01
          • 2023-04-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多