web-dev-qa-db-ja.com

Dockerコンテナーでサービスを自動的に実行する

Riak(NoSQLデータベース)を保持する単純なイメージをセットアップしています。イメージは、riak startをCMDとしてRiakサービスを開始します。これで、docker run -d quintenk/riak-devを使用してデーモンとして実行すると、Riakプロセスが開始されます(ログで確認できます)。ただし、数秒後に自動的に閉じます。 docker run -i -t quintenk/riak-dev /bin/bashを使用して実行すると、riakプロセスは開始されません(更新:この説明については回答を参照してください)。実際、サービスはまったく実行されていません。ターミナルを使用して手動で起動できますが、Riakが自動的に起動するようにします。この動作は他のサービスでも発生すると考えられますが、Riakは単なる例です。

そのため、コンテナーを実行/再起動すると、Riakが自動的に開始されます。これを設定する正しいアプローチは何ですか?


参照用に、イメージを作成できるDockerfileを以下に示します(更新:選択した回答を使用して変更されます)。

FROM ubuntu:12.04
RUN apt-get update
RUN apt-get install -y openssh-server curl 
RUN curl http://apt.basho.com/gpg/basho.apt.key | apt-key add -
RUN bash -c "echo deb http://apt.basho.com precise main > /etc/apt/sources.list.d/basho.list"
RUN apt-get update
RUN apt-get -y install riak
RUN Perl -p -i -e 's/(?<=\{http,\s\[\s\{")127\.0\.0\.1/0.0.0.0/g' /etc/riak/app.config
EXPOSE 8098 
CMD /bin/riak start && tail -F /var/log/riak/erlang.log.1

編集:CMDで-fを-Fに変更しました。


私自身の答え

しばらくの間Dockerで作業した後、supervisordを使用してプロセスを調整する習慣を取りました。そのためのサンプルコードが必要な場合は、 https://github.com/Krijger/docker-cookbooks をご覧ください。私は他のすべての画像のベースとしてスーパーバイザー画像を使用します。スーパーバイザー ここ を使用してブログを書きました。

35
qkrijger

Dockerコンテナを実行し続けるには、フォアグラウンドでプロセスをアクティブにしておく必要があります。

したがって、おそらくDockerfileの最後の行を次のように置き換えることができます。

CMD /bin/riak console

あるいは

CMD /bin/riak start && tail -F /var/log/riak/erlang.log.1

複数行のCMDステートメントを使用することはできず、最後のステートメントのみが実行されることに注意してください。

43
Gigablah

テールを使用してコンテナを存続させるのはハックです。また、-fオプションコンテナは、ログのローテーションが発生すると終了します(これは、-F代わりに)。

より良い解決策は supervisor を使用することです。これを見てください チュートリアル DockerコンテナーでのRiakの実行について。

32
sesm

「docker run -i -t quintenk/riak-dev/bin/bashを使用して実行すると、riakプロセスは開始されません」

コンテナに接続したときにのみログを監視できるようにしたいようです。私の使用例は、コマンドを自動的に開始したいという点で少し異なりますが、コンテナにアタッチしてbashシェルにすることができるようにしたいです。次のように両方の問題を解決できました。

イメージ/コンテナで、/etc/bash.bashrcファイルの最後に自動的に開始するコマンドを追加します。

あなたの場合は、必要な機能に応じて、/bin/riak start && tail -F /var/log/riak/erlang.log.1行を追加するか、/bin/riak starttail -F /var/log/riak/erlang.log.1を別々の行に追加します。

ここで、変更をコンテナにコミットし、docker run -i -t quintenk/riak-dev /bin/bashで再度実行します。 bashrcに配置したコマンドは、アタッチすると既に実行されていることがわかります。

4
damick

説明:

docker run -i -t quintenk/riak-dev /bin/bashを使用して実行すると、riakプロセスが開始されません

以下のとおりであります。 DockerfileでCMDを使用することは、docker run {image} {command}を使用してコンテナを起動することと実際には同じ機能です。 Gigablahが最後のCMDのみを使用していると述べたため、この場合、Dockerfileに書き込まれたCMDが上書きされます。

BuildfileでCMD /bin/riak start && tail -f /var/log/riak/erlang.log.1を使用すると、チャームのように機能するdocker run -d {image}を使用して、コンテナをバックグラウンドプロセスとして開始できます。

4
qkrijger

後でプロセスを終了させるクリーンな方法が必要なため、最後のコマンドをシェルの呼び出しにします readは、後でプロセスにアタッチするまでそのプロセスをブロックします Enterキーを押します。

arthur@macro:~/docker$ Sudo docker run -d -t -i -v /raid:/raid -p 4040:4040 subsonic /bin/bash -c 'service subsonic start && read -p "waiting"'
WARNING: Docker detected local DNS server on resolv.conf. Using default external servers: [8.8.8.8 8.8.4.4]
f27229a260c9

arthur@macro:~/docker$ Sudo docker ps                                                                                                                                     
[Sudo] password for arthur: 
ID                  IMAGE               COMMAND                CREATED              STATUS              PORTS
35f253bdf45a        subsonic:latest     /bin/bash -c service   2 days ago          Up 2 days           4040->4040

arthur@macro:~/docker$ Sudo docker attach 35f253bdf45a

arthur@macro:~/docker$ Sudo docker ps                                                                                                                                     
ID                  IMAGE               COMMAND             CREATED             STATUS              PORTS

コンテナをアタッチして読み取りのブロックを解除すると、コンテナが終了することがわかります。もちろん、サービスの停止やログの保存など、他のクリーンアップが必要な場合は、read -pよりも洗練されたスクリプトを使用できます。

3
Arthur Ulfeldt

新しいdockerコンテナの構築を開始するたびに、単純なトリックを使用します。それを維持するために、エントリポイントスクリプトでpingを使用します。

そのため、たとえばDockerfileでdebianを使用する場合、pingを実行できることを確認します。これは、コンテナ内からアクセス可能なものをチェックするための、常にニースです。

...
RUN DEBIAN_FRONTEND=noninteractive apt-get update \
 && apt-get install -y iputils-ping 
...
ENTRYPOINT ["entrypoint.sh"]

そして、entrypoint.shファイル内

#!/bin/bash
...
ping 10.10.0.1 >/dev/null 2>/dev/null

常にスタートアップファイルを使用するため、CMD bashの代わりにこれを使用します。

0
Osiris