たのしい工学

プログラミングを学んで、モノをつくりたいひと、効率的に仕事をしたい人のための硬派なブログになりました

【Docker入門】トレンドに遅れたひとのためのDocker

   

こちらも言わずもがなだと思いますが、現在業務でまだDockerを使用したことがないという方は強烈な危機感を持った方が良いと思いますし、最低限

Dockerfileを書いて
docker buildコマンドでDockerイメージをビルドして
そのイメージを何らかのリポジトリ(DockerHub等)にdocker pushして
そのイメージを何らかのVM上にdocker pullして
そのイメージをdocker runしてコンテナを実行して
そのコンテナの特定のポートに外部からアクセスする
といった一連の作業を自分一人で出来るようになっておくのは必須というか、上記の作業が出来ない方はトレンドから相当遅れてしまっていると考えた方が良いと思われます。

サービスのコンテナ化というのはここ数年のWeb業界の一大トレンドというか完全に一般化してきていますので、もしこの記事を読んでおられる皆さんの会社がまだ本番環境でDockerを運用していないのであれば、多分その会社は早めに辞めたほうが良いと思います。(そのくらい重要な技術になってきています)

ローカル環境でのテストや、CI上でのテストに関してもDockerを使用することが当然のような流れになってきています。

というパワーセンテンスをみかけたので、今回は上記でいわれている内容が最低限ひとりでこなせるよう、Dockerについてまとめてみました。よかったら参考にしてください。

(記事はこちら
2018年の最先端バックエンドエンジニアに必要なスキルについて考えてみました。)

Dockerのインストール

各自の環境にあわせてインストールしてみてください

おおまかには下記のかんじです。
詳細は他にくわしく書いてる方がいるので
Dockerインストールメモなどを参考にしてみてください

  • windowsの場合
    → docker tools(windws Pro非対応の場合)をダウンロード
    https://www.docker.com/
  • Linux(VirtulaBox上のvagant環境等に入れる)の場合
    ヴァージョンを気にしないなら、

    ◎centOSの場合
    sudo yum install docker

    ◎ubuntuの場合
    sudo apt-get install docker

  • mac
    Docker Storeからdmgファイルをダウンロードできます。

わりとすっきり構築できたのは、Linux系環境の場合だったので、構築にてこずっているひとはLinux環境でやってみるといいかもしれません。

Dockerコンテナの基本操作

dockerがインストールし終わったら、つぎのようにやっていきましょう。

「sudo docker run centos echo "hello world"」とすると、centos から Container を作って、その Container 上で「echo "hello world"」が実行されたと思ってください。

Container がどこに作られたかというのは、「sudo docker ps」で一覧を見ることができます。
https://gyazo.com/af2f961f783d534d3e4843e4de97f36d
こうして見ると何もないのですが、それはなぜかというと、「sudo docker ps」は実行中の Container 一覧を見ることができるコマンドになります。

すでに表示をし終わって Container としての動作が終了したので、動作が終了したものを見るためには「sudo docker ps -a」としてください。
https://gyazo.com/b87eee185552a2a5835dc106effa0b71
https://gyazo.com/e6079d0de50caa04827be508bfd6160e
そうすると、centosの Image でこういった Container ID が作られていて、「echo hello world」が実行されていて、いつ実行されたのかが分かって、「Exit 0」というのは正常終了したという意味になります。

ちなみに、いろいろ実行していくと Container が貯まるのですが、最新の 5 つだけ見たいという場合には、「… -n=5」というコマンドも使えるので、それも覚えておきましょう。
それから Container を削除したい場合には、「sudo docker rm」として ID を指定すれば OK です。
一意に決まればいいので、3 文字くらいで OK かと思います。

rmなどは、unix系シェルコマンドと同じですね。

こういった Container の操作にもまずは慣れておきましょう。

実行中のContanierを操作する

実行中のContainerを操作する方法について見ていきます。

「sudo docker run」として、バックグラウンドで走らせたいので「-d」というオプションを付けます。
centos というイメージで、free という、メモリの状況を表示させるコマンドを 3 秒ごとに実行させてみたいと思います。

このようにすると Container の ID が返ってきます。
https://gyazo.com/13166f253aa5e31a7b06883a2dfc8869

前回と同じように「sudo docker ps」とすると、前回は見れなかったのですが、今回は実行中のタスクがあるので、一覧に表示されているのが分かります。

https://gyazo.com/fb867431808999f30d5bb8ae7a44244c

ちなみに実行中のタスクのログを見ることもできて、そのためには「sudo docker logs」を使えば OK です。

Container の ID を指定すればいいので、「sudo docker logs "container IDの上三桁"」としましょう。

