Как собрать из исходного кода несколько сервисов с помощью docker-compose и создать единый образ?

Я пытаюсь создать несколько контейнеров для моего приложения Python/Django под названием controller, и я хотел бы, чтобы контейнеры запускались в одном образе, а не в двух. Проблема в том, что мой файл docker-compose.yml собирает два сервиса из исходного кода и в результате генерирует два разделенных образа. Приложение состоит из 5 сервисов: проект Django, Celery (worker, beat, flower) и Redis.

Как я могу сказать docker-compose, чтобы он собирал django и redis службы из исходного кода и создавал все службы в одном образе?

Я пробовал заменить image: image: controller-redis на image: controller и он создает уникальный образ со всеми службами, но большинство из них не запускаются, потому что файлы не найдены :

Вывод журналов :

$ docker-compose logs -f
controller-celery_beat-1    | /usr/local/bin/docker-entrypoint.sh: 24: exec: /start-celerybeat: not found
controller-django-1         | /usr/local/bin/docker-entrypoint.sh: 24: exec: /start: not found
controller-flower-1         | /usr/local/bin/docker-entrypoint.sh: 24: exec: /start-flower: not found
[...]
controller-celery_worker-1  | /usr/local/bin/docker-entrypoint.sh: 24: exec: /start-celeryworker: not found

Docker-compose ps

$ docker-compose ps
NAME                         COMMAND                  SERVICE             STATUS              PORTS
controller-celery_beat-1     "docker-entrypoint.s…"   celery_beat         exited (127)        
controller-celery_worker-1   "docker-entrypoint.s…"   celery_worker       exited (127)        
controller-django-1          "docker-entrypoint.s…"   django              exited (127)        
controller-flower-1          "docker-entrypoint.s…"   flower              exited (127)        
controller-redis-1           "docker-entrypoint.s…"   redis               running             6378-6379/tcp

docker-compose.yml

version: '3.8'

services:
  django:
    build:
      context: .
      dockerfile: ./compose/local/django/Dockerfile
    image: controller
    command: /start
    volumes:
      - .:/app
    ports:
      - "8001:8001"
    env_file:
      - controller/.env
    depends_on:
      - redis
    networks:
      - mynetwork

  redis:
    build:
      context: .
      dockerfile: ./compose/local/redis/Dockerfile
    image: controller-redis # <------------------ modification was done here
    expose:
      - "6378"
    networks:
      - mynetwork

  celery_worker:
    image: controller
    command: /start-celeryworker
    volumes:
      - .:/app:/controller
    env_file:
      - controller/.env
    depends_on:
      - redis
      - controller
    networks:
      - mynetwork

  celery_beat:
    image: controller
    command: /start-celerybeat
    volumes:
      - .:/app:/controller
    env_file:
      - controller/.env
    depends_on:
      - redis
      - controller
    networks:
      - mynetwork

  flower:
    image: controller
    command: /start-flower
    volumes:
      - .:/app:/controller
    env_file:
      - controller/.env
    depends_on:
      - redis
      - controller
    networks:
      - mynetwork

networks:
  mynetwork:
    name: mynetwork

compose/local/django/Dockerfile

FROM python:3.10

ENV PYTHONUNBUFFERED 1
ENV PYTHONDONTWRITEBYTECODE 1

RUN apt-get update \
  && apt-get install -y build-essential \
  && apt-get install -y libpq-dev \
  && apt-get install -y gettext \
  && apt-get install -y git \
  && apt-get install -y openssh-client \
  && apt-get install -y libcurl4-openssl-dev libssl-dev \
  && apt-get install -y nano \
  && rm -rf /var/lib/apt/lists/*

COPY ./requirements.txt /requirements.txt
RUN pip install -r /requirements.txt

COPY ./compose/local/django/entrypoint /entrypoint
RUN chmod +x /entrypoint

COPY ./compose/local/django/start /start
RUN chmod +x /start

COPY ./compose/local/django/celery/worker/start /start-celeryworker
RUN chmod +x /start-celeryworker

COPY ./compose/local/django/celery/beat/start /start-celerybeat
RUN chmod +x /start-celerybeat

COPY ./compose/local/django/celery/flower/start /start-flower
RUN chmod +x /start-flower

WORKDIR /app

ENTRYPOINT ["/entrypoint"]

compose/local/redis/Dockerfile

FROM redis

RUN apt-get update \
  && apt-get install -y wget \
  && wget -O redis.conf 'http://download.redis.io/redis-stable/redis.conf' \
  && mkdir /usr/local/etc/redis \
  && cp redis.conf /usr/local/etc/redis/redis.conf

RUN sed -i '/protected-mode yes/c\protected-mode no' /usr/local/etc/redis/redis.conf \
  && sed -i '/bind 127.0.0.1 -::1/c\bind * -::*' /usr/local/etc/redis/redis.conf \
  && sed -i '/port 6379/c\port 6378' /usr/local/etc/redis/redis.conf

CMD [ "redis-server", "/usr/local/etc/redis/redis.conf" ]

WORKDIR /app

compose/local/django/start

#!/bin/bash

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

python manage.py runserver 0.0.0.0:8001

compose/local/django/celery/beat

#!/bin/bash

set -o errexit
set -o nounset

rm -f './celerybeat.pid'

# watch only .py files
watchfiles \
  --filter python \
  'celery -A controller beat -l info --scheduler django_celery_beat.schedulers:DatabaseScheduler'

compose/local/django/celery/worker

#!/bin/bash

set -o errexit
set -o nounset

# watch only .py files
watchfiles \
  --filter python \
  'celery -A controller worker --loglevel=info -Q controller_queue_1,controller_queue_2,default'

compose/local/django/celery/flower

#!/bin/bash

set -o errexit
set -o nounset

worker_ready() {
    celery -A controller inspect ping
}

until worker_ready; do
  >&2 echo 'Celery workers not available'
  sleep 1
done
>&2 echo 'Celery workers is available'

celery -A controller  \
    --broker="${CELERY_BROKER}" \
    flower

Файлы проектов

docker-compose.yml
controller/
    compose/
        local/
            django/
                Dockerfile
                entrypoint
                start
                celery/
                    beat/
                        start
                    flower/
                        start
                    worker/
                        start
            redis/
                Dockerfile
Вернуться на верх