219

私がやろうとしているのと同じことをしているように見えるチュートリアルをたくさん見てきましたが、何らかの理由で Docker コンテナーが終了します。基本的に、Docker コンテナー内に Web サーバーといくつかのデーモンをセットアップしています。この最後の部分はrun-all.sh、Dockerfile で CMD を実行するという名前の bash スクリプトを使用して行います。run-all.sh次のようになります。

service supervisor start
service nginx start

そして、次のように Dockerfile 内で開始します。

CMD ["sh", "/root/credentialize_and_run.sh"]

手動で実行すると (つまり、-i -t /bin/bash を使用してイメージにアクセスすると)、サービスがすべて正しく起動し、イメージを実行するとすべてが正しく実行されているように見えますが、一度終了します。プロセスの起動を終了します。プロセスを無期限に実行したいのですが、私が理解している限り、これを行うにはコンテナーを実行し続ける必要があります。それにもかかわらず、 を実行するdocker ps -aと、次のように表示されます。

➜  docker_test  docker ps -a
CONTAINER ID        IMAGE                            COMMAND                CREATED             STATUS                      PORTS               NAMES
c7706edc4189        some_name/some_repo:blah   "sh /root/run-all.sh   8 minutes ago       Exited (0) 8 minutes ago                        grave_jones

何を与える?なぜ終了するのですか?維持するために bash スクリプトの最後に while ループを置くことができることはわかっていますが、終了しないようにする正しい方法は何ですか?

4

13 に答える 13

117

私はちょうど同じ問題を抱えていました.andフラグを使用してコンテナを実行している場合、コンテナは実行され続ける-tことがわかりました。-d

docker run -td <image>

フラグの機能は次のとおりです ( によるとdocker run --help):

-d, --detach=false         Run container in background and print container ID
-t, --tty=false            Allocate a pseudo-TTY

最も重要なものは-t旗です。-dコンテナをバックグラウンドで実行できるようにするだけです。

于 2016-04-26T17:50:31.820 に答える
45

終了する理由は、シェル スクリプトが最初に PID 1 として実行され、それが完了すると PID 1 がなくなり、PID 1 の間だけ docker が実行されるためです。

スーパーバイザーを使用してすべてを実行できます。「-n」フラグを指定して実行すると、デーモン化しないように指示されるため、最初のプロセスのままになります。

CMD ["/usr/bin/supervisord", "-n"]

そしてあなたのsupervisord.conf:

[supervisord]
nodaemon=true

[program:startup]
priority=1
command=/root/credentialize_and_run.sh
stdout_logfile=/var/log/supervisor/%(program_name)s.log
stderr_logfile=/var/log/supervisor/%(program_name)s.log
autorestart=false
startsecs=0

[program:nginx]
priority=10
command=nginx -g "daemon off;"
stdout_logfile=/var/log/supervisor/nginx.log
stderr_logfile=/var/log/supervisor/nginx.log
autorestart=true

その後、必要に応じて他のプロセスをいくつでも持つことができ、必要に応じてスーパーバイザーがそれらの再起動を処理します。

そうすれば、nginx と php5-fpm が必要になる可能性があり、それらを分離してもあまり意味がない場合に、supervisord を使用できます。

于 2015-06-03T23:39:16.913 に答える
45

ブロ@Sa'adが述べたように、引数なしでプレーンに実行catして、コンテナを機能させ続けることができます[実際には何もせず、ユーザー入力を待つだけです](JenkinsのDockerプラグインは同じことを行います)

于 2016-07-10T14:05:46.467 に答える
13

daemon off;nginx.confに追加するかCMD ["nginx", "-g", "daemon off;"]、公式の nginx イメージに従って実行してください。

次に、以下を使用して、スーパーバイザーをサービスとして実行し、nginx をフォアグラウンド プロセスとして実行して、コンテナーが終了しないようにします。

service supervisor start && nginx

場合によっては、コンテナーに複数のプロセスが必要になることがあります。そのため、コンテナーに 1 つのプロセスだけを強制しても機能せず、デプロイでさらに問題が発生する可能性があります。

そのため、トレードオフを理解し、それに応じて決定を下す必要があります。

于 2014-11-04T12:58:21.207 に答える
0

開発中に、まだサービスがなくても、それをシミュレートしてコンテナーを存続させたい場合があります。

実行中のサービスをシミュレートする bash プレースホルダーを作成するのは非常に簡単です。

while true; do
  sleep 100
done

開発が進むにつれて、これをより深刻なものに置き換えます。

于 2021-02-19T15:52:51.053 に答える