いま、さきほどのsudo docker psより、containerID362~のプロセスがあることがわかるので、sudo docker logs "container 362 とします。
https://gyazo.com/43a786d27a5e167b32f75c3670b8f616

そうすると、このようにログが確認できます。

ちなみにこのタスクをフォアグラウンドに持ってきたいときは「sudo docker attach」を使うことができます。

あとで Ctrl+C で抜けるのですが、そのためのオプションが決まり文句としてあるので、「--sig-proxy=false」を付けるようにしておいてください。

「sudo docker attach --sig-proxy=false "containerIDの上三桁"」とすると、3 秒毎に表示がされるはずです。
キャプチャ動画 - faa7dab74557fb9fe55eaf21d005a3f0

ちなみにこの実行中のタスクをストップさせたい場合には、「sudo docker stop」もしくは「sudo docker kill」が使えます。

「sudo docker kill 362」としたいと思います。

そのようにして「sudo docker ps」で見てみると、実行中のものがなくて、「sudo docker ps -a」で見てみると、停止中のところに先ほどの Container が入っているのが分かるかと思います。
これをまた再開させたい場合には、「sudo docker start "containerIDの上三桁"」とすればいいので、それも覚えておくといいでしょう。
https://gyazo.com/0afb671009250ba1b4eabff2c39bdab8

そうすると、実行中の Container に出てきているのが分かるかと思います。

Container からImageをつくってみる

ここでやること

Container内での作業
Commit
Imageからの起動

次は Container の中に変更を加えて、そこから Image を作ってみるというのをやってみましょう。

Container の中でいろいろインストールしたりして、そこから「docker commit」で Image を作っていきましょう。

ではやっていきたいのですが、今まではコマンドをただ単に実行していただけなのですが、実際に Container の中に入って作業するというのをやってみたいと思います。

「sudo docker run」としたあとに、インタラクティブモードにしたいので「-i」としましょう。

Container の中でターミナルを立ち上げたいので「-t」として、Image を指定して、「/bin/bash」としてシェルを立ち上げます。

https://gyazo.com/3d857f572f53a64c141d19434becdafa

[root@”コンテナID”]のシェルが立ち上がったことがわかります。

そうすると Container の中に入ったので、何をするかというと、いろいろインストールをしてもいいのですが、今回は簡単に「touch hell.txt」で hell.txt を追加してみます。

https://gyazo.com/adbe5a520ef79b9e34ee9e9c0df38a16

そうすると hello.txt が出来ているのが分かるかと思います。

ここで「exit」とすると、Container から抜けることができて、実行が終了します。

そうすると、「sudo docker ps -a」で今の Container が表示されます。
https://gyazo.com/96ebbd5998f64a67b50c31bb5d2a9a02
これを元に Image を作っていきましょう。

Image を作るには「docker commit」でしたね。

Container の ID が 15a なので「sudo docker commit 15a」としたあとに Image の名前を付けます。

Image の名前は、慣習的に「ユーザ名/分かりやすい名前」なので、今回は「hoge/hello」としましょう。

このようにすると、Image が作られるはずです。

「sudo docker images」で見てみましょう。

https://gyazo.com/9e9739e26230269f9124c12ba5753342

hoge/hello が出来ています。
これを元に Container を作っていきたいと思います。

その中に hello.txt があるかどうかというのを見れば OK かなと思います。

なので、「sudo docker run -i -t hoge/hello /bin/bash」とすれば OK ですね。

「ls」で見てみると、ちゃんと hell.txt があるのが分かるかと思います。

https://gyazo.com/95c5b803c87c5aa9c21f644eac08a450

このように Container の中にいろいろ必要な設定などをして、そのあとに「docker commit」で Image を作ることができるということが分かったかと思います。

Dockerfileを使ってみる

前回まで Image から Container を立ち上げて、そこで変更を加えて、それをまた Image にするというのをやってきましたが、この一連の作業を実はスクリプトに書いておいて自動化することができます。

Image を元に何らかの変更を加えてまた新しい Image を作るというのを「docker build」というコマンドで行えます。

自動化するためのスクリプトファイルである Dockerfileを作っていきます。

https://gyazo.com/f8bce30e3ae8ac995167d7e755a4251a

まず何の Image を元にするかというのを「FROM」で指定します。

今回は centos を元にします。

誰が書いたかというのを「MAINTAINER」で書くことになっています。「MAINTAINER hoge hoge@hoge.com」のように名前と E メールアドレスを書いておけば OK かと思います。そのあとにいくつかコマンドがあるのですが、今回は 2 つ、「RUN」と「CMD」というのを使っていきたいと思います。コメントを書くには「#」として、そのあとに書きます。

