Dockerコンテナで複数のプログラムを実行できますか?


150

デスクトップ上のユーザーで実行することを目的としたアプリケーションをデプロイするという点から、Dockerに頭を抱えようとしています。私のアプリケーションは単にフラスコWebアプリケーションとmongoデータベースです。通常、私はVMにインストールし、ホストポートをゲストWebアプリに転送します。Dockerを試してみたいのですが、複数のプログラムをどのように使用するつもりなのかわかりません。ドキュメンテーションには、ENTRYPOINTしか存在しないと記載されているので、Mongoとフラスコアプリケーションをどのように使用できますか。または、それらを別々のコンテナーに入れる必要がありますか?その場合、どのようにして互いに対話し、これによりアプリの配布が簡単になりますか?


2
しかしさんは答えが私たちに教えて何を見てみましょう... - ..ドッキングウィンドウはとても人気があった理由は、私は思ってしまう(単一のプロセス..?):上のスポット
javadba

回答:


120

ENTRYPOINTは1つしか存在できませんが、そのターゲットは通常、必要な数のプログラムを起動するスクリプトです。さらに、たとえばスーパーバイザーなどを使用して、単一のコンテナー内で複数のサービスを起動することもできます。これは、単一のコンテナー内でmysql、apache、およびwordpressを実行するdockerコンテナーの例です

たとえば、単一のWebアプリケーションで使用されるデータベースが1つあるとします。そうすれば、おそらく両方を1つのコンテナーで実行する方が簡単です。

複数のアプリケーションで使用される共有データベースがある場合は、データベースを独自のコンテナで実行し、アプリケーションをそれぞれ独自のコンテナで実行することをお勧めします。

アプリケーションが異なるコンテナで実行されている場合、アプリケーションが互いに通信するには、少なくとも2つの可能性があります。

  1. 公開されたIPポートを使用し、それらを介して接続します。
  2. 最近のdockerバージョンはリンクをサポートしています。

1
新しいバージョンのDockerがDockerコンテナネットワークをサポートするようです
jpierson 2016

Dockerはスーパーバイザーの実行をサポートするようになり、autorestart = true、stdout_logfile、stderr_logfileなどの各プロセスの動作を指定できるようになりました。docs.docker.com/ engine / admin / using_supervisord
Andreas Lundgren

4
この例では、Webアプリケーションとmongodbを同じコンテナで実行することをお勧めしません。Dockerには監視対象または類似のinitのようなプロセスの良いユースケースがありますが、これはそれらの一部ではありません。docker-composeを使用して、2つのサービスを別々のコンテナーで実行する方が簡単です。
nicolas-van 2018

@ nicolas-vanなぜシンプルなのですか?それは、データベースが停止した場合に、全体を再起動する代わりに、データベースのコンテナを再起動できるからですか?
brillout

同じマシン上のアプリケーションは、Unixドメインソケットを介して通信することもできます。最高のパフォーマンスが保証されています。
懐疑的なジュール

21

LAMPスタック、Mongo DB、および自分のサービスを実行するという同様の要件がありました

DockerはOSベースの仮想化であるため、実行中のプロセスの周囲でコンテナーを分離するため、FOREGROUNDで実行されているプロセスが少なくとも1つ必要です。

したがって、独自の起動スクリプトをエントリポイントとして提供することで、起動スクリプトが拡張Dockerイメージスクリプトになり、少なくとも1つのフォアグラウンドサービスが開始されていて、終わりに近づいている限り、任意の数のサービスをスタックできます。

したがって、私のDockerイメージファイルの最後には2行あります。

COPY myStartupScript.sh /usr/local/myscripts/myStartupScript.sh
CMD ["/bin/bash", "/usr/local/myscripts/myStartupScript.sh"]

私のスクリプトでは、MySQL、MongoDB、Tomcatなどをすべて実行します。最後に、Apacheをフォアグラウンドスレッドとして実行します。

source /etc/apache2/envvars
/usr/sbin/apache2 -DFOREGROUND

これにより、すべてのサービスを開始し、最後のサービスがフォアグラウンドで開始された状態でコンテナーを存続させることができます

それが役に立てば幸い

更新:私がこの質問に最後に回答して以来、Docker composeのような新しいものが登場しました。これにより、各サービスを独自のコンテナーで実行しながら、それらすべてをそれらのサービス間の依存関係としてバインドし、docker-composeとそれを使用してください、あなたのニーズがそれに一致しない限り、それはよりエレガントな方法です。


6

同じコンテナで両方のサービスを実行することを推奨していた以前のいくつかのソリューションには強く同意しません。推奨されていないことがドキュメントに明記されている

コンテナーごとに1つのサービスを使用して、問題のある領域を分離することをお勧めします。そのサービスは複数のプロセスに分岐する場合があります(たとえば、Apache Webサーバーは複数のワーカープロセスを開始します)。複数のプロセスを持つことは問題ありませんが、Dockerから最大の利益を得るには、1つのコンテナーがアプリケーション全体の複数の側面に関与することを避けてください。ユーザー定義のネットワークと共有ボリュームを使用して、複数のコンテナーを接続できます。

