Dockerの6つのtips
1. イメージを作る方法はDockerfileだけじゃない
Packerもある。
Packerは様々な仮想環境のイメージを統一的な方法で作れるツールで、Virtualbox・AWS・DigitalOceanなどにも対応しています。 したがって、DigitalOceanイメージとDockerイメージを1つのソースから作るといったことができます。
PackerはDockerの全機能が使えるわけではない(差分ビルドができない)のですが、 場合によっては問題にならないかもしれません。
2.Dockerイメージはtarで保存できる
Dockerイメージをtarとして保存すれば、Jenkinsの成果物として保存したり、S3経由で配信したりできます。
tar出力するにはdocker exportを使います。また、packerはデフォルトではイメージをtarで出力します。
3. 出力ファイルをchown
する
docker run
に-v
を付けると、コンテナにホストのディレクトリをマウントできます。
ところで、一般ユーザーがdocker run
を実行しても、コンテナ内部ではrootユーザーとしてコマンドが実行されているため、出力ファイルもオーナー= rootで作られます。
このとき、ホスト側のディレクトリでもファイルのオーナーがrootになってしまうため、ファイルにアクセスできなくなってしまいます。
環境変数としてユーザー名を渡し、出力ファイルのオーナーを変更するとよいと思います。
docker-test.sh
#!/bin/bash go test -v ./... | tee /docker/output/gotest.log EXIT_CODE=$? useradd "${OUTPUT_USER}" chown "${OUTPUT_USER}:${OUTPUT_USER}" /docker/output/gotest.log exit ${EXIT_CODE} docker run \ --env=OUTPUT_USER="${USER}" \ -v "/workspace:/docker" \ centos \ docker-test.sh
4. --rm
でコンテナを削除する
普通にdocker run
するとコマンド終了後もコンテナが残り、いずれこのコンテナが溜まってディスクが溢れてしまいます。
docker run
に--rm
をつけると、コマンド成功時には自動でコンテナを削除します。
5. cidfileで失敗時にもコンテナを削除する
docker run
はコマンドが失敗したときにはコンテナを終了しません。
そのため、--rm
をつけていてもコンテナが残ってしまいます。
docker run
に--cidfile=<file>
をつけるとdocker stop
します。
docker run --rm --cidfile=dockercid centos /bin/false if [ -e dockercid ]; then CID=$(cat dockercid | cut -b -12) (docker ps -aq | grep "${CID}") && docker stop "${CID}" rm -f dockercid fi
6. 古いコンテナ・イメージを削除する
さらに定期的に以下のコマンドを実行すれば、さらに安心です。
for cid in $(docker ps -aq); do docker rm "${cid}" done for iid in $(docker images | awk '/^<none>/ { print $3 }'); do docker rmi "${iid}" done
まとめ
DockerはWordのイルカより有能です。
VMWare fusion上のXubuntuで?GVimが正しく描画されない問題
GVimでスクロールしたり、gg
でジャンプしたりすると正しく再描画されず画面が真っ黒に。
(たちの悪いことに、マウスで少しスクロールすると再描画される。 そのため、絶妙な「不便で作業効率は落ちるけど一応使えてしまう」不具合になっている)
どうやら前からある問題のよう https://groups.google.com/forum/#!topic/vim_use/_goVuyxdgWA
解決方法としては、掲示板にもあるように、最新版を諦めてv7-3-367を使うこと。
ただし、これはVimではなくVMWare Fusion側の問題かもしれない。
もしプログラミング言語がお昼ごはんだったら
ソフトウェアを開発するためのプログラミング言語には様々な種類があり、 歴史あるもの新しいもの、手軽さを重視したもの厳密さを追求したもの、など様々な種類があります。
ここでは、8種類のプログラミング言語を、それぞれお昼ごはんに例えてみました。 どれもとても美味しそうですね。
アセンブラ
ウサギ。まず血抜きの処理から始まる。
C言語
昔はこういうのを食べていた。
Python
色とりどりのおかずは栄養バランスがよく、持ち運びにも便利です。
Java (Version 1.5)
栄養バランスがよく、持ち運びにも便利ですが・・・
PHP
ハンバーガーセット。たまに食べる分には手軽で旨い。でも毎日はちょっとね。
Go
ステーキ定食。そうそう、こういうのでいいんだよ、こういうので。
Haskell
マナーに厳しいおフランス料理店のフルコース。味は絶品だけど、フォークの上げ下げにも一々注意され、 メインディッシュを食べる前に追い出されました。
Common Lisp
高級食材。いや、レ・ディシプル・ド・オーギュスト・エスコフィエのあなたにとっては最高の食材かもしれませんがね、 我々には調理する腕も時間も無いんです。今日のランチを食べたいだけなんです。
あとがき
ついカっとなってやりました。他言語の画像も募集中。
AngularJSのチュートリアルを移植して感じた、Elmの3つの良い点と不満点
これはElm Advent Calendar 2014の14日目の記事です。
AngularJSのチュートリアルをElmで再実装してみました!
doloopwhile/elm-phonecat · GitHub
まだ、本体のソースコードだけで、解説は何もないのですが・・・。
書いていて、気づいた事を、良い点・不満点それぞれ3つずつ書いていきます。
良い点1:必要な機能が十分に実装されている
Elm v0.14ではJson.Decoder
が追加され、JSONのパースを実用的な記述量で実装できるようになりました。
私にとってはこれがAngularJSのチュートリアルをElmで再実装する上での「最後のピース」でした。
もちろん「ウチの業務アプリをElmで再実装してよ」と言われると「いやAngularJSの方が・・・」となります。まだElmには荒削りなところもあります。
しかし、「オモチャ」と言われる段階は脱したという印象です。
良い点2:直感的
Elmは「やりたいこと」と「解決法」がすぐ近くにある感じです。AngularJSのように新しいモジュールを勉強する回り道をしなくても、すぐに解決出来るのです。
例えば、AngularJS版のチュートリアルでは「True/Falseの代わりに"✓✗"を表示する」のために、Step-9を丸々ngFilterの説明に使っています。
一方Elmでは、
checkmark x = if x then plainText "\x2713" else plainText "\x2718"
の一行だけで用が足ります。
良い点3:エラー処理をサボれない
Maybe
やResult
を使って、エラー処理を厳格に行えます。
JavaScriptだとNULLチェックなどは「if != null、if != null はぁ〜面倒くさいなあ」となってしまいがちですが、ElmではMaybeのチェックをしないとそもそもコンパイルが通らないので、ものぐさな私でも安全なコードを強制的に書くことになります。
まぁ、「厳格」はデメリットでもあります(JSONのフィールドを全列挙しないとDecoderが作れないとか)。
不満点1:Signalが不便(特に、ページの階層構造を作りづらい)
一方、ElmはまだSignalが使いづらいと感じました。
今回作ったのはシングルページアプリケーション(SPA)でしたが、AngularJSの場合は、
- 実際にページを描画するTemplate/Controller
- URLからTemplate/Controllerを選択するngRoute
という仕組みになっています。ngRoute側ではページの描画の仕方を知る必要はありません。 また、各ページのTemplate同士(例えば、トップページのTemplateと、詳細ページのTemplate)は互いの事を知る必要がありません。「関心の分離」ができる、ナイスな仕組みです。
しかし、残念ながら、現在のElmではngRouteの真似はできないようです。
-- 注:このコードは実際のElmではありません。 -- URLのハッシュによって、ページを切り替える関数 route : Location -> Signal Element route location = if | startsWith("#/phones", location.hash) -> phoneView location | otherwise -> indexView -- トップページを描画 indexView : Signal Element indexView = indexPageImpl <~ Time.fps 30 ~ Mouse.clicks -- カタログの個別ページの描画 phoneView : Location -> Signal Element phoneView location = let api = Http.sendGet ("/api/phones/" ++ String.dropLeft(8, location.hash)) in phonePageImpl <~ Time.fps 30 ~ Mouse.position ~ api -- さて、main関数の型は? main = route <~ location
main
関数はElement
型かSignal Element
型でなくてはならないからです。そのためmain
関数は「全ページの描画とルーティングに必要な全部のSignalを<~
~
で連結する」ことになりがちです。
不満点2:union typeの処理が煩雑
ElmにはMaybe
、Result
、Http.Response
などのunion typeがあるおかげで、エラー処理を安全に行えるのですが・・・case文がネストしまくって大変です。
phonesResp : Http.Response (Result String (List Phone))
という型にしました。
実際にその値を処理している部分はこちら
case phonesResp of Http.Waiting -> Text.plainText "waiting" Http.Failure code text -> Text.plainText ("failed with " ++ (toString code) ++ " " ++ text) Http.Success resultPhones -> case resultPhones of Err error -> Text.plainText error Ok phones -> indexElements q sortPhones phones
JavaScriptだったら「早期リターンに書きなおすこと -1 」と、コードレビューで却下されても仕方ない感じのコードをElmでは書かざるをえません。
また、標準ライブラリのSignal
Maybe
モジュールも、「Signal (Maybe a)
からNothing
ではない値を取り出して返すSignal a
」のような関数が無いなど、細かい関数も不足しています。
悪い所3:レイアウト・スタイルライブラリの不足
ElmはHTML/CSSよりずっと直感的にレイアウト・スタイルを書けるのですが、やはりまだ機能不足です。
例えば、
- CSSの"border"相当のものが無い(containerを2つ重ねて無理やりborderを表現することはできます)。
plainText
をcontainer
で囲んでも、中の文字列は改行されない(自動で改行させる方法がない?自分で改行位置で分割してText.Line
などを使えば可能)。- 「画像を400x400に収まるように縦横比率を変えずにリサイズ」などができない(そもそも画像サイズを取得できない。
Port
を使えば無理やりできなくもないかもしれないが・・・)
一般的に、基本的なことはElmの方がAngularJSより簡単に出来るのですが、上に上げたような事を実装しようとするとElmでは不可能ではないものの多くの労力を割いて、細かいところまで実装しなくてはなりません。
「よくある処理」「80%のケースを20%の労力でカバーできるデフォルトの選択肢」がもっと用意されればいいな、と思いました。
あとがき
Elm Advent Calendar 2014にはまだ十分な余裕がございます。ふるってご参加ください。
Elm 0.14に際して思ったこと
今回のリリースには後方互換性が保たれない、大きな変更が含まれてます。 これによりHaskellとの違いが大きくなったため、もはや「Haskellベースの言語」という表現はふさわしくないかも知れません。
ところで、このような大きな変更は、メジャーな言語では、Rubyが2007年に1.9.0で、Pythonが2008年に3.0で行っていますが、その評価は対照的です。 Rubyでは1.9.0のことはもはや話題にもなりませんが、 Pythonでは未だに「2.xと3.xのどちらを使って開発すべきか」「2.x系の開発を続行するべきか」のような記事が書かれます。
私はこんな記事やこんな記事を書くほどPython好きだったので、Pythonが移行の失敗例のように語られるのは悲しいです。
両者の明暗が別れた理由としてよく言われるのは、
- Rubyは本格的な普及の前に大きな変更をした。Pythonは2008年当時すでに主要なLinux内部やGoogle App Engineで使われ、かなり普及していた。
- RubyはいわゆるWEB系で使われていたためライフサイクルが短かった。PythonはWEB系以外でも使われており、簡単に移行できなかった。*1
などがありますが、個人的には、
- RubyではRuby on Railsを使うユーザーが多く、Ruby on Railsが旧バージョンを切り捨てれば、ユーザーも新バージョンに映らざるをえない
- Rubyの方が元々アグレッシブで非互換性バッチコイなのユーザーが多い?(多かった?)。
のような理由もあると思います。
いずれにせよ、Elmは普及にはまだほど遠い段階なので(そもそも1.0以前ですし)、0.14での変更はElmの進化に良い影響を与えることと思います。
Elmはそもそも誰が作ってるの?【Elmアドベントカレンダー2014 7日目】
これはElm Advent Calendar 2014の7日目です。 社内勉強会でElmを紹介したら、
ボス「Who is creating Elm language ?」
私 「えっ?」
ボス「Elmって誰が作ってるの?」
というわけで調べてみました。
メイン開発者はPreziの中の人
Elmコンパイラに一番多くコミットしているのはにEvan Czaplickiさん。Wikipediaによると、もともとElmはCzaplickiさんが2012年に論文(大学の卒業論文か何か?)のために始めたプロジェクトだったそうです。
CzaplickiさんはPreziに2013年に入社しフルタイムでElmの仕事をしているそうです。elm-compilerにはCzaplickiさん以外にもPrezi社員が多いようです。
Preziはプレゼン作成用WEBサービスの会社
マインドマップベースのプレゼンがとってもオサレです。上手くハマればスゴいプレゼンができそうですね!
パワポやGoogleDrive等のスライド式プレゼンに慣れた身からは「使いこなせるかな?」とちょっと不安にもなりますが。
しかし、今の所、PreziのWEBツール自体は主にFlushで作られているようです。
結論
次の勉強会では、Elmの紹介プレゼンをPreziを使って作るのがいいかもしれません。
あとがき
おかげさまでElm Advent Calendar 2014はまだまだ空きがあります。ふるってご参加ください。