@Pkun

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

dockerをシェルからrunコマンドで起動するとコンテナが止まってしまうんですが

解決したいこと

ここに解決したい内容を記載してください。

何故止まってしまうんでしょうか?
docker run -d -p 8080:80 -v /var/docker/cont1/htdocs:/usr/local/apache2/htdocs --name cont1 httpd

今日帰ったら試すお手本コマンドなんですか
このコマンドを打っても止まるってしまうでしょうか?元のimageがダメなんでしょうか?
上のコマンドは-itオプションつけてないですが
-itはつけるべきでしょうか?
httpdはimageですよね?
分かる方、どうかよろしくおねがいしますm(_ _)m

0 likes

4Answer

docker ps -aでまず自分が作ったコンテナがあるかどうか、他に余計なものを動かしてないか確認してください。

また、docker logs コンテナIDで失敗したコンテナでもエラーが見れるはずですよ。

エスパー回答: すでに何かのアプリかコンテナを8080ポートで起動してませんか、同じポートは使えませんよ

2Like

Comments

  1. なお、止まっているコンテナでもポートは衝突した気がします。
  2. @Pkun

    Questioner

    なるほどぉ!ありがとうございます。
  3. 前の質問もですが、解決したのかしてないのか、やってみたら~だったみたいな返答がないのでその後がよくわからないです。
    回答者も全てを列挙して回答はしてあげれませんので、「これかな」的なものしか最初には出していません。

    上手なプログラマなどは質問の仕方が上手いので、単純なコマンドにかぎらず質問の仕方も勉強してみてください。

httpd -DFOREGROUND
apache や busybox の httpd などはデーモン(バックグラウンド)で実行されます。
docker は推奨が1プロセスのコンテナなのでフォアグラウンド実行するとよいです。

0Like

おそらく複数の内容がチャンポンしてしまっているのかも知れません。切り分けの第一歩として、コマンドの意味から入って、各々の動作を確認するのが急がば回れだと思います。

docker \
    # コンテナを実行する。コンテナが存在しない場合は、Dockerfile の内容を
    # もとに作成してから実行する。
    run \
    # -d は detach(切り離す)の略。コンテナ起動後、ターミナル/コマンドプロン
    # プトを閉じても動き続けるようにバックグラウンドで実行する、の意。
    -d \
    # -p は publish(公開)の略。コンテナのポートを外部からアクセスできる
    # ようにポートを公開する、の意。8080:80 は、ホスト(Docker が動いてい
    # るマシン)の 8080 番ポートを公開し、外部からの接続をコンテナの 80 番
    # ポートに転送する。これによりホストから、もしくはホスト以外の他のマシンか
    # らホストの 8080 ポートにアクセスするとコンテナの 80 番に接続できる。
    -p 8080:80 \
    # -v は volume の略。ホストのローカル・ディレクトリをコンテナにマウントす
    # るの意。ローカルの `/var/docker/cont1/htdocs` ディレクトリは、コ
    # ンテナの `/usr/local/apache2/htdocs` にマウントされる。ハード
    # ディスクやドライブでもないのにマウントというのは Linux の習慣。Linux
    # ではフォルダもディスクもデバイスも全て「ファイル」として扱うため。
    -v /var/docker/cont1/htdocs:/usr/local/apache2/htdocs 
    # --name はコンテナの名前。Docker 内部のネットワークで、コンテナを認
    # 識するためのホスト名(コンピューター名)の意。他のコンテナを同時に起動し
    # た場合に、他のコンテナから `ping cont1` のように、ホスト名でアクセス
    # できる。ホスト側では使えないホスト名で、コンテナの名前確認用としてしか
    # 機能しない。
    --name cont1 \
    # コンテナの元(雛形)となる Docker イメージの名前。
    httpd

@tonberry1050 さんがおっしゃるように、ホスト(ローカル)の 8080 番ポートがすでに使われている場合は、-p 8081:80 のようにポートを変更してどうか、になります。

