DollsKit

Docker

公式ドキュメント
https://docs.docker.com/

いっぱいあって分かりづらい。。 Get Started のチュートリアルと Manuals がおすすめかもしれない。

Docker ドキュメント日本語化プロジェクト (少し古いので注意)
https://docs.docker.jp/index.html

インストールとデータディレクトリの変更は Raspberry Pi セットアップ を参照。

概要

古来より伝わる LAMP (Linux + Apache + MySQL + PHP) …も今は昔かもしれないが、複数のソフトウェアに依存したシステムが当然になり、 バージョン間の食い合わせ等も含めて システムに直接インストールして環境を整えるのは初心者だけでなく 上級者も苦心するようになった。

生の環境に直接構築するのではなく、”ハコ” の中で一通り必要なソフトウェアを インストールし、安全と判断された “ハコ” を保存してそのまま渡す、 おかしくなったら気軽に捨てて元の状態からやり直せると非常に楽、 というアイデアは仮想化技術 (Virtual Machine; VM) によって達成できた。

しかしそれはハードウェアレベルの仮想化であり、VM には仮想ディスクに OS/カーネルをインストールするところから始める必要がある。 つまりぶっちゃけ重い。

カーネルは色々とアグレッシブな Linux であっても互換性に関しては注意深く気にされており、 そこまで隔離された “ハコ” の中に収める必要性は薄い。 というわけで、カーネルはホストのものをそのまま使い、ユーザランドのファイルツリーに インストールされるファイル群をいい感じに隔離された環境内で動かすのが Docker である。 ちょっと手を抜いた、でもやっぱり仮想化の一種。 カーネルは仮想化しない、それより上を仮想化、isolation する感じ。 主に unionfs (複数のファイルシステムを重ねて1つのファイルツリーに見せるファイルシステム) によって実現されている。 あとネットワーク仮想化とか。

必要なソフトがインストールされ整備された環境がワンコマンドで動き出すので、 はっきり言って色々とめちゃくちゃ楽。 勉強しないと何やってるのか一切分からないけど。

概念

特有の用語とその概念を覚えないと何も分からない。。

よく使うコマンド

Special Thanks: サイボウズの研修資料

操作例

Special Thanks: サイボウズの研修資料

イメージの取得と確認

docker images
# デフォルトで DockerHub を見に行く
docker pull nginx
docker images

イメージからコンテナを起動

# -d: detach バックグラウンド起動
# --name: コンテナに名前をつける
# -p: コンテナ内の 80 番ポートをホストの 8080 番にバインド
# 最後がイメージ名
docker run -d --name mynginx -p 8080:80 nginx
# 起動中のコンテナ一覧
docker ps
docker logs mynginx
docker stop mynginx
docker rm mynginx

ボリュームやバインドマウントは -v --mount を使う。 -v は昔からあるやつ。短く済む。 --mount は新しい。やや冗長になるが、意味を読み取りやすい。

docker volume create my-vol
docker volume ls
docker volume inspect my-vol

便利なイメージ

busybox

ボリュームはコンテナの生成破棄とは別に管理されるので、他のコンテナにマウントして 調査やバックアップを行うことができる。

DockerHub にある busybox は最低限のいつものコマンドだけを集めた軽量がウリのイメージ。

# コマンドを実行して終了
# --rm をつけないと終了したコンテナが docker container ls -a に残る
docker run --rm busybox ls
# -i -t で stdin をコンソールに接続するとコマンド入力待ちになる
docker run --rm -it busybox
# docker volume ls で得たボリューム名と、コンテナ内でのマウント先を指定
# いつものコマンドで調べる
docker run --rm -it -v growi-public_mongo_db:/tmp/db busybox
# ホストディレクトリのバインドマウントと併用
# コンテナ削除後も成果をホストファイルシステムに残せる
docker run --rm -it -v growi-public_mongo_db:/tmp/db -v ./share:/tmp/share busybox

ボリュームマウントとホスト fs のバインドマウントを組み合わせて起動し、 busybox のコマンドを使えば大体何でもできるはず。

alpine

Alpine は軽量 Linux ディストリビューション。

               DISK USAGE   CONTENT SIZE
alpine:latest      13.6MB         4.28MB
busybox:latest     6.21MB         1.91MB
debian:latest       209MB         52.8MB

Debian/Ubuntu

うまくできないなら諦めて Ubuntu + apt でも使うといいよ(適当)。 バージョンによりサイズが変動しているので歴代サイズまとめサイトを見て選択する。 そもそもプロダクションではバージョン固定すべき。

docker compose

1つの Docker コンテナ内では1つのサーバやデータベース等が動作するが、 実際のシステムはサーバ + データベースのように複数のコンテナを接続して 同時に動かすことによって実現されることが多い。 なのでコンテナを1つ1つ docker コマンドで操作するのは大変である。 そこで1つのアプリケーションシステムを構成する複数のコンテナ操作を まとめて定義したものを実行してくれるのが docker compose である。

つまり、compose の方も理解しないと実践的なアプリケーションを管理することができない。 とはいえ、docker の各コマンドを理解すれば compose の yaml ファイルは 自然に読めるようになっているはず。

docker compose コマンド

docker compose CMD

設定ファイルのオーバーライド

設定ファイルは複数指定可能で、ベース + 追加/変更 の形にできる。 デフォルトは compose.yaml + compose.override.yaml (optional) を探す。

プロジェクト名

compose は docker コンテナやネットワーク等の要素を一括で操作するが、 その際はプロジェクト名により操作対象か判定している。 プロジェクト名のデフォルトは compose.yml ファイルのあるディレクトリ名である。 これが被ると予期しないコンテナやネットワークが削除されて事故るし、 うまく変えれば同じファイルから複数のプロジェクトを同時に立ち上げることができる。

ボリューム

docker volume <CMD> で個別に操作可能だが、compose の定義から作られることも多い。

Commands:
  create      Create a volume
  inspect     Display detailed information on one or more volumes
  ls          List volumes
  prune       Remove unused local volumes
  rm          Remove one or more volumes

growi だとこんな感じで作って

volumes:
  growi_data:
  mongo_configdb:
  mongo_db:
  es_data:
  page_bulk_export_tmp:

こんな感じでボリューム名とマウント先を指定してコンテナから使われている。

volumes:
  - mongo_configdb:/data/configdb
  - mongo_db:/data/db

実際には最初にプロジェクト名を付けて他のプロジェクトと名前空間を分けている。

$ docker volume ls
DRIVER    VOLUME NAME
local     growi-public_es_data
local     growi-public_growi_data
local     growi-public_mongo_configdb
local     growi-public_mongo_db
local     growi-public_page_bulk_export_tmp