MacOS で Docker を始めてみる

これまで仮想環境というと VirtualBox (とそれを操作する Vagrant) を使ったことがあったが、今回 Docker に手を出してみた。

とりあえず MacOS High Sierra か MacOS Mojave 上に Docker をインストールし、適当に CentOS でも動かしてみようと思う。

目次

Docker のダウンロードとインストール

Mac 用の Docker (Docker Desktop) はコチラからダウンロードできる。

Docker をダウンロードするには、Docker ID というアカウントを作らないといけない。この後出てくる Docker Hub のために必要なようだ。

インストーラをダウンロードしたらそいつを開いて、いつものように Applications/ ディレクトリに放り投げてやれば良い。

Docker を起動させると、タスクバーに Docker のアイコンが現れ、常駐するようになる。

ココまで到達すれば、ターミナルで $ docker コマンドが叩けるようになっていると思う。

Docker を使って CentOS を起動させてみる

それでは、Docker を使って CentOS を起動させてみる。ターミナルで以下のように入力する。

$ docker run -it centos:7 bash

いきなり centos:7 という文言が登場するので、「VirtualBox でいうイメージファイルは要らないのか?」と思うが、ココで Docker Hub が登場する。

Docker Hub は、Docker イメージ (Docker で動作する仮想環境) を公開できる GitHub のようなモノで、ココに色々なベンダや団体が公式で Docker イメージを置いて配信してくれている。

ユーザは基本的に Docker Hub から Docker イメージをダウンロードして利用するワケだが、ローカルにその Docker イメージがなければ、自動的に Docker Hub から検索して取得してくれるのだ。

CentOS の場合は、次のページで配布されているイメージ名 (タグ) が確認できる。

もし上述のコマンドで、centos:7 ではなく centos と指定した場合は、その時点での最新版が取得できる。他にも centos:6 (centos:centos6 と書いても同じ) とか、centos:7.6.1810 とか、色々なバージョンがタグ付けされて公開されている。

初回はこの Docker Hub から Docker イメージがダウンロードされるのだが、CentOS の場合で 200MB くらいあるので、ポケット Wi-Fi を使っているような人は通信量に注意。

さて、初回は Docker イメージのダウンロードに少々時間がかかるが、それが完了すると、CentOS のプロンプトが表示されるだろう。

# 起動コマンドを叩くと…
$ docker run -it centos:7 bash

# こんなプロンプトが表示されるはず
[root@380f3a76c398 /]# whoami
root

# CentOS が動作していることが分かる
[root@380f3a76c398 /]# cat /etc/redhat-release
CentOS Linux release 7.6.1810 (Core)

こんな感じで、CentOS が使えるようになった。

Docker は終了時に変更を保持してくれない : Docker の思想

CentOS が触れるようになったので、yum で色々インストールして、コードを書いて動かしたりしてみて、「あぁ〜満足、今日はおしまい〜」と exit を打ったら最後。

翌日、同じ $ docker run コマンドで CentOS を立ち上げてみると、昨日行ったはずの設定変更も、作ったファイルも、全てが消えてしまっているのだ。

もちろん、ファイルを永続化したり、OS 周りの設定変更を保存したりする方法はあるのだが、何も考えずに $ docker run$$ exit で起動・終了していると、このような挙動になる。docker start とかの話を始めると少々長くなるので今回は省略するが、このような挙動は、Docker の基本思想によるものであることに触れておこう。

Docker は、「Docker イメージ」と呼ばれる「設計図・設計書」を基に、「Docker コンテナ」という「箱 (実体)」を作る。

「Docker イメージ」の実態は Dockerfile というファイルに記述されたスクリプトで、ココに「Docker コンテナを起動する前にやること」を書いておくのだ。例えば、Node.js がすぐさま使える node イメージの場合だと、「ベースの OS に Debian を使って、Node.js をインストールしておいて、npm コマンドが使えるように PATH を通して…」的なことを、Dockerfile に記述している。実際のファイルは以下で閲覧できる。

で、Docker イメージを基に「箱」を作る、と表現したが、「Docker コンテナ」というのが、実際に稼動している仮想環境のことだ。セキュリティ用語に「サンドボックス」という言葉があるが、Docker コンテナはこの考えに近い。箱の内で行われた変更は、外部には影響しないし、最後は箱ごと捨ててしまうのだ。

Docker はこの Docker コンテナを、頻繁に起動したり、終了して破棄したり、といった使い方が想定されている。つまり、

  1. 予め「Docker イメージ (Dockerfile)」で、「こういうアプリケーションサーバを構築して、起動させるぞ」といった命令を書いておき、
  2. $ docker run コマンドによりそのイメージからコンテナを生成、アプリケーションサーバを起動させる
  3. サーバがクラッシュしたり、機能改修によって中身を差し替えたくなったら、起動しているコンテナを終了して破棄し、別の新たなコンテナを起動する

といった使い方を見越して作られているのだ。

VirtualBox なんかとは違い、「1つのコンテナ = 1つの仮想環境」で動かすのは1プロセスだけ、という感覚で、その「仮想環境 = Docker コンテナ = 箱」を、用途に応じてポイポイとっかえひっかえするワケだ。

なんだか難しいぞ Docker

2019年、遅ればせながら Docker に入門したワタクシ。使っていくうちに理解できることも増えてきたが、VirtualBox や Vagrant のような感覚とは違う使い方で、戸惑うことも多い。

これからちょくちょく Docker の使い方について、理解したことを紹介していこうと思う。