スーパーバイザまたは同様のプログラムには適切な使用例がありますが、Webアプリケーション+データベースの実行はそれらの一部ではありません。

そのためには、必ずdocker-composeを使用し、責任の異なる複数のコンテナーを調整する必要があります。


2
これはコメントであり、回答ではありません。このポジションをサポートする説明やリンクを追加することを検討してください。それ以外の場合は役に立ちません。
Ivan Ivanov

1
これは、そのようなユースケースで私ができる最高の推奨はdocker-composeを使用することであるという意味での答えです。とにかく、私が公式の勧告へのより多くのリンクを与えることができるのはあなたの言う通りです。更新します。
nicolas-van

質問は、1つのコンテナーで2つのプロセスを実行することに関するものであるため、ベストプラクティスについては気にしません。例を挙げましょう。PhotonOSベースのイメージとJavaプロセス内でrabbitmqも実行する必要があったので、エントリスクリプトを使用してENTRYPOINTとして使用しました:)
Vallerious

元の質問は、Dockerコンテナで2つのプロセスを実行する技術的な実現可能性に関する一般的な質問ではありません。これは、MongoDBデータベースと共にPythonアプリケーションをデプロイするという特定の使用例を示しています。そして、そのユースケースでは、単一のコンテナの使用をやめ、docker-composeの使用を推奨するのが最善の方法です。
nicolas-van

5

それらは別々のコンテナに置くことができ、実際、アプリケーションがより大きな環境で実行することも意図されていた場合、おそらくそうなります。

マルチコンテナシステムでは、必要なすべての依存関係を有効にするには、さらにオーケストレーションが必要になりますが、Docker v0.6.5 +では、Docker自体に組み込まれていることを支援する新しい機能- リンクがあります。ただし、マルチマシンソリューションの場合は、Docker環境の外部から配置する必要があります。

2つの異なるコンテナーを使用しても、2つの部分は引き続きTCP / IPを介して通信しますが、ポートが特にロックダウンされていない限り(複数のコピーを実行できないためお勧めできません)、新しいポートを渡す必要があります。アプリケーションに関してデータベースが公開されているため、Mongoと通信できる。これも、Linkingが役立ちます。

すべての依存関係が同じコンテナーで行われる、より単純で小規模なインストールの場合、最初にENTRYPOINTとして呼び出されるプログラムによってデータベースとPythonランタイムの両方を起動することも可能です。これは、シェルスクリプト、または他のいくつかのプロセスコントローラとしてシンプルにすることができます- Supervisordは非常に人気があり、多くの例では、公共Dockerfilesに存在します。


3

2つのコンテナーを使用することが望ましいという他の回答にも同意しますが、単一のコンテナーに複数のサービスをまとめることに心を決めている場合は、監視対象のようなものを使用できます。

Hipache例えば、含まDockerfileはsupervisordを実行し、hipacheとのRedisサーバの両方のファイルsupervisord.confの指定が実行されるように。


2

Dockerは、その方法の例をいくつか提供しています。軽量オプションは次のとおりです。

すべてのコマンドをラッパースクリプトに入れ、テストおよびデバッグ情報を完備します。としてラッパースクリプトを実行しますCMD。これは非常に単純な例です。まず、ラッパースクリプト:

#!/bin/bash

# Start the first process
./my_first_process -D
status=$?
if [ $status -ne 0 ]; then
  echo "Failed to start my_first_process: $status"
  exit $status
fi

# Start the second process
./my_second_process -D
status=$?
if [ $status -ne 0 ]; then
  echo "Failed to start my_second_process: $status"
  exit $status
fi

# Naive check runs checks once a minute to see if either of the processes exited.
# This illustrates part of the heavy lifting you need to do if you want to run
# more than one service in a container. The container will exit with an error
# if it detects that either of the processes has exited.
# Otherwise it will loop forever, waking up every 60 seconds

while /bin/true; do
  ps aux |grep my_first_process |grep -q -v grep
  PROCESS_1_STATUS=$?
  ps aux |grep my_second_process |grep -q -v grep
  PROCESS_2_STATUS=$?
  # If the greps above find anything, they will exit with 0 status
  # If they are not both 0, then something is wrong
  if [ $PROCESS_1_STATUS -ne 0 -o $PROCESS_2_STATUS -ne 0 ]; then
    echo "One of the processes has already exited."
    exit -1
  fi
  sleep 60
done

次に、Dockerfile:

FROM ubuntu:latest
COPY my_first_process my_first_process
COPY my_second_process my_second_process
COPY my_wrapper_script.sh my_wrapper_script.sh
CMD ./my_wrapper_script.sh

2

を使用すると、2つのプロセスをフォアグラウンドで実行できますwait。次の内容でbashスクリプトを作成するだけです。例start.sh

# runs 2 commands simultaneously:

mongod & # your first application
P1=$!
python script.py & # your second application
P2=$!
wait $P1 $P2

Dockerfileで、

CMD bash start.sh

0

専用スクリプトがオーバーヘッドが大きすぎるように見える場合は、を使用して個別のプロセスを明示的に生成できますsh -c。例えば:

CMD sh -c 'mini_httpd -C /my/config -D &' \
 && ./content_computing_loop
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.