【初心者向け】Dockerを速習しよう

Dockerとは

ローカル(MacやWindowsの手元のPC)とリモート(サーバー)で環境構築を毎回し直すのは非常に面倒です。
また、職場のPCと家のPCで再度環境構築を行ったり、職場ではWindows、自宅ではMacだとすると、設定方法も全く変わってきて、シームレスな開発を行うことができません。

そこで現れた救世主がDockerです。

Dockerというのは、Mac/Windows/Unix問わずで動作し、そのDockerと呼ばれる概念の上で、LinuxのOSを動作させます。
そのため、MacでもLinuxの環境で操作したり、WindowsでもLinuxの環境で操作しておくことで、サーバーに実装する際にそのまま持っていくことができます。

引用元:Get Started, Part 1: Orientation and Setup

Dockerは上記の画像の用に、Host OS(Mac, Windows, Unix)上で動作させ、その上でコンテナと呼ばれる仮想マシンを資源のある限りいくつでも作ることができます。

Dockerのインストール

Dockerがインストール済みでない方は、下記の記事を参考にDockerのインストールを行ってください。
なお、Windows10より前のバージョン、もしくはWindows10 Home EditionではDocker for Windowsがうまくインストールできないため、Docker Toolboxを使うのですが、こちらは別途色々と知識が必要ですので、サーバー側にUbuntu16.04LTS版をインストールして、そちらにDockerをインストールして使う方が楽だったりします。

Windowsの方

Macの方

Docker速習

Dockerイメージのダウンロード

Dockerイメージとは、誰かが既に環境構築済みのシステムをイメージ化して配布できるファイルのことを言います。
Docker Hub上で公開されているDockerイメージはすべてダウンロードすることができ、こちらをダウンロード後に、コンテナ化(具体的な仮想マシンを立てること)することで、環境構築の手間が一切いらずに、開発をすすめることができます。

Dockerイメージのダウンロードには、docker pullを使用します。

たとえば、Docker Hub上で配布されている python というDockerイメージをダウンロードするには、以下のようなコマンドを使用します。

このコマンドを実行すると、以下のように、ダウンロードが始まります。

このダウンロードしたものをdockerイメージと言い、仮想的に構築された環境です。
しかし、このイメージは環境の実態ではなく、その環境設定のためのファイル(プログラムで言うクラスのようなもの)といったところです。
これを具体的に実態のある環境にするためには、このイメージをコンテナ(プログラムでいうインスタンス化のようなもの)にしてあげる必要があります。

現状保持しているイメージからコンテナを作成できるため、イメージを確認してみましょう。
イメージの確認には、dockre imagesを使用します。

Dockerコンテナの作成

では、コンテナを作成していきましょう。
コンテナの作成は docker run を使います。

これでコンテナが立ち上がります。
しかし、目の前に表示されないため、もう少しオプションが必要となります。

その前に、立ち上げたコンテナを確認しておきましょう。

こちらを実行すると、以下のような結果が得られます。

こちらにあるように、Dockerコンテナが立ち上がり、StatusがExitedになっているため、すでに停止されていることが分かるかと思います。
また、ランダムにコンテナ名が指定されており、今回はlaughing_noyceとなっています。

標準入出力を指定したコンテナの作成

前回の方法では、コンテナを立ち上げても、結果が返ってこないため、どのような挙動となっているかよくわかりません。
そこで、標準入出力を共有することで、コンテナ側の動作を確認できるようにしましょう。

docker runの際のオプションを指定し、-itと付けてあげましょう。

こちらのようにpythonモードが立ち上がり、コンテナ側の挙動が確認できるようになりました。
しかし、これではPythonモードをexit()するとコンテナも終了してしまい、Linux側の環境構築等ができません。

Linuxへアクセス

そこで、Linux側にアクセスしてみましょう。
これは最後に、/bin/bashを付けてあげればOKです。

こうすれば、OSがよくわからないですが、Linuxにアクセスでき、pipなどのコマンドが使用できるようになります。
後ろ側のOSシステムはUbuntuとなっているため、コマンドはUbuntu系が一通り使えます。

