docker 使うコマンド

コマンド

気が向いた時に更新していきます。

$ docker search イメージ名
#コンテナのもととなるイメージを検索 
$ docker pause コンテナ識別子
# 起動中のコンテナを停止
$ docker pull イメージ名
$ dcoker attach  
# 稼働しているコンテナの接続
$ docker top
#稼働コンテナのプロセス確認
$ docker port
#稼働コンテナのポート確認
$ docker commit
#コンテナからイメージ作成

docker 頭の整理

docker for mac

Macでdockerを使う際はdocker for mac という素晴らしいアプリが ある。これは

  • docker
  • docker-machine
  • docker-compose

というありがたいツールがオール・インワンになっているアプリケーションです。 docker-machineは前回話した通り、仮想マシンを作成するものです。 docker-composeは後々まとめる予定。。

仮想マシンにログインするには

docker ssh とコマンドを打てばおkです。Vagrantみたいですね。

イメージとは

dockerの仮想マシン上にログインしたものの、 何もない状態ではつまらないので、docker上でruby環境やらpython環境 構築したいですね。その際には、docker imageをダウンロードして使います。

docker imageとは、アプリ実行に必要なプログラム、ミドルウェアを一つにまとめたものです。通常はプログラムとミドルウェアを別々に管理しておくようです。

docker image は自分で作成することもできますが、

docker hubを探して使うことも出来ます (便利!)

イメージを取得するするには

docker pull イメージ名 を行えばうまくいきます。

githubみたいです。

docker 概念整理

dockerとは

dockerとはホストマシン(macのローカル)に依存せず、開発環境を構築出来るツール linuxカーネルの仮想技術を用いているため、オーバーヘッドが少ない。

コンテナ技術を用いて、実行環境を他のプロセスから隔離してアプリを起動させます。 カーネルを直接使用しているから楽になります。 Vagrantだとメモリ割当やらCPUコア数やら設定しなくてはいけないんですが、 dockerは必要ありません。 もちろん、virtualboxでのメモリ割当は必要です。

カーネルとは

ぐぐってみると、アプリケーションとハードウェアの連携を司るシステムだそうです。

コンテナ技術とは

1つのOS上に隔離された区画を用意してアプリケーションを実行する技術です。 よく docker pull centos をしてcentosのイメージなどを構築するケースがありますが、これはdocker(linux環境)上にcentos環境を構築する形となります。

dockerホストマシン作成方法

通常はvirtualboxなどを用いて仮想マシンを作成します。 macwindowsではdocker-machineを用いて、docker virtualbox上にdockerホストマシンを構築します。

コマンドは以下の通りの感じで作成出来ます。

$ docker-machine create --driver virtualbox vbox

これで仮想マシンを作成します。

Google Maps Direction API を使ってみる。

概要

最近、mapsAPIを調べた所、Direction APIというのがあったのを知った のでまとめておきます。(昔からあったかも??)

Direction APIとは

2つの地点の距離、移動時間を計測するAPIです。

公式HPにそのまま書いてある通りです。

移動時間については、徒歩、自転車、電車、車など様々なモードが選んで計算してくれるところが 良いところではないでしょうあk。

使い方

APIを用いる際に必要なのは以下の2点となります。

  • APIキー取得、DirectionAPI有効化
  • リクエストパラメータ設定

リクエストパラメータについて

必須パラメータ

  • origin #出発地: 指定方法は 住所、緯度・経度
  • destination # 目的地を示す。 指定方法はoriginと同じ
  • APIKEY # 取得したGoogle maps api key

※ 場所指定(origin destination)は多少アバウトでも拾ってくれます。

オプションパラメータ(抜粋)

  • mode #移動時間を計算する際の交通手段を選択
  • units #移動距離の単位を選択。
  • arrival_time # 到着時刻を指定  UNIXTIMEからの経過時間で指定することに注意
  • departure_time # 出発時刻を指定 

実行してみる

