Answers:
想通了,使用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
"
sh
而是使用:[sh, -c, "cd /usr/src/app && npm start"]
ash
在高山上使用:)
我在单独的临时容器中运行诸如迁移之类的启动前内容(请注意,撰写文件的版本必须为“ 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
这有助于保持事物清洁和分离。要考虑的两件事:
您必须确保正确的启动顺序(使用depends_on)
您希望避免通过第一次使用构建和图像对其进行标记来实现多个构建;您可以在其他容器中引用图像
bash -c
上面的步骤。
我建议使用sh
而不是,bash
因为它在大多数基于Unix的图像(高山等)上更容易获得。
这是一个例子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
-启动我的开发服务器>
用于启动多线输入(参见stackoverflow.com/a/3790497/2220370)
这对我有用:
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
...否则,您将得到一个错误:
服务“ Web”中“命令”选项的无效插值格式:
$${Types}
和$${Client}
。我认为这将阻止docker compose解释这些变量并在您从其调用docker-compose的任何外壳中寻找它们的值,这意味着它们仍然存在以供bash取消引用(在 docker处理完您的.env
文件之后)。
您可以在此处使用入口点。docker中的入口点在命令之前执行,而command是容器启动时应运行的默认命令。因此,大多数应用程序通常在入口点文件中带有设置过程,最后它们允许命令运行。
制作一个shell脚本文件时,docker-entrypoint.sh
名称可能没有问题(名称无关紧要)。
#!/bin/bash
python manage.py migrate
exec "$@"
在docker-compose.yml文件中使用它,entrypoint: /docker-entrypoint.sh
并将命令注册为command: python manage.py runserver 0.0.0.0:8000
PS:不要忘记docker-entrypoint.sh
与您的代码一起复制。
docker-compose run service-name ....
*更新*
我认为运行某些命令的最佳方法是编写一个自定义Dockerfile,该文件可以在从映像运行官方CMD之前完成我想要的所有操作。
docker-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)
这可能是最干净的方法。
*老路*
我用命令创建了一个shell脚本。在这种情况下,我想启动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
因此,这会分叉mongo,进行monogimport,然后杀死已分离的分叉mongo,然后在不分离的情况下再次启动它。不知道是否有一种方法可以附加到派生的进程上,但这确实可行。
注意:如果您严格要加载一些初始数据库数据,这是这样做的方法:
mongo_import.sh
#!/bin/bash
# Import from fixtures
# Used in build and docker-compose mongo (different dirs)
DIRECTORY=../deploy/local/mongo_fixtures
if [[ -d "/fixtures" ]]; then
DIRECTORY=/fixtures
fi
echo ${DIRECTORY}
mongoimport --db wcm-local --collection clients --file ${DIRECTORY}/clients.json && \
mongoimport --db wcm-local --collection configs --file ${DIRECTORY}/configs.json && \
mongoimport --db wcm-local --collection content --file ${DIRECTORY}/content.json && \
mongoimport --db wcm-local --collection licenses --file ${DIRECTORY}/licenses.json && \
mongoimport --db wcm-local --collection lists --file ${DIRECTORY}/lists.json && \
mongoimport --db wcm-local --collection properties --file ${DIRECTORY}/properties.json && \
mongoimport --db wcm-local --collection videos --file ${DIRECTORY}/videos.json
mongo_fixtures / *。json文件是通过mongoexport命令创建的。
docker-compose.yaml
version: '3'
services:
mongo:
container_name: mongo
image: mongo:3.2.12
ports:
- "27017:27017"
volumes:
- mongo-data:/data/db:cached
- ./deploy/local/mongo_fixtures:/fixtures
- ./deploy/local/mongo_import.sh:/docker-entrypoint-initdb.d/mongo_import.sh
volumes:
mongo-data:
driver: local
如果您需要运行多个守护进程,则Docker文档中建议在非分离模式下使用Supervisord,以便所有子守护程序都将输出到stdout。
从另一个SO问题中,我发现您可以将子进程的输出重定向到stdout。 这样,您可以看到所有输出!
使用来在docker-compose文件中运行多个命令bash -c
。
command: >
bash -c "python manage.py makemigrations
&& python manage.py migrate
&& python manage.py runserver 0.0.0.0:8000"
来源:https : //intellipaat.com/community/19590/docker-run-multiple-commands-using-docker-compose-at-once?show=19597#a19597
使用诸如wait-for-it或dockerize之类的工具。这些是小的包装脚本,您可以将其包含在应用程序的映像中。或编写自己的包装器脚本以执行更多特定于应用程序的命令。根据:https : //docs.docker.com/compose/startup-order/
我在尝试将我的jenkins容器设置为以jenkins用户身份构建docker容器时遇到了这个问题。
我需要触摸Dockerfile中的docker.sock文件,稍后再在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
docker-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
/bin/bash