もし http://localhost:8081/ で接続できた場合は、試行錯誤している間に作成した、裏で起動している他のコンテナが 8080 を使っている可能性があります。もしくは、他のローカルのサービスが利用していることになります。

起動しているコンテナが他にもないかの確認は、@tonberry1050 さんの docker ps -a で起動 & 終了しているコンテナのプロセス(ps)を確認できます。

また、docker ls -a により、起動中 & 終了含めた、作成された全てのコンテナを確認することができます。

一度終了してしまったコンテナの再起動は面倒、かつ意図しない挙動につながるので、docker container prune コマンドで、使われていないコンテナを削除することをオススメします。(prune はコンテナの搾りカスを処分するコマンドです)

Docker は体で覚えることが多く、最初のうちはコンテナを作っては壊し、を繰り返します。しかし、それ(作りなおされること)が前提なのが Docker のいいところでもあります。

$ docker container ls -la
$ docker image ls -a

上記の 2 つのコマンドで大量に出てきた場合は、以下のコマンドで真っさらにしてから再チャレンジすると安定すると思います。

docker system prune

このコマンドは、イメージとコンテナをすべて削除します。そのため、docker rundocker build で、ベースとなるイメージも再ダウンロードされます。しかし、色々といじっている間に壊れたイメージやコンテナも再作成されるので、最初のうちは定期的に実行して綺麗な(シンプルな)状態で試すのが良いと思います。

0Like

何故止まってしまう

ということですが、多分言いたい事はプロンプトが戻ってくる(入力状態になる)ということを言いたいのかなと。

$ docker run -it -p 8080:80 -v /var/docker/cont1/htdocs:/usr/local/apache2/htdocs httpd

とりあえずこうしたら希望通りに動きますか?

-d(デーモン化)の代わりに-itを入れています。

まず、-d(デーモン化)するとプロンプトは戻ってくると思います。

$ docker run httpd

をすると、このイメージの内容を見ると分かるように最後にhttpd-foregroundが実行されます
なので、本来ならhttpdのログが流れるはずですが、まずデーモン化しているのでこれがバックグラウンドで実行されるだけになるので目に見えません。

加えてただ単に

$ docker run httpd

としてもこの場合はhttpd-foregroundが留まらずログが目に見えません。なので、

$ docker run -it httpd
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
[Sun Sep 18 09:15:54.825721 2022] [mpm_event:notice] [pid 1:tid 140640255237440] AH00489: Apache/2.4.54 (Unix) configured -- resuming normal operations
[Sun Sep 18 09:15:54.825812 2022] [core:notice] [pid 1:tid 140640255237440] AH00094: Command line: 'httpd -D FOREGROUND'

こうすればログが目に見えて表示されるので、実行された感が出ます。
(cmd+c、ctrl+cで抜けられます)

bashをhttpd-foregroundの代わりに実行してやると、コンテナの中に入れるので

$ docker run --rm -it httpd bash
root@82a606f8d242:/usr/local/apache2# which httpd-foreground
/usr/local/bin/httpd-foreground
root@82a606f8d242:/usr/local/apache2# cat /usr/local/bin/httpd-foreground
#!/bin/sh
set -e

# Apache gets grumpy about PID files pre-existing
rm -f /usr/local/apache2/logs/httpd.pid

exec httpd -DFOREGROUND "$@"

こんな感じでhttpd-foregroundとは一体何なのか?を見ることも出来ます。
--rmを付けるとコンテナ停止時にコンテナを除去してくれるのでとりあえず動かしてみたい時は便利です。

$ docker run --rm -d -p:8080:80 httpd

こうしておいて、「 http://ホストのIPアドレス:8080 」へブラウザでアクセスすれば「It works!」と出ると思います。

そしてデーモン化しているので、そのままではcmd+cのように止めようがない為

unix系OSなら
$ docker ps -a | grep http

などとしてコンテナのIDを見つけて

$ docker stop XXXXX

とやると良いと思います。

0Like

Your answer might help someone💌