web-dev-qa-db-ja.com

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
337
Brett Cullen

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"
601
Brett Cullen

私は、移行のようなスタートアップ前のものを別の一時的なコンテナで実行しています。

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つの事柄:

  1. 正しい起動シーケンスを確実にする必要があります(depends_onを使用)

  2. buildとimageを使って最初のラウンドでタグ付けすることによって達成される複数のビルドを避けたいです。あなたはそれから他の容器の画像を参照することができます

127
Bjoern Stiel

私は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 - 私の開発サーバーを起動します
42
LondonAppDev

もう一つのアイデア:

この場合のように、コンテナを構築するのであれば、その中に起動スクリプトを置いて、これをcommandで実行するだけです。または起動スクリプトをボリュームとしてマウントします。

17
rweng

ここでエントリーポイントを使うことができます。 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をあなたのコードと一緒にコピーすることを忘れないでください。

17
Harshad Yeola

これは私のために働く:

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質問から、子プロセスの出力を標準出力にリダイレクトできることがわかりました。 このようにして、すべての出力を確認できます。

3
Tim Tisdall

*更新*

いくつかのコマンドを実行する最良の方法は、公式の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

それで、これはモンゴをフォークし、モノインポートし、そして分離されたフォークされたモンゴを殺し、そして分離せずにそれを再び起動する。分岐したプロセスにアタッチする方法があるかどうかわからないが、これはうまくいきます。

3
radtek

Wait-it-itや dockerize などのツールを使用してください。これらはあなたのアプリケーションのイメージに含めることができる小さなラッパースクリプトです。あるいは、アプリケーション固有のコマンドを実行するための独自のラッパースクリプトを作成してください。に従って: https://docs.docker.com/compose/startup-order/

1
Eran

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
0
Jason Anderson