Как собрать из исходного кода несколько сервисов с помощью 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