my cognition

書きたいことを書きます。

コンテナ環境がおかしいと気づいたとき、メンテナンスを始めるときの思考の流れ

最近、コンテナをメンテすることがあるので、どのように考えているかを整理して書きました。

tl;dr

  • readme に make command と記載がある場合は Makefile を見る
  • Makefile 内に docker-compose または docker compose と記載がある場合は docker-compose.yml を見る
  • docker-compose.yml の中に build と書いてある場合は Dockerfile を見る
  • Dockerfile を見る場合は、 FROM の定義とコマンドを見る
  • ログを見る。ログを見る。とにかくログを見る。

コンテナを扱ううえで最低限知っとかないといけない概念

古い言い方かもしれませんが、コンテナとは、コンテナを実行するPCから見れば、ただのプロセスであり、実行プログラムです。それは、 nodejs でも nginx でもいいです。 gcc でもいいです。何かしらの入力を受け付け、何かしらの出力を行うプロセスです。

443 ポートに HTTPS 接続を行い、 GET を行えばHTML文書を返してくれるし、あるファイル群をマウントしているディレクトリでビルドを実行すれば、コンパイル結果を記録してくれます。

あるプログラムに何か仕事をさせたい場合は、接続を行うポートや、読み込ませたいファイルが必要となります。

ポート

プロセスの中では、コンテナを起動したPCのカーネルを利用して、いわゆるOSが動いています。この辺の仕組みはどうでもいいので、コンテナの中ではOS、例えばLinuxディストリビューションが動いていると思ってもらえばいいです。

OSが動いているので、コンテナ内のOSは、コンテナ内のアプリケーションの動作のためにポートを管理しています。 nginx を起動すればコンテナ内のOSは 443 ポートで待ち受けます。

ここで、PCを動かしているOSと、コンテナ内のOSで、別々のポート管理の仕組みが働いていることがわかります。この2つの橋渡しをするのが docker-compose.ymlports であり、 docker コマンドであれば -p オプションです。

docker-compose.ymlports8443:443 とし、PCのブラウザで https://localhost:8443/ とアクセスすれば、コンテナ内の https://localhost に接続したものと同等になります。

マウント

コンテナ内のOSは、アプリケーションを実行するための最低限のファイルだけが置かれることが多いです。

実際は、例えばコンパイルしたい場合は、PCのあるディレクトリをコンテナ内のどこかにマウントしたくなります。これが volumes とかで書かれていることです。これはPCのディレクトリをコンテナ内のここでアクセスできるというだけのことです。

細かい設定はありますが、本当にこれだけのことです。信じてください

これらのポートを接続する、PCのファイルをマウントする、という概念さえわかれば十分です。実装は iptables で行われているとか考えなくていいです。

とにかく、PCとコンテナ内はポート、およびマウントした場所を通じてやり取りをする、ということがわかればOKです。

リポジトリで見るファイル

Makefiledocker-compose.ymlDockerfile を見ます。

Makefile

環境によっては、 docker compose コマンドなどを make start などと定義し、開発を容易に行うためのコマンドが用意されていることがあります。 この謎のコマンド定義は、 Makefile ファイル内に記載されています。

Makefile とは何か知らなくても、あなたが最低限、コマンドラインを実行する方法を知っていれば、読めば何となくわかります。 気合で読んでください。読めばわかります。 例えば make start などと書いてある場合は、どこかに start という記述があり、そこから docker compose up といった記述が見つかるかもしれません。 そこまでわかれば、「ああ、make start というものは、実はこれらのコマンドを実行しているだけなんだな」というのがわかります。

怖がらず、Makefile を一行一行読んでください。 make は、 Makefile に書いてあるコマンドしか実行していません。

docker-compose.yml

雰囲気で読めます。頑張ったら読めます。変数っぽいものは変数だし、名前っぽいのは名前です。 ただし、 build と書かれている部分だけは注意が必要です。相対パスで指定されている Dockerfile を読み込んでコンテナを作るってわかれば100点です。つまりは docker build と同じです。

Dockerfile

ここまでくれば、あとはもう怖いものは無いです。 Dockerfile には、あるイメージから実行したいコマンドがつらつらと書かれているだけです。愚直に上から読んでいきましょう。何も特別なことはありません。

FROM が書かれている部分だけは、Dockerfile の内容の外に実行内容が書かれているので、 "docker (FROMの内容)" とかで検索しましょう。ただし、そこまで必要になることはほぼないです。

ログ

ここまでで何となくコンテナのやりたいことが理解できたので、 make start して見ましょう。この文書を見ているあなたは、何かしらコンテナで不調が起こっていることの原因を知りたいはずです。

その答えは、ログに全て書かれているはずです。コンテナ内のWebサイトにアクセスしてエラーが出る場合は、ログが出力されるはずです。もし、 docker-compose.ymldocker compose up -d のように -d オプションがついているなら、 docker compose logs -f などでログを出力させるか、一時的に -d オプションを削除して実行しなおしてみましょう。

それでもログが出力されない場合は、 Dockerfile をコミットした人に聞きましょう。もしくは、標準出力を抑制するような記述がないか、 Dockerfile 内をくまなく探しましょう。

ログを見つけられたら、Google でエラーメッセージで検索しましょう。だいたい、あなたの直面したエラーは、だいたい人が答えを書いています。

不運にも答えが見つからない場合は、GitHub で検索してみましょう。そして 3 days や 2 week ぐらいの issue が見つかったあなたは幸運です。コンテナ内で使われているアプリケーションが、更新によって、直近で breaking change が発生してることを見つけられた英雄になれます。 issue に記載のワークアラウンドなどを頼りに Dockerfile の内容を修正し、コンテナ環境を直していきましょう。

参考文献

https://docs.docker.jp/compose/reference/up.html

https://docs.docker.com/engine/reference/commandline/compose_logs/