このようにして、複数のコマンドを順番に実行できるようにしたいと思います。
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
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"
私は、移行のようなスタートアップ前のものを別の一時的なコンテナで実行しています。
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
これは物事をきれいにして別々に保つのを助けます。考慮するべき2つの事柄:
正しい起動シーケンスを確実にする必要があります(depends_onを使用)
buildとimageを使って最初のラウンドでタグ付けすることによって達成される複数のビルドを避けたいです。あなたはそれから他の容器の画像を参照することができます
私は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
- 私の開発サーバーを起動しますもう一つのアイデア:
この場合のように、コンテナを構築するのであれば、その中に起動スクリプトを置いて、これをcommandで実行するだけです。または起動スクリプトをボリュームとしてマウントします。
ここでエントリーポイントを使うことができます。 dockerのentrypointはコマンドの前に実行されますが、whileコマンドはコンテナの起動時に実行されるデフォルトのコマンドです。そのため、ほとんどのアプリケーションは通常、エントリポイントファイルでセットアップ手順を実行し、最後にはコマンドの実行を許可します。
シェルスクリプトファイルの作成は、以下の内容を含む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
P.Sとしてコマンドを登録します。docker-entrypoint.sh
をあなたのコードと一緒にコピーすることを忘れないでください。
これは私のために働く:
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はコマンドを実行している変数beforeを間接参照しようとします。そのため、bashに変数を処理させたい場合は、ドル記号を2倍にしてエスケープする必要があります。
command:
- /bin/bash
- -c
- |
var=$$(echo 'foo')
echo $$var # prints foo
それ以外の場合はエラーになります。
サービス "web"の "command"オプションの補間形式が無効です。
複数のデーモンプロセスを実行する必要がある場合は、すべてのサブデーモンが標準出力に出力されるように、デタッチされていないモードで Supervisordを使用するためのDockerドキュメントの提案 があります。
別のSO質問から、子プロセスの出力を標準出力にリダイレクトできることがわかりました。 このようにして、すべての出力を確認できます。
*更新*
いくつかのコマンドを実行する最良の方法は、公式のCMDがイメージから実行される前に必要なことをすべて実行するカスタムDockerfileを作成することです。
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)
これはおそらく最もクリーンな方法です。
*オールドウェイ*
私は自分のコマンドでシェルスクリプトを作成しました。この場合、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
それで、これはモンゴをフォークし、モノインポートし、そして分離されたフォークされたモンゴを殺し、そして分離せずにそれを再び起動する。分岐したプロセスにアタッチする方法があるかどうかわからないが、これはうまくいきます。
Wait-it-itや dockerize などのツールを使用してください。これらはあなたのアプリケーションのイメージに含めることができる小さなラッパースクリプトです。あるいは、アプリケーション固有のコマンドを実行するための独自のラッパースクリプトを作成してください。に従って: https://docs.docker.com/compose/startup-order/
Jenkinsユーザーとしてdockerコンテナを構築するためにjenkinsコンテナをセットアップしようとしているときに、私はこれに遭遇しました。
後でdocker-composeファイルにリンクするときに、Dockerfileのdocker.sockファイルに触れる必要がありました。最初に触れない限り、まだ存在していません。これは私のために働きました。
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