Почему мой образ docker не запускается при использовании docker run (image), но я могу запускать контейнеры, созданные с помощью docker-compose up?

Мой docker-compose создает 3 контейнера — django, celery и rabbitmq. Когда я запускаю следующие команды -> docker-compose build и docker-compose up, контейнеры запускаются успешно.

Однако у меня возникли проблемы с развертыванием образа. Сгенерированное изображение имеет идентификатор изображения 24d7638e2aff. Однако по какой-то причине, если я просто запущу приведенную ниже команду, ничего не произойдет с выходом 0. Приложения django и celery имеют одинаковый идентификатор изображения.

docker run 24d7638e2aff

Это нехорошо, так как я не могу развернуть этот образ в kubernetes. Моя единственная мысль заключается в том, что файл докеров был настроен неправильно, но я не могу понять, в чем причина.

docker-compose.yaml

version: "3.9"
services:
  django:
    container_name: testapp_django
    build:
      context: .
      args:
        build_env: production
    ports:
      - "8000:8000"
    command: >
      sh -c "python manage.py migrate &&
             python manage.py runserver 0.0.0.0:8000"

    volumes:
      - .:/code
    links:
      - rabbitmq
      - celery

  rabbitmq:
    container_name: testapp_rabbitmq
    restart: always
    image: rabbitmq:3.10-management
    ports:
      - "5672:5672" # specifies port of queue
      - "15672:15672" # specifies port of management plugin

  celery:
    container_name: testapp_celery
    restart: always
    build:
      context: .
      args:
        build_env: production
    command: celery -A testapp worker -l INFO -c 4
    depends_on:
      - rabbitmq

Докерфайл

ARG PYTHON_VERSION=3.9-slim-buster

# define an alias for the specfic python version used in this file.
FROM python:${PYTHON_VERSION} as python

# Python build stage
FROM python as python-build-stage

ARG build_env

# Install apt packages
RUN apt-get update && apt-get install --no-install-recommends -y \
  # dependencies for building Python packages
  build-essential \
  # psycopg2 dependencies
  libpq-dev

# Requirements are installed here to ensure they will be cached.
COPY ./requirements .

# Create Python Dependency and Sub-Dependency Wheels.
RUN pip wheel --wheel-dir /usr/src/app/wheels  \
  -r ${build_env}.txt


# Python 'run' stage
FROM python as python-run-stage

ARG build_env
ARG APP_HOME=/app

ENV PYTHONUNBUFFERED 1
ENV PYTHONDONTWRITEBYTECODE 1
ENV BUILD_ENV ${build_env}

WORKDIR ${APP_HOME}

RUN addgroup --system appuser \
    && adduser --system --ingroup appuser appuser

# Install required system dependencies
RUN apt-get update && apt-get install --no-install-recommends -y \
  # psycopg2 dependencies
  libpq-dev \
  # Translations dependencies
  gettext \
  # git for GitPython commands
  git-all \
  # cleaning up unused files
  && apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \
  && rm -rf /var/lib/apt/lists/*

# All absolute dir copies ignore workdir instruction. All relative dir copies are wrt to the workdir instruction
# copy python dependency wheels from python-build-stage
COPY --from=python-build-stage /usr/src/app/wheels  /wheels/

# use wheels to install python dependencies
RUN pip install --no-cache-dir --no-index --find-links=/wheels/ /wheels/* \
  && rm -rf /wheels/


COPY --chown=appuser:appuser ./docker_scripts/entrypoint /entrypoint
RUN sed -i 's/\r$//g' /entrypoint
RUN chmod +x /entrypoint


# copy application code to WORKDIR
COPY --chown=appuser:appuser . ${APP_HOME}

# make appuser owner of the WORKDIR directory as well.
RUN chown appuser:appuser ${APP_HOME}
USER appuser

EXPOSE 8000

ENTRYPOINT ["/entrypoint"]

входная точка

#!/bin/bash

set -o errexit
set -o pipefail
set -o nounset

exec "$@"

Как создать образы этих контейнеров, чтобы развернуть их на k8s?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
1
67
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Я думаю, это потому, что команды для запуска сервера django находятся в файле docker-compose.yml.

Вы должны переместить эти команды внутрь точки входа.

set -o errexit
set -o pipefail
set -o nounset

python manage.py migrate && python manage.py runserver 0.0.0.0:8000
exec "$@"

Обратите внимание, что эта команда python manage.py runserver 0.0.0.0:8000 запустит приложение с сервера разработки, который нельзя использовать в производственных целях.

Вы должны искать gunicorn или аналогичный.

Я попробовал это, и теперь серверная часть работает нормально, но сельдерей вообще не загружается, даже при попытке запустить его в автономном режиме.

thecoder 18.11.2022 10:20

По этой же причине нужно переместить команду celery -A testapp worker -l INFO -c 4 в стартовый скрипт контейнера, иначе он не запустится.

HoliSimo 18.11.2022 10:31
Ответ принят как подходящий

Compose command: переопределяет Dockerfile CMD. docker run вообще не смотрит на docker-compose.yml файл, а docker run без какой-либо конкретной команды запускает CMD изображения. Вы ничего не объявили для этого, поэтому контейнер немедленно закрывается.

Оставьте сценарий точки входа без изменений (или даже удалите его полностью, так как он ничего не делает). Добавьте строку CMD в Dockerfile

CMD python manage.py migrate && python manage.py runserver 0.0.0.0:8000

Теперь просто docker run, как вы показали, он попытается запустить сервер Django. Для контейнера Celery вы все равно можете передать переопределение команды

docker run -d --net ... your-image \
  celery -A testapp worker -l INFO -c 4

Если вы выполняете развертывание в Kubernetes и сохраняете сценарий точки входа, вам нужно использовать args: в спецификации вашего модуля, чтобы предоставить альтернативную команду, а не command:.

Другие вопросы по теме