このコンテナに例えば、numpyをインストールしてみましょう。

numpyのインストールが完了したら、python側でimport出来るか確認しましょう。

特にインポートの際にエラーが出ていないため、正常にnumpyがインストールできていることが確認できます。
これでPythonの環境構築を行うことができます。

コンテナ作成の落とし穴

では、もう一度、コンテナを立ち上げてみましょう。

こちらのように、先ほどインストールしたはずのnumpyをimportしようとすると、エラーが起きてしまいました。
この原因は、docker runがコンテナを立ち上げるコマンドのため、別のクリーンなコンテナを立ち上げてしまったせいです。

作成済みコンテナの立ち上げ

では、numpyのインストールを行ったコンテナを探しましょう。

こちらで、作成したコンテナ一覧が確認できます。

コンテナを再度立ち上げる場合は、docker startを使います。
再度立ち上げたいコンテナ名をコピーしておきます。

これでスタートすると、またインタラクティブモードではなくバックエンドで動いてしまいます。

インタラクティブに動作させるには -i のオプションをつけます。

こちらのように、numpyを読み込んだ際にエラーが起きていないため、コンテナの再起動が正しく行えたことがわかります。

補足:コンテナの停止と削除

このコンテナを停止するには、docker stopを使います。

こちらのコマンドは、不要なコンテナを停止する(通常はexitすれば自動的に停止する)際と、起動中のコンテナを削除する前に一度ストップしないとエラーが出たりする際に使用するため、覚えておきましょう。

コンテナの名前の指定

特に指定なくコンテナを立ち上げた際には、ランダムにコンテナの名前が付いています。
コンテナの再起動など、コンテナの名前はよく使うため、こちらを事前に指定しておくと便利です。

コンテナの名前の指定には、--nameのオプションを使います。

例えば、先ほどのコンテナにseminarという名前を付ける場合は、以下のように追記します。

補足:コンテナの削除

また、同じ名前のコンテナがあった際に、Conflictというエラーが起きるため、こちらを避けるためには、別の名前を付けるか、作成済みのDockerコンテナの削除を行いましょう。

例えば、seminarという名前のコンテナを削除する時はdocker rmの後に、コンテナ名を指定します。

コンテナとのディレクトリの共有

ホスト側(Windows/Mac/Linux)と共有のフォルダを使いたい場合は、-v ホスト側のディレクトリ:コンテナ側のディレクトリ で設定できます。

こちらは、デスクトップのworkというディレクトリと、コンテナ側の/homeというディレクトリを共有しています。
そのため、デスクトップのworkにファイルを置くことでファイルの即時共有ができ、また、コンテナ側で保存したファイルも簡単に取り出すことができます。

コンテナとポートの共有

Jupyter Notebookを使用する際やWebアプリケーション開発の際によく使用するのですが、Dockerコンテナ側のポートと、ホスト側(Windows/Mac/Linux)のポートを共有して使えるようにできます。
ポート番号を共有するためには、docker run コマンドにオプションで -p を付けます。
例えば、ホスト側の8888番ポートをコンテナ側の8888番ポートと紐付ける場合は -p 8888(ホストのポート番号):8888(コンテナのポート番号) となります。

それでは、ディレクトリとポート番号を共有したコンテナを立ち上げましょう。

コンテナのイメージ化

作成したコンテナをイメージ化することで、他の人に配布することができます。
また、ポートやディレクトリの指定はコンテナの立ち上げ時にしか行えないため、一時的にコンテナを保存したいといったときにも、一旦イメージ化して、それを立ち上げ直すといった便利な方法があります。

イメージ化するのは、docker commitでコンテナ名を指定し、Dockerイメージの名前を指定しましょう。

:v1.0はタグと呼ばれ、バージョンを管理するために付けるものです。

イメージ化をすることで、Dockerイメージのリストに登録されていると思います。

補足:Dockerイメージのアップロード

こちらでは説明を割愛しますが、DockerイメージをDocker Hub上にアップロードすることにより、他の人がdocker pullで使用できるようになります。

こちらは下記の記事等をご参考ください。