Использование Docker-Compose, как выполнять несколько команд
Я хочу сделать что-то вроде этого, где я могу запускать несколько команд в порядке.
db:
image: postgres
web:
build: .
command: python manage.py migrate
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/code
ports:
- "8000:8000"
links:
- db
Ответы
Ответ 1
bash -c
, используйте bash -c
.
Пример:
command: bash -c "python manage.py migrate && python manage.py runserver 0.0.0.0:8000"
Тот же пример в мультилинии:
command: >
bash -c "python manage.py migrate
&& python manage.py runserver 0.0.0.0:8000"
Или же:
command: bash -c "
python manage.py migrate
&& python manage.py runserver 0.0.0.0:8000
"
Ответ 2
Я запускаю материал перед запуском, например, миграции в отдельном эфемерном контейнере, например (примечание, файл компоновки должен иметь тип версии "2" ):
db:
image: postgres
web:
image: app
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/code
ports:
- "8000:8000"
links:
- db
depends_on:
- migration
migration:
build: .
image: app
command: python manage.py migrate
volumes:
- .:/code
links:
- db
depends_on:
- db
Это помогает держать вещи в чистоте и разделить. Две вещи, которые следует учитывать:
-
Вы должны обеспечить правильную последовательность запуска (используя параметр depend_on)
-
вы хотите избежать нескольких сборок, которые достигаются путем пометки его в первый раз с использованием сборки и изображения; вы можете ссылаться на изображение в других контейнерах, затем
Ответ 3
Я рекомендую использовать sh
а не bash
потому что он более доступен для большинства образов на основе Unix (alpine и т.д.).
Вот пример docker-compose.yml
:
version: '3'
services:
app:
build:
context: .
command: >
sh -c "python manage.py wait_for_db &&
python manage.py migrate &&
python manage.py runserver 0.0.0.0:8000"
Это вызовет следующие команды по порядку:
-
python manage.py wait_for_db
- дождаться готовности БД -
python manage.py migrate
- запускать любые миграции -
python manage.py runserver 0.0.0.0:8000
- запустить мой сервер разработки
Ответ 4
Здесь вы можете использовать точку входа. точка входа в докер выполняется перед командой, а команда - это команда по умолчанию, которая должна запускаться при запуске контейнера.
Таким образом, большинство приложений обычно выполняют процедуру настройки в файле точки входа, а в последнем случае они позволяют запускать команду.
сделать файл оболочки script может быть как docker-entrypoint.sh
(имя не имеет значения) со следующим содержимым в нем.
#!/bin/bash
python manage.py migrate
exec "[email protected]"
в файле docker-compose.yml используйте его с entrypoint: /docker-entrypoint.sh
и зарегистрируйте команду как command: python manage.py runserver 0.0.0.0:8000
P.S: не забудьте скопировать docker-entrypoint.sh
вместе с вашим кодом.
Ответ 5
Другая идея:
Если, как в этом случае, вы создаете контейнер, просто разместите в нем запуск script и запустите его с помощью команды. Или установите запуск script в качестве тома.
Ответ 6
Это работает для меня:
version: '3.1'
services:
db:
image: postgres
web:
build: .
command:
- /bin/bash
- -c
- |
python manage.py migrate
python manage.py runserver 0.0.0.0:8000
volumes:
- .:/code
ports:
- "8000:8000"
links:
- db
docker-compose пытается разыменовать переменные перед запуском команды, поэтому, если вы хотите, чтобы bash обрабатывал переменные, вам нужно экранировать знаки доллара, удваивая их...
command:
- /bin/bash
- -c
- |
var=$$(echo 'foo')
echo $$var # prints foo
... в противном случае вы получите ошибку:
Неверный формат интерполяции для опции "команда" в сервисе "сеть":
Ответ 7
* ОБНОВИТЬ *
Я подумал, что лучший способ запустить некоторые команды - написать собственный Dockerfile, который делает все, что я хочу, до запуска официального CMD из образа.
докер-compose.yaml:
version: '3'
# Can be used as an alternative to VBox/Vagrant
services:
mongo:
container_name: mongo
image: mongo
build:
context: .
dockerfile: deploy/local/Dockerfile.mongo
ports:
- "27017:27017"
volumes:
- ../.data/mongodb:/data/db
Dockerfile.mongo:
FROM mongo:3.2.12
RUN mkdir -p /fixtures
COPY ./fixtures /fixtures
RUN (mongod --fork --syslog && \
mongoimport --db wcm-local --collection clients --file /fixtures/clients.json && \
mongoimport --db wcm-local --collection configs --file /fixtures/configs.json && \
mongoimport --db wcm-local --collection content --file /fixtures/content.json && \
mongoimport --db wcm-local --collection licenses --file /fixtures/licenses.json && \
mongoimport --db wcm-local --collection lists --file /fixtures/lists.json && \
mongoimport --db wcm-local --collection properties --file /fixtures/properties.json && \
mongoimport --db wcm-local --collection videos --file /fixtures/videos.json)
Это, наверное, самый чистый способ сделать это.
* СТАРЫЙ ПУТЬ *
Я создал сценарий оболочки с моими командами. В этом случае я хотел запустить mongod
и запустить mongoimport
но вызов mongod
блокирует запуск остальных.
docker-compose.yaml:
version: '3'
services:
mongo:
container_name: mongo
image: mongo:3.2.12
ports:
- "27017:27017"
volumes:
- ./fixtures:/fixtures
- ./deploy:/deploy
- ../.data/mongodb:/data/db
command: sh /deploy/local/start_mongod.sh
start_mongod.sh:
mongod --fork --syslog && \
mongoimport --db wcm-local --collection clients --file /fixtures/clients.json && \
mongoimport --db wcm-local --collection configs --file /fixtures/configs.json && \
mongoimport --db wcm-local --collection content --file /fixtures/content.json && \
mongoimport --db wcm-local --collection licenses --file /fixtures/licenses.json && \
mongoimport --db wcm-local --collection lists --file /fixtures/lists.json && \
mongoimport --db wcm-local --collection properties --file /fixtures/properties.json && \
mongoimport --db wcm-local --collection videos --file /fixtures/videos.json && \
pkill -f mongod && \
sleep 2 && \
mongod
Так что это разветвляет монго, делает моногимпорт, а затем убивает раздвоенное монго, и снова запускает его, не отрываясь. Не уверен, есть ли способ присоединиться к разветвленному процессу, но это работает.
Ответ 8
Если вам нужно запустить более одного процесса демона, предложите предложение в документации Docker использовать Supervisord в режиме без отсоединения поэтому все суб-демоны будут выводиться на стандартный вывод.
Из другого вопроса SO я обнаружил, что вы можете перенаправить вывод дочерних процессов на stdout. Таким образом вы можете увидеть весь вывод!
Ответ 9
Используйте такой инструмент, как wait-for-it или dockerize. Это небольшие скрипты-оболочки, которые вы можете включить в образ приложений. Или напишите свою собственную оболочку script, чтобы выполнить больше команд приложения. в соответствии с: https://docs.docker.com/compose/startup-order/
Ответ 10
Я столкнулся с этим, пытаясь настроить мой контейнер jenkins для сборки докеров как пользователь jenkins.
Мне нужно было прикоснуться к файлу docker.sock в Dockerfile, так как я позже сошлюсь на него в файле docker-compose. Пока я не прикоснулся к нему первым, его еще не было. Это сработало для меня.
Dockerfile:
USER root
RUN apt-get update && \
apt-get -y install apt-transport-https \
ca-certificates \
curl \
software-properties-common && \
curl -fsSL https://download.docker.com/linux/$(. /etc/os-release;
echo "$ID")/gpg > /tmp/dkey; apt-key add /tmp/dkey && \
add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") \
$(lsb_release -cs) \
stable" && \
apt-get update && \
apt-get -y install docker-ce
RUN groupmod -g 492 docker && \
usermod -aG docker jenkins && \
touch /var/run/docker.sock && \
chmod 777 /var/run/docker.sock
USER Jenkins
докер-compose.yml:
version: '3.3'
services:
jenkins_pipeline:
build: .
ports:
- "8083:8083"
- "50083:50080"
volumes:
- /root/pipeline/jenkins/mount_point_home:/var/jenkins_home
- /var/run/docker.sock:/var/run/docker.sock
Ответ 11
Хотя это не совсем относится к вопросу, размещая его здесь, он помогает кому-то. Если вы хотите запустить команду перед запуском контейнера, вы можете запустить контейнер в обычном режиме. Затем войдите в контейнер и внесите изменения. Затем вы можете зафиксировать контейнер как новое изображение. Это новое изображение может использоваться для обеспечения того, чтобы все необходимые изменения существовали до запуска контейнера.
Ответ 12
В версии Docker Compose версии 2 (и в том числе 3) вы можете указать список аргументов, как в Dockerfile
:
version: '3'
# version: '2'
services:
app:
image: foo:1-bar
command: ["foo", "bar", "baz"]
Ответ 13
попробуйте использовать ";" отделить команды, если вы находитесь в двух вариантах
например.
command: "sleep 20; echo 'a'"