まず RUN なのですが、これは build するときに実行されるものになります。

いろいろなものをインストールしたりできるので、まずはこれを書いていきましょう。今回はインストールするのではなくて、ただ単に「now building...」と表示させるだけにしましょう。

もう 1 つ CMD というものがあるのですが、CMD は build された Image を元に、その Image からまた Container を作るとき、つまり run するときに実行されるものになります。なので「CMD echo "now running..."」としたいと思います。

ちなみにコマンドは「CMD echo "now running..."」のように書くこともできるのですが、「CMD ["echo", "now running..."]」のように書くことが推奨されています。

実行したいものを「,」で区切って、「[」と「]」で囲んでください。

https://gyazo.com/7140408ce366881d80444a98bb405abc

これを保存して、実際に build をしましょう。

「sudo docker build」として、このときに新しい Image の名前を付けることができます。

今回は「-t hoge/echo」としましょう。

カレントディレクトリにある Dockerfile を使うので、最後に「.」を付けるのを忘れないようにしましょう。

https://gyazo.com/fa21d9c9abf98574b17c66cd8e138e68

このようにするといろいろ実行してくれて、build しているときに「now building...」と出ているのが分かるかと思います。

https://gyazo.com/a7c2de40407bfb1fe70df2cc9720ee92

いろいろ実行されていますが、「sudo docker images」とすると「hoge/echo」が出てきているのが分かるかと思います。
https://gyazo.com/3c98d1c935f4e2d5d68bcd5e32a29aff
実行すると、先ほどの echo が実行されるはずです。

「sudo docker run hoge/echo」としてみましょう。

https://gyazo.com/64d7551af0f84ae0033e2d001f8f773a

「now running...」と出ていることがわかります。

Dockerでサーバを立ててみる

dockerfileをつぎのようにします。
https://gyazo.com/accb97440b86e48940f5037274f43624

docker buildする際に走らせるコマンドRUNに

「yum install -y httpd」

を設定して、centosのイメージファイルにapachサーバをインストールします。

そのあと、あとで、Ubuntu側でindex.htmlファイルを作成するのですが、そのファイルをdockerのcentos Imageファイルに取り込む場合には、ADDコマンドを利用します。

ADD ./index.html /var/ww/htmlでindex.htmlを/var/www/htmlにコピーします。

そのあとに、EXPOSE 80で httpdで使う80番ポートを開けます。

実際にRUNのときに実行するコマンドは「CMD["/usr/sbin/httpd","-D","FOREGROUND"]」とします。

そのあと、ubuntu側でindex.htmlを作成します。

簡単に
https://gyazo.com/a9271b6ae6e211eb5bae021b899bec0d
こんな感じにしておきます。

https://gyazo.com/431f7569a682a2a6ac7ac1f9d399e7b5

今回ホスト側のポートの 8080 番を Container 側の 80 番にリダイレクトしたいので、「-p 8080:80」というオプションを付けます。

「sudo docker run -p 8080:80 -d hoge/httpd」とすると、今実行して、裏で Container の httpd が立ち上がっているはずです。

ホストの 8080 番でアクセスできるはずなので、ブラウザで「設定したip:8080」にアクセスすると、ちゃんと「hello docker world!」と、先ほど作ったファイルが表示されているのが分かるかと思います。ちなみに現在のホストのipはifconfigで調べることができます。

Docker Imageをpushする

今どういった状態かというと、「docker pull」「docker run」「docker commit」ができて、Dockerfile で build をするやり方を見てきました。

出来た Image を Docker Index にプッシュするというのをやってみたいと思います。

そうするためには Docker Index の方でサインアップをする必要があるので、サインアップ画面より登録をしておいてください。

すでにサインアップは済ませてあるので、「sudo docker login」でログインします。

そうするとユーザ名などを聞かれるので、入力します。

ログインが成功すると、Image をプッシュすることができるようになります。

「sudo docker push hoge/httpd」でプッシュします。
(結構時間がかかります)

Docker Index のサイトの方でちゃんとプッシュできているかというのを確かめてみましょう。

ログインをします。

そうすると、Repositories のところに hoge/httpd というのができているのが分かるかと思います。

これで他のマシンでまったく同じ環境を動かしたいときには「docker pull hoge/httpd」とするとちゃんとイメージが引っ張ってこれるので、Docker の使い方として参考にしてみてください。

※ちなみに、Docker indexにアップするdocker Imageの名前に、docker IDがふくまれていない場合、うまくpushできないことがあるようです。その場合、Image file名にdocker IDが含まれるようにするとうまくいくようです。

今回はここまで。

 - Docker