Dockerの概要

Vagrantのアナロジーでいうと、イメージはboxファイルのようなもので、コンテナはVMイメージのようなもの。コンテナは状態を持つ。

$ docker container start コンテナ名
$ docker container exec -it コンテナ名 bash
# 以下コンテナ内
# touch touched_file
# exit
$ docker container stop コンテナ名
$ docker container start コンテナ名
$ docker container exec -it コンテナ名 bash
# ls
touched_file
#

ただし、コンテナは簡単に破棄される存在なので、状態を持たせないのが前提となる。ログなどは標準出力、標準エラー出力へ出力する(何かしらのログ収集プログラムに処理させる)。ログファイルが複数ある場合は、ボリュームを使ってファイル共有したログ処理専用コンテナを用いる方法もある。

イメージは、レイヤ構造になっていてDockerfile内で実行される1コマンドが1つのレイヤとなる。DockerfileのFROMで指定する元イメージで実行されているコマンドも含め、127レイヤが上限のレイヤ数になる。そのため、できるなら以下のように&&で繋げてDockerfileとしては1つのコマンドにまとめてしまう方がよいと言われている。

RUN apt-get update -y && \
    apt-get upgrade -y

ただ、レイヤはそのレイヤ以前のコマンドに変更がなければキャッシュされたものを使われるため、いたずらになんでも&&で繋げてしまうとちょっとした修正なのにapt-getコマンドが実行されて無駄なダウンロードが発生したりするので、意味のある単位で繋げるようにしなければならない。また、イメージを公開するつもりがないのであれば、必要なタイミングで整理すればよく、レイヤ数をそこまで気にする必要はないだろう。

コンパイルのために必要なライブラリなど、構築時には必要だが実行時には不要なものは削除して、イメージサイズを減らすようにした方が良いと言われる。最近では、multi stage buildと呼ばれる機能で、コンパイル用のイメージと実行用のイメージを分ける方法が取られる。

# Dockerfile
FROM ruby:2.7.2 AS nodejs

WORKDIR /tmp

# nodejsのバイナリを取得
RUN curl -LO https://nodejs.org/dist/v14.15.4/node-v14.15.4-linux-x64.tar.xz
RUN tar xf node-v*-linux-x64.tar.xz
RUN mv node-v*-linux-x64 node

# ============================================================
FROM ruby:2.7.2

# 上記のnodejsイメージでダウンロードしたnodejsをコピーしてくる
COPY --from=nodejs /tmp/node /opt/node

なぜイメージサイズを減らす必要があるかといえば、ディスク容量や起動速度に影響するからだが、劇的に変わるものではないだろうし「減らせるところは減らしとこうね」ぐらいの意識で良いのではないかと思っている。なお、よく、容量が小さいからAlpineが良いと言われるが、他のディストロと比較してもせいぜい数十MBから200MB程度の差である。

REPOSITORY              TAG       IMAGE ID       CREATED             SIZE
alpine                  latest    e50c909a8df2   3 days ago          5.61MB
ubuntu                  latest    f63181f19b2f   11 days ago         72.9MB
debian                  latest    e7d08cddf791   2 weeks ago         114MB
centos                  latest    300e315adb2f   7 weeks ago         209MB

設定

Ctrl-Pでヒストリを戻れない問題

docker run --rm -it イメージ名 bashなどをして、Ctrl-Pでシェルのヒストリを戻ろうとしても効かない問題がある。DockerのキーバインドでCtrl-Pが指定されているらしく、当該のキーバインドを別のものに割り当てる設定をすることで解決する。

~/.docker/config.jsonに以下の設定を追加する。すでに設定が記述されている場合はよしなに設定すること。

{
  "detachKeys": "ctrl-[,q"
}