Что такое команда docker для запуска моего Django сервера? - PullRequest
2 голосов
/ 06 февраля 2020

Я пытаюсь Dockerize мою локальную настройку Django / MySql. У меня есть этот каталог и структура файла ...

apache
docker-compose.yml
web
    - manage.py
    - venv
    - requirements.txt
    - ...

Ниже приведен файл docker -compose.yml, который я использую ...

version: '3'  

services:
  web:
    restart: always
    build: ./web
    expose:
      - "8000"
    links:
      - mysql:mysql
    volumes:
      - web-django:/usr/src/app
      - web-static:/usr/src/app/static
    #env_file: web/venv
    environment:
      DEBUG: 'true'
    command: [ "python", "./web/manage.py runserver 0.0.0.0:8000" ]

  mysql:
    restart: always
    image: mysql:5.7
    environment:
      MYSQL_DATABASE: 'maps_data'
      # So you don't have to use root, but you can if you like
      MYSQL_USER: 'chicommons'
      # You can use whatever password you like
      MYSQL_PASSWORD: 'password'
      # Password for root access
      MYSQL_ROOT_PASSWORD: 'password'
    ports:
      - "3406:3406"
    expose:
      # Opens port 3406 on the container
      - '3406'
    volumes:
      - my-db:/var/lib/mysql

volumes:
  web-django:
  web-static:
  my-db:

Однако при запуске

docker-compose up

Я получаю ошибки, подобные приведенным ниже

maps_web_1 exited with code 2
web_1    | python: can't open file './web/manage.py runserver 0.0.0.0:8000': [Errno 2] No such file or directory
maps_web_1 exited with code 2
maps_web_1 exited with code 2
web_1    | python: can't open file './web/manage.py runserver 0.0.0.0:8000': [Errno 2] No such file or directory
maps_web_1 exited with code 2

Есть ли другой способ, которым я должен ссылаться на файл manage.py?

Редактировать: Добавлена ​​информация, запрошенная в комментариях ...

FROM python:3.7-slim

RUN apt-get update && apt-get install

