nginx
おもちゃシステムばかりでなく、今度は nginx を起動してみましょう
docker run --rm -it nginx
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2021/12/05 04:57:07 [notice] 1#1: using the "epoll" event method
2021/12/05 04:57:07 [notice] 1#1: nginx/1.21.4
... 10行ほど省略 ...
2021/12/05 04:57:09 [notice] 32#32: signal 28 (SIGWINCH) received
あれれ、ログインできません … そういうコンテナもあります。 まずは、Ctrl-C を押してコンテナを殺してください
2021/12/05 04:59:45 [notice] 1#1: signal 17 (SIGCHLD) received from 33
2021/12/05 04:59:45 [notice] 1#1: worker process 33 exited with code 0
... 5行ほど省略 ...
2021/12/05 04:59:45 [notice] 1#1: worker process 34 exited with code 0
2021/12/05 04:59:45 [notice] 1#1: exit
サーバプロセス(daemon として)実行
docker run -it
をつけるのはログインしたいからなのですが、
必ずしもログインできるわけではありません(そのようにコンテナが作られていません)
サーバプロセスは
docker run -d nginx
と実行します。
-d
はdaemon
のd
、ログインなど考えていない(ターミナルを切りはなしてOK)という意思表示です
一行なぞの数字(16進数)が表示されますが、それは生成されたコンテナのIDです
2cb33eff6c2d2ddce617ed7342ab9a7aab14463682ac69b2d9115c65297f6f34
動作を確認
docker ps
を実行すれば
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2cb33eff6c2d nginx "/docker-entrypoint.…" 3 minutes ago Up 3 minutes 80/tcp quirky_margulis
のように表示されるはずです。 一番左にコンテナIDの先頭が見えていて、イメージ名が nginx なのが確認できます。
コンテナにログインする
dockerコンテナ内でUnixコマンドを実行するdocker exec ...
という呪文があります。
これを使い、コンテナ内の/bin/bashを実行することでユーザrootでログインしましょう
docker exec -it コンテナID /bin/bash
コンテナIDは、上のdocker psで表示されているものをコピー&ペーストしてください。 このIDは十分ランダムなはずで、先頭の数文字でも、どのコンテナか特定できるため、 コンテナIDは先頭の数文字でも大丈夫です(ふつうは docker ps の表示からコピーするでしょうけど)。
docker exec -it 192e128251 /bin/bash
root@2cb33eff6c2d:/#
のようにプロンプトが表示されログインできたはずです。
さてコンテナに入れはしたのですが、 サーバの様子を調査するコマンドが入っていないので何していいかわからないですね;-)
コンテナを改変
ちなみにコンテナを改変しても再起動すると元に戻ります。 だからコンテナを壊しても全然大丈夫です。 気がねなく、いじりたおしてください。
そんなわけで、OSを調べるコマンドがないと始まりません。 しかたないから ps コマンドをいれましょう。
でもOSのパッケージ管理システムが分かりません。
そもそも、このコンテナの大元の distro は何でしょうね?
そういうとき、まずは雑な探し方をします(w)
だいたい、
/etc ディレクトリには、
OSのバージョン情報をもつほげほげ_version
とかふがふが_release
という名前のファイルがあると予想されるので、
シェルパターン*
(どんな文字にでもマッチするという意味)を使い、
それらしい文字列のファイルを表示してみましょう。
なおcatコマンドではファイル名が分からないので、
headコマンドで各ファイルの先頭最大10行だけを表示させます
head /etc/*ver* /etc/*rel*
(注:
/etc/*ver*
は /etc の下でファイル名に ver という文字を含むファイルすべて、
/etc/*rel*
は同様にファイル名に rel を含むファイルすべてという意味)
次のように表示されました。debian のようです。 では apt コマンドを使いましょう
==> /etc/debian_version <==
11.1
==> /etc/os-release <==
PRETTY_NAME="Debian GNU/Linux 11 (bullseye)"
NAME="Debian GNU/Linux"
VERSION_ID="11"
VERSION="11 (bullseye)"
VERSION_CODENAME=bullseye
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
ちなみに ps コマンドは procps パッケージです。 (詳細は略しますが)コンテナ内で次のコマンドを実行すると ps コマンドが入ります
apt update
apt install procps
ps auxww コマンドを実行すると、次のように表示されました。 たしかに nginx サーバが走っています
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.2 8688 5484 ? Ss 05:08 0:00 nginx: master process nginx -g daemon off;
nginx 32 0.0 0.1 9092 2368 ? S 05:08 0:00 nginx: worker process
nginx 33 0.0 0.1 9092 2368 ? S 05:08 0:00 nginx: worker process
nginx 34 0.0 0.1 9092 2368 ? S 05:08 0:00 nginx: worker process
root 35 0.0 0.1 4096 3324 pts/0 Ss 05:09 0:00 /bin/bash
root 907 0.0 0.1 6696 2816 pts/0 R+ 05:26 0:00 ps auxwww
exit でコンテナから抜けます
コンテナを止める
docker ps
してみると、
nginx コンテナが走り続けています。
サーバプロセスなので走りつづけていて当たり前です。
docker stop コンテナID
で停止させてください
【補足】 このガイドの実行例では docker run にデバッグのため –rmオプションをつけていることが多いですが、 本番のサーバプロセスでは –rm は不要です。 ちなみに –rm をつけて実行すると、 コンテナに一回ログインして exit するだけでコンテナが終了し、 イメージのゴミも残りません。便利
コンテナIDが面倒ですよね?
–name オプションでコンテナに名前をつければ名前で操作できます
docker run -d --name=mynginx nginx
これなら
docker exec -it mynginx /bin/bash
docker stop mynginx
などと操作できます
コラム
ps auxww
を実行したさいに、
nginx のマスタープロセスがプロセス番号 1 番であることに気づきましたか?
docker は普通の意味で Unix を実行する気はさらさらなく、
デフォルトでは init プロセスを使いません。
そういう設計思想(docker とは隔離されたアプリ一つだけを実行する環境と言えば正確かな?)なんですね
それで不具合とかないのか?というと、あるんですけども…
まぁ、 コンテナを起動、短時間実行、コンテナ終了という使い方なら問題になりません。 たぶん gmail の裏側(gmail は Google borg で動いていると思います。いずれにせよ docker ではない)とか Amazon Lambda の裏側(これも docker かどうかは知らないけど、いずれにせよコンテナでしょ)は、 そういう動作をしていて、そういう使い方ならOKです。
nginx コンテナのように長時間実行する場合も、 プロセス番号1番の挙動次第では大丈夫ですが、 一般的には問題になります。 これを説明するには Unix プロセスの詳細に立ち入らないといけないので、 そうとう長い話が始まります… (以下、略)