本日は Dockerのお勉強

Dockerというのは今話題の何と言ったらばいいのでしょうかね 自分でそんなに理解していないので表現できないのだけど、とにかくイメージとしては 「自分自身のパソコン上で Linuxを自在に走らせることを可能にする」ものです

例えば、自分の MacOSの上で少しの手間で Linux上で走る Web Serverやら SQL databaseを走らせ、MacOSではその Web Serverやら MySQLと通信してあたかも仮想のインターネットが自分の MacOS上に形成されるのです

自分で Webのプログラム組む時にテストとして 仮想インターネット環境を作らねばならず、この目的では 以前より使用されていた XAMPとか 今も盛んに使用されていて自分も使っている MAMPがあるのですが、そんなことせずに(多分)そのような環境を作ることができるのです しかも、それで動作すれば、そのファイル(イメージ)を持ち込めば世界中どのマシンでも動くらしいのです

うーん自分でも良く分からないので説明できないのですが・・・

これまで何冊かの書籍を Kindleで購入してきたのですが、どうも今ひとつピント来ず、またサンプルが動作しないのでつまづいてきました

今回、「Docker/Kubernetes実践コンテナ開発入門」という書籍を Kindleで購入して少し読み始めました

Docker書籍

この書籍は Just Publishedであり、昨日 download可能となりました それでテストしているのですが、なかなかこの書籍は書かれている内容が Docker初心者には理解し難いものがあり、色々とテストしてようやく最初のサンプルプログラムが走りました

#! main.go -- go言語でサーバーを立ち上げるためのプログラムを書く

package main

import (
  "fmt"
  "log"
  "net/http"
)

func main() {
  http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    log.Println("received request")
    fmt.Fprintf(w, "Hello Docker from DOCKER/KUBERNETTES BOOK!!")
  })

  log.Println("Server was started.")
  server := &http.Server{Addr: ":8080"}
  if err := server.ListenAndServe(); err != nil {
    log.Println(err)
  }
}

このGO言語で書かれたプログラムは port番号8080で Web Serverを立ち上げるものです なんだか色々と難しいことが書いてあるけど、やってるのは もともと GO言語のライブラリとして用意されている fmt, log, net/http といったライブラリを読み込んでそのライブラリに既に用意されている命令を呼び込んでいるたけです

そしてこれをコンパイルするために用意されている Dockerfile という拡張子無いファイルが重要なのです

FROM golang:1.9

RUN mkdir /echo
COPY main.go /echo

CMD ["go", "run", "/echo/main.go"]

このファイルを同じフォルダに Dockerfile という拡張子の無いファイル名で置くのです

このファイルでは書いてある通りに、 goloang version 1.9という既に定義されている色々な仕掛けを読み込み、それから Dockerが作成した特殊環境 Conatinerの中に /echo というフォルダを作成し、それからそのフォルダにさっき、compileした main.goという実行形式をコピーし、それから go して run してサーバーを立ち上げろ ということなのです

しかし、ここまで理解するのに色々とハマりました まず第一に、これらのファイルをどこに配置すれば良いのか、その説明が本には無いのです

仕方なく、僕は 文書フォルダの中に DOCKERKUBERNETES-BOOKというフォルダを作成し、そこに2つのファイル Dockerfileと main.goを置きました そして

$cd Documents/DOCKERKUBERNETES-BOOK

として current folderをこのフォルダに移動させそこで terminalより 以下の Docker commandsを打ちました

$docker image build -t example/echo:latest . // 実は最後のピリオドが重要です これが current directoryを表しているのですよ

これにより コンテナの中で go言語で書かれたサーバー立ち上げプログラムがコンパイルされてサーバーが立ち上がりました しかし、一発で立ち上がればいいのですが、main.goの中で typo (打ち間違い)が当然あります その時にeditorで何回もさっきの image buildを行っても エラーが出るのです

何回見直して typoを修正しきってもエラーを吐くのです これにはまいりました インターネットで原因を調べても良く分かりません

ふと思いついて ひょっとしてコンパイルされたイメージがコンテナの中に既に存在するのでエラーになるのでは? と思いました あたりでしたね

 

$docker image build --no-cache -t exmaple/echo:latest .

とすれば再びビルドして新たなイメージを作り直します

またこのようにしてできたイメージは

$docker container run example/echo:test

として簡単にスタートできますね そしてこのWeb Serverに外部から port 9000でアクセスさせるためには まず走っている イメージ-サーバーを停止せねばなりません

$docker ps

により走っているイメージプロセスを表示させます その最後に nameというタグがありますので、そのネームを用いて

$docker stop [nameの部分に表示される名前] //この名前は dockerが不規則に作成しているものです

としてそのプロセスをまず停止します それから再度 port forwardingしながら WEb Serverを立ち上げるために 再度以下のコマンドによりサーバーを立ち上げます

$docker container run -d -p 9000:8080 example/echo:latest

こうすることにより dockerで走っているサーバーの 8080 portがメインマシン ここでは僕の macOSですがこの port 9000と繋がります( = port forwarding) 結果的にはこの macOSでブラウザから localhost:9000とすれば、メッセージが表示されるのです