RUN apt-get install -y libmariadb-dev-compat libmariadb-dev
RUN apt-get update \
    && apt-get install -y --no-install-recommends gcc \
    && rm -rf /var/lib/apt/lists/*

RUN python -m pip install --upgrade pip

COPY requirements.txt requirements.txt
RUN python -m pip install -r requirements.txt

COPY . .

Ответы [ 3 ]

2 голосов
/ 08 февраля 2020

Как и предполагали другие, это наиболее вероятно из-за запуска manage.py runserver из неправильного каталога или чего-то очень похожего на это.

Вы не используете директиву WORKDIR в вашей Dockerfile, в все. Намного безопаснее, если вы их используете. Измените файлы Dockerfile и docker-compose.yml, как показано ниже, и ваша проблема должна быть решена.

Dockerfile

FROM python:3.7-slim

RUN apt-get update && apt-get install

RUN apt-get install -y libmariadb-dev-compat libmariadb-dev
RUN apt-get update \
    && apt-get install -y --no-install-recommends gcc \
    && rm -rf /var/lib/apt/lists/*

RUN python -m pip install --upgrade pip
RUN mkdir -p /app/

WORKDIR /app/

COPY requirements.txt requirements.txt
RUN python -m pip install -r requirements.txt

COPY . /app/

docker -составить .yml

version: '3'  

services:
  web:
    restart: always
    build: ./web
    expose:
      - "8000"
    links:
      - mysql:mysql
    volumes:
      - web-django:/usr/src/app
      - web-static:/usr/src/app/static
    #env_file: web/venv
    environment:
      DEBUG: 'true'
    command: [ "python", "manage.py", "runserver", "0.0.0.0:8000" ]
...

Уведомление

Вы сможете исправить проблему, просто удалив web из своей команды для запуска сервера. Это потому, что когда вы создаете Dockerfile, вы находитесь внутри каталога web. Поэтому, когда вы делаете COPY . ., вы копируете содержимое в каталог web, а не в сам каталог web. На самом деле, ваша файловая структура внутри docker образа должна выглядеть примерно так:

- root
- home
- var
- ...
- manage.py
- venv
- requirements.txt
- ...
0 голосов
/ 06 февраля 2020

Давайте попробуем отладить эту ошибку:

maps_web_1 exited with code 2
web_1    | python: can't open file './web/manage.py runserver 0.0.0.0:8000': [Errno 2] No such file or directory

Похоже, либо код не скопирован в контейнер (с именем 'web'), либо команда запущена из корневого / домашнего каталога, где manage.py недоступен.

1. Код доступен на контейнере? Как проверить?

Обычно docker просто выполняет команды в контейнере и завершает работу, если нет незавершенной запущенной задачи (например, сервер работает в фоновом режиме). Чтобы прекратить выход и включить его отладку, добавим команду running , чтобы вы могли войти в container и посмотреть, присутствует ли код.

команда: tail -f / dev / null # трюк для поддержки docker в режиме отладки.

docker -compose.yml

  web:
    restart: always
    build: ./web
    expose:
      - "8000"
    links:
      - mysql:mysql
    volumes:
      - web-django:/usr/src/app
      - web-static:/usr/src/app/static
    #env_file: web/venv
    environment:
      DEBUG: 'true'
    command: tail -f /dev/null #trick to keep the docker alive for debug mode.
Войдите в контейнер 'web', запустите из командной строки docker exec -it web bash

Проверьте наличие файлов проекта, теперь вы можете запустить команду python manage.py runserver 8000 вручную. Если это работает, то мы можем быть уверены, что сервер может работать на контейнере. Теперь мы можем проанализировать начальный рабочий каталог.

Если код присутствует, проверьте, почему manage.py не найден? Установлен ли рабочий каталог? означает, что контейнер знает, что является базовым каталогом для запуска команды?

Укажите, какой рабочий каталог находится в Dockerfile перед Вы копируете файлы проекта в контейнер.

Dockerfile в веб-каталоге

        ENV PYTHONUNBUFFERED 1
        ARG PROJ_DIR=/usr/project/web
        RUN mkdir -p $PROJ_DIR
        WORKDIR $PROJ_DIR
        COPY . $WORKDIR

docker -compose.yml

        restart: always
        build: ./web
        expose:
          - "8000"
        links:
          - mysql:mysql
        volumes:
          - web-django:/usr/src/app
          - web-static:/usr/src/app/static
        #env_file: web/venv
        environment:
          DEBUG: 'true'
        command: python manage.py runserver 0.0.0.0:8000 #note this command is triggered from $WORKDIR that we set in Dockerfile.

Я думаю, что это должно решить проблему или помочь вам выяснить проблему.

0 голосов
/ 06 февраля 2020

В директиве command:, если вы используете синтаксис массива, вы несете ответственность за разбиение команды на слова. Как вы показали, вы запускаете эквивалент python "manage.py runserver 0.0.0.0:8000" в приглашении оболочки, и он должным образом рассматривает всю команду и параметры в качестве имени файла сценария, который должен быть запущен, включая пробелы. Если разбить это на отдельные слова, оно будет работать лучше

command: ["python", "manage.py", "runserver", "0.0.0.0:8000"]

Но на самом деле нет никакой причины указывать это в docker-compose.yml. Это команда по умолчанию, которую вы хотите запустить для запуска контейнера, независимо от того, как вы его запустили, поэтому она должна быть командой по умолчанию в Dockerfile

...
EXPOSE 8000
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]

. Вам не нужно links: вообще на современном Docker (Docker Compose автоматически настраивает межконтейнерную сеть для вас ). Вы определенно не хотите монтировать именованные тома поверх кода своего приложения: это скрывает то, что находится в вашем образе, и (поскольку вы сказали Docker, что это важные пользовательские данные) заставляет Docker использовать старую версию вашего приложение, если вы пытаетесь обновить свое изображение.

Это оставляет вам более простой docker-compose.yml файл:

version: '3'      
services:
  web:
    restart: always
    build: ./web
    ports:           # to access the container from outside
      - "8000:8000"
    environment:
      DEBUG: 'true'

  mysql:
    restart: always
    image: mysql:5.7
    environment:
      MYSQL_DATABASE: 'maps_data'
      MYSQL_USER: 'chicommons'
      MYSQL_PASSWORD: 'password'
      MYSQL_ROOT_PASSWORD: 'password'
    ports:
      - "3406:3306"  # second port is always container-internal port
    volumes:
      - my-db:/var/lib/mysql

volumes:
  my-db:
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...