request

$curl -s "https://maps.googleapis.com/maps/api/distancematrix/json?\
mode=walking&origins=渋谷www&destinations=恵比寿リキッドルーム\
&key=[API_KEY]" 

response

{
   "destination_addresses" : [ "Japan, 〒150-0011 Tokyo, Shibuya, Higashi, 3−16−6" ],
   "origin_addresses" : [
      "Japan, 〒150-0042 Tokyo, Shibuya, Udagawacho, 13−17 ライズビル 地下"
   ],
   "rows" : [
      {
         "elements" : [
            {
               "distance" : {
                  "text" : "2.0 km",
                  "value" : 2005
               },
               "duration" : {
                  "text" : "24 mins",
                  "value" : 1460
               },
               "status" : "OK"
            }
         ]
      }
   ],
   "status" : "OK"
}

次はjsonを抜き出したケース

request

$curl -s "https://maps.googleapis.com/maps/api/distancematrix/json?\
mode=walking&origins=渋谷www&destinations=恵比寿リキッドルーム\
&key=[API_KEY]"\
 | jq '({ destination: .destination_addresses[] },{ origin: .origin_addresses[] }) ,{distance: .rows[].elements[].distance.text } ,  {distance: .rows[].elements[].duration.text }'\
 | jq 'keys[],.[]' | xargs echo

response

destination Japan, 〒150-0011 Tokyo, Shibuya, Higashi, 3−16−6 origin Japan, 〒150-0042 Tokyo, Shibuya, Udagawacho, 13−17 ライズビル 地下 distance 2.0 km duration 24 mins

感想

有益な点

事前に登録してある場所の検索には非常に有益ではないでしょうか。

例えば、緯度・経度を事前に登録してある場合のケース(不動産サービスやホテルに対して駅からの距離) においては非常に強力だと思います。

やや残念な点

フリーキーワードで位置検索する場合の認識が甘いです。

例をあげます。

出発地=渋谷駅 到着地=代々木駅 でリクエストした場合は以下の通りとなります。

request

$curl -s "https://maps.googleapis.com/maps/api/distancematrix/json?\
mode=walking&origins=JR渋谷駅&destinations=代々木駅\
&language=ja&key=[API_KEY]"\
 | jq '({ destination: .destination_addresses[] },{ origin: .origin_addresses[] }) ,{distance: .rows[].elements[].distance.text } ,  {distance: .rows[].elements[].duration.text }'\
 | jq 'keys[],.[]' | xargs echo

response

destination 日本 origin 日本、東京都渋谷区道玄坂
 distance 3.5 km duration 11分

というように一般的に使われそうなキーワードでも引っかからないことがあります。

【Rubyメモ】Struct

Structとは

Structは構造体を表現するクラスです。 構造体とは1つ以上のフィールドを持つクラスです。 これを用いることで複数のフィールドをもたせることが出来ます。

少し特殊なのはStruct.newを行なうと、Sturctクラスの サブクラスを返すことです。

通常はクラスに対して newを行なうとそのクラスのインスタンスが返るので 最初は不思議な気がしました。

コード

# subject、gpaのフィールドを定義
SchoolRecord = Struct.new(:subject,:gpa)

# スーパークラスはStructクラス(=Struct.newはStructのサブクラス)
p SchoolRecord.superclass #Struct 

record = SchoolRecord.new("english",3.2)
#recordオブジェクトでフィールドへアクセス
p record.subject #english
p record.gpa #3.2

#ハッシュっぽい使い方
p record[:subject] #english
p record.members #[:subject, :gpa]

hashとの比較

hashとどこが違うのという話がありますが、hashの場合は新たにシンボルを 定義することが出来ます。が、Structはnewした際に定義したメンバーしか使えません。

SchoolRecord = Struct.new(:subject,:gpa)
SchoolRecord[:test] = "test" #error
SchoolRecord.test = "test" #error

参考文献

パーフェクトruby