フーッ ここまで来るのに一時間使いましたね

Dockerで nginxを走らせる

今朝 Dockerで高速な Web Serverである nginxを走らせてみました

$ docker run -p 8080:80 nginx

これで別に terminal windowを開いて

$ docker ps

としたところ、

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
117c3fc5c632        nginx               "nginx -g 'daemon of…"   51 seconds ago      Up 51 seconds       0.0.0.0:8080->80/tcp   epic_nobel

と既に nginxが走っていることを確認しました

そこで、Macから browserを立ち上げ http://localhost:8080/ とアクセスしてみたところ、

Welcome to nginx!

If you see this page, the nginx web server is successfully installed and working. Further configuration is required.

For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.

Thank you for using nginx.

このように、Welcome addressが出ました やったね

ちなみに今度はchrome, safari, firefoxの全てで作動しました

Dockerの何回目かの勉強

これまで何回も Docker習得に挑み、挫折してきました 挫折すると暫く、そうですね数ヶ月間 Dockerのことは忘れ、またブーメランのように戻ってくるのです さあ今度はどうでしょうか また挫折するのかな?

そもそも Dockerとは Container-baseの仮想コンピューターシステムです 何と言えばいいか、例えば自分の MacBook Proの上に、たとえば Linux serverを何個も同時に動かしたりできるのです これは現代コンピューターサイエンスのもっとも進んだ利用なのだと思います

何れにしても目標としては、自分の MacBook Proの上に、Linux Web + PHP + MySQL (つまりいわゆる LAMP: L = Linux, A = Apache Web Server, M = MySql database server, P = PHP or Python programming language)を構築し、それを使用して Web program開発をすることなのです 現在はこの目的のために MAMPを利用しているのです

実はアメリカから帰国する前に「やったあ できた」と思ったのですが、その後検討すると Chromeでしか作動しない、FireFoxや Safariでは動作しない、http://localhost:8080/ではアクセスできない などの問題点があり、これではプログラム開発できません

それでゼロ点に回帰してやり直すことにしました 本日はこんなこと学びました

MacBook Proの bash terminal上で

$ screen ~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/tty

と入力し、Enterを押す そうすると

linuxkit-025000000001:~#

という待受になりこの時点で Linuxが Dockerコンテナの中で作動しだすが、ここで exitと入力すると あれあれ不思議 bash terminal上にこの Docker container上で動作する Linuxが遊び心でこんな素敵な画面を出力するのです

Welcome to LinuxKit

                        ##         .
                  ## ## ##        ==
               ## ## ## ## ##    ===
           /"""""""""""""""""___/ ===
          {                       /  ===-
           ______ O           __/
                          __/
              ___________/

linuxkit-025000000001 login: root (automatic login)

Welcome to LinuxKit!

NOTE: This system is namespaced.
The namespace you are currently in may not be the root.
login[483]: root login on 'ttyS0'
linuxkit-025000000001:~#

このままだと終了しないので、Ctrl-a kと入力することにより、Macbook Proの terminal bashに復帰します

こんなことですが、Dockerの始めの一歩でした 是非とも皆様方試みて下さい

ちなみにこのクジラの絵ですが、Dockerの trade markですクジラが貨物船のようにコンテナを積み込んでいる模式絵なのです 面白いですね

わーあいっ

今現在 Washington DCのラウンジで成田行き飛行機の出発を待っています その間に進歩して Chromeブラウザにこのようなものを出すことに成功しました

これは Docker containerで立ち上げた LAMP serverです

素晴らしいですね これは index.htmlに html文書を作成し、http://sample.localhost:8080/index.html にアクセスしたものです やったね やったね こうなるともう MAMPは不要となるのかな

本当のやったあ

この前の投稿ではタイトルが「やったあ」となっていますが、そのタイトルは実はこの投稿に対するものなのです

それと言うのも、このアメリカでの時差ボケの最中に解決したこと一つ それは Dockerで LAMPサーバーを Macbook Proの中に立ち上げることに成功したのです

といっても結構スキルの必要な作業であり、それを探すというのも一つの才能なのです 僕はサーチして このページに行き着きました いやいやありがたいことです

ただ、その記載の中に一箇所誤りがあり、そもそも良く理解していないので、何が誤りか検出するのに20分ぐらいを費やしました それは

./db/Dockerfile

DBサーバの設定ファイルです。
DockerHubにあるmysql:5.6を使用しています。

FROM mysql:5.6
MAINTAINER docker-db

COPY ./my.cnf /etc/mysql/my.cnf ※1

ここに一箇所誤りがあるのです それは簡単な話ですが、※1を削除せねばならない、ということです

それに気づいて修正したところ、見事に

docker-server$ docker-compose ps
Name Command State Ports
----------------------------------------------------------------------------------
dockerserver_db_1 docker-entrypoint.sh mysqld Up 3306/tcp
dockerserver_web_1 docker-php-entrypoint apac ... Up 0.0.0.0:8080->80/tcp

というふうに mysqldとphpが立ち上がりました 感謝感謝です