当前位置: 首页 > 知识库问答 >
问题:

Docker上的Django正在启动,但浏览器给出空响应

姚臻
2023-03-14

对于一个在mac上使用Django、Python3、Docker的简单应用程序

FROM python:3
ENV PYTHONUNBUFFERED=1

RUN mkdir /code

WORKDIR /code
COPY requirements.txt /code/
RUN python3 -m pip install -r requirements.txt
CMD python3 manage.py runserver  

COPY . /code/
version: "3.9"

services:
  # DB
  db:
    image: mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: '****'
      MYSQL_USER: '****'
      MYSQL_PASSWORD: '****'
      MYSQL_DATABASE: 'mydb'
    ports:
      - "3307:3306"
    expose:
      # Opens port 3306 on the container
      - '3307'
    volumes:
      - $HOME/proj/sql/mydbdata.sql:/mydbdata.sql

  # Web app
  web:
    build: .
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    depends_on:
      - db

此外,我想要的是在第一次创建映像时执行 SQL ,之后应该安装该数据库。

    volumes:
  - $HOME/proj/sql/mydbdata.sql:/mydbdata.sql

看起来Docker正在启动,但从我的浏览器中,我得到了这个响应

localhost didn’t send any data.
ERR_EMPTY_RESPONSE

我缺少什么?请帮忙。

共有1个答案

邵旺
2023-03-14

创建图像时,django项目似乎已经在运行。由于您使用command选项docker-compose.yml文件,因此在这种情况下,您不需要Dockerfile中的CMD命令。

我会重写 Dockerfiledocker-compose.yml,如下所示:

FROM python:3
ENV PYTHONUNBUFFERED 1

RUN mkdir /code

WORKDIR /code
COPY requirements.txt /code/
RUN python3 -m pip install -r requirements.txt

COPY . /code/
version: "3.9"

services:
  db:
    image: mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: '****'
      MYSQL_USER: '****'
      MYSQL_PASSWORD: '****'
      MYSQL_DATABASE: 'mydb'
    ports:
      - "3307:3306"  # make sure django project connects to 3306 port  
    volumes:
      - $HOME/proj/sql:/docker-entrypoint-initdb.d

  web:
    build: .
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    depends_on:
      - db

有几点需要指出。

    < li >当您运行< code>docker-compose up时,您可能会看到一个错误,因为您的django项目甚至在db初始化之前就已经在运行了。那是自然的。所以你需要定制的命令或者shell程序来强制django项目等待尝试连接db。

在我的情况下,我会使用自定义命令。

version: "3.9"

services:

  db:
    image: mysql:8
    env_file:
      - .env
    command: 
      - --default-authentication-plugin=mysql_native_password
    restart: always
    ports:
      - "3308:3306"

  web:
    build: .
    command: >
      sh -c "python manage.py wait_for_db &&
             python manage.py makemigrations && 
             python manage.py migrate && 
             python manage.py runserver 0.0.0.0:8000"
    volumes:
      - .:/code
    ports:
      - "8001:8000"
    depends_on: 
      - db
    env_file:
      - .env

接下来,< code>wait_for_db.py。这个文件是我在< code > myapp/management/commands/wait _ for _ db . py 中创建的。这样,您可以推迟数据库连接,直到数据库准备好。这个SO帖子对我帮助很大。

有关详细信息,请参阅编写自定义django-admin命令。

import time

from django.db import connection
from django.db.utils import OperationalError
from django.core.management.base import BaseCommand


class Command(BaseCommand):
    """Wait to connect to db until db is initialised"""

    def handle(self, *args, **options):
        start = time.time()
        self.stdout.write('Waiting for database...')
        while True:
            try:
                connection.ensure_connection()
                break
            except OperationalError:
                time.sleep(1)

        end = time.time()
        self.stdout.write(self.style.SUCCESS(f'Database available! Time taken: {end-start:.4f} second(s)'))

初始化一个新实例第一次启动容器时,将创建一个具有指定名称的新数据库,并使用提供的配置变量进行初始化。此外,它将执行带有扩展名的文件。嘘,。/docker-entrypoint-initdb.d .文件中的sql和. sql.gz将按字母顺序执行。通过将sql转储装载到该目录中,您可以轻松地填充mysql服务,并提供带有贡献数据的自定义映像。默认情况下,SQL文件将被导入到由MYSQL_DATABASE变量指定的数据库中。

所以你的<代码>。sql文件应该位于mysql容器中的< code >/docker-entry point-initdb . d 中。更多信息请看这篇文章。

version: "3.9"

services:

  db:
...
    volumes:
      - data:/var/lib/mysql

...

volumes:
  data:
 类似资料:
  • 我可以在下面/上面的代码帮助下启动Chrome浏览器的空窗口,但他们是一些错误,我得到了

  • 我一直试图在浏览器localhost:8080上运行它,但它说“站点无法到达”,尽管它说Tomcat在终端中运行 我通过从网站下载二进制版本安装了它。 这是加泰罗尼亚,出去 这是grep tomcat 根38084 0.1 1.0 6062688 80312 s000 S 8:54AM 0:15.59/library/java/javavirtualmachines/jdk1.8.0_91.jdk

  • 问题内容: 我刚接触selenium。我生成了我的第一个Javaselenium测试用例,它已成功编译。但是当我运行该测试时,我得到了以下RuntimeException 请告诉我如何解决此错误。 这是我要运行的Java文件。 我首先通过命令提示符启动了selenium服务器,然后通过另一个命令提示符执行了上述java文件。 第二个问题:我可以右键单击包含selenium的网页上的指定位置。 问题

  • 问题内容: 抱歉,您有愚蠢的问题,但是如何在webdriver中启动Chrome浏览器?我知道我必须指定chromedriver.exe的路径。问题是我无法下载chromedriver.exe,它已被删除。我发现的文件也没有.exe扩展名。我正在使用Eclipse,Java。请帮忙!我按照建议的步骤进行了所有操作,但是没有用。这是我的代码: 这是错误: 失败:测试java.lang.Illegal

  • 我使用html5拖放。 当我从任何给定网页拖动图像或链接时,浏览器窗口会识别dragover事件。 例如,在浏览器选项卡上拖动图像会使浏览器切换窗口。例如,拖动链接到书签也是如此。 现在,当我拖动自定义的可拖动元素时,浏览器没有任何反应。有没有办法改变这种行为?

  • 问题内容: 我是jqGrid的新手,我需要在调整Web浏览器窗口大小时调整网格大小。我已在网格中应用 ,但无法正常工作。 CSS的设置是唯一一个实现,但它不是在良好的jqGrid的情况下, 该组中明确的许多内部结构。 什么是解决它的完美方法? 问题答案: jqGrid 在许多内部结构(div,表等)上使用固定值。因此,不能只设置CSS 。但是,还有另一种方法可以做到这一点。可以在对象上注册事件处理

  • 我正试图通过cmd启动logstash。我有正确的目录,但是当我输入命令启动它时,它会出现以下错误(见图中所示): 请帮帮我。