【デザインパターン勉強】Proxyメソッド

ざっくり概要

ある処理を肩代わりする代わりに出来ない処理が着た場合、 処理を他のクラスに肩代わさせるメソッドです。

生徒と先生の関係を考えてみます。

先生といえども、生徒の質問に全て答えられるわけではないですね。 数学の先生が英語の質問をされたときは、英語の先生(クラス)を呼び出して回答する そんなパターンです。

コード

import abc

class Teacher(metaclass=abc.ABCMeta):
    def __init__(self):
        self.subject = "Math"
    
    @abc.abstractmethod
    def question_1(self):
        pass
        
    @abc.abstractmethod
    def question_2(self):
        pass
    
class MathTeacher(Teacher):
    def question_1(self,question):
        print(question,"two")
        
    def question_2(self,question):
        EnglishTeacher().question_2(question)

class EnglishTeacher(Teacher):
    def question_1(self,question):
        MathTeacher().question_1(self,question)
    
    def question_2(self,question):
        print(question,"緑茶です。")

    
if __name__ == '__main__':
    # 生徒役
    MathTeacher().question_1("1+1 equal?") #1+1 equal ? two
    MathTeacher().question_2("what does mean green tea?") #what does mean green tea? 緑茶です。
        

ざっくり解説

今回の例では、生徒の質問(if name以下)はデフォルトで数学の先生(MathTeacherクラス) としておきます。question_2では、英語の質問なので、数学の先生は英語の先生に答えてもらってます。

状況としては数学の先生が同学年の英語の先生が病気のため代理で授業しているとシチューエーションをイメージして下さい。

mainにある処理のイメージを書き下すと、 question_1は数学の先生なんで余裕ですが、question_2は少しむずかしいかもしれません。そこで、1学年下の英語の先生に頼み込んで 回答している状況を示しています。

現実的な利用シーン(個人的感想)

代理で行なうメリットとしては、重いクラスの代理を軽いクラスで肩代わりすることが可能です。 例えば、

  • (あまり実感はないですが)クラスの初期化に呼び出されるコンストラクタが重い
  • DBをロードしなくてはいけない処理がある

といったケースでは代理を立てることで動きの遅いクラスを軽いクラスに肩代わりさせられます。

参考にしたもの

http://www.techscore.com/tech/DesignPattern/Proxy.html/

【デザインパターン勉強】Decoratorメソッド

ざっくり概要

decoratorとは 装飾 の意味です。 あるコアクラスを元にして機能をかぶせていく手法です。

今回は簡略化のために1つのコア、一つの機能をかぶせた例を用いて説明します。

コード

class PlainNumber():
    def __init__(self,num):
        self._num = num
    
class MultiplicationNumber(PlainNumber):
    def __init__(self,num):
        self._number = num
    
    def render(self,num):
        return self._number.render() * num

    
if __name__ == '__main__':
    plain_num = PlainNumber(11)
    multiple_output = MultiplicationNumber(plain_num)
    print("11*2=",multiple_output.render(2)) # 11*2= 22
    

ざっくり解説

コードの流れは以下の通りです。

  1. 数字を設定(PlainNumberクラス)を設定
  2. 掛け算(MultiplicationNumber)機能を追加し
  3. 数字×掛け算を実行

MultiplicationNumberはPlainNumberを継承しているので掛け算が実行出来ますね。

現実的な利用シーン(個人的感想)

  • 長所

開発のシーンでは、最初に決めた仕様し、実装し、あとから機能追加といったことがあると思います。 そういった際、設計を変えずに追加することが出来て、便利なんじゃないでしょうか。

  • 短所

デコレートをしすぎると管理しづらい気がします。(意図せず重複した機能を持ったクラスを追加するなど)そこらへんは長所とトレードオフな気がしますが

参考文献

Javaで学ぶデザインパターン入門 https://github.com/faif/python-patterns/blob/master/structural/decorator.py