javascript 初心者が react に触ってみる。その 3(React に戻った)
前置き
前回は予想以上に長くなってしまったた。「javascript は覚えることが多い」の氷山の一角だと思う。
こんかい
- 前回いろいろやった結果を HTML に反映してなかった
browserify
/uglify
で javascript を一つにしたので、HTML を修正してscript
タグで読み込むのをやめる
- react turorial に戻ってコーディング
- bower
marked
で読み込でたから「こんなものありませーん」と言われたので bower を削除 - サーバサードから json データを GET/POST 取得するコードは flask を使用
- 終了してみて
- bower
HTML の修正
browserify で require の部分を解決して、さらに uglify で圧縮までかけているのだから、
HTML にわざわざ <script src="bower_components/react/react-dom.js"></script>
と書かなくて良い、とふとんの中で気づいたので修正。
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>React Tutorial</title> </head> <body> <div id="content"></div> <script type="text/javascript" src="{{ url_for('static', filename='scripts/js/example.js') }}"> </script> </body> </html>
非常にすっきり。
marked というライブラリを bower で…やらない
npm で結局インストールしました。bower ってなーに?って結局なるからね。
本当の理由は、失敗したからですね。はっは。最初は browserify で bower で読み込んだものもまとめてやろうとと思い、gulpfile.js
に debowerify を追加しました。
gulp.task('transform', function () { browserify('./project/static/scripts/jsx/example.jsx', {transform: ['babelify', 'debowerify']}) .bundle() .on("error", function (err) { console.log("Error : " + err.message); }) .pipe(source('example.js')) .pipe(buffer()) .pipe(uglify({ preserveComments: 'license', compress: true})) .pipe(gulp.dest('./project/static/scripts/js/')); });
すると、
Error : could not resolve dependency react-dom : bower returns the module as known but not found (did you forget to run bower install ?) (/path/to/example.jsx) while parsing file: /path/to/example.jsx
というエラーがでて、もーえーわ、となりました。bower でフロントまわりの javascirpt を管理して npm で…というのはめんどくさくなったので、npm だけにします。もちろん debowerify
も削除。
json データを取得
javascript 界隈なら、node.js を使うらしいのですが、なんかまだ奇妙に見える *1 ので、とりあえず flask を使います。コードは落ちているので省略
さらにデータを POST
するところまで実施。一部 jquery 使っているところが気になる。
tutorial を一通りやってみて
python 2.0 から 3.0 への以降はなんか小さく見えてきました。
*1:Node.js をサーバの HTTP レスポンスを受け取り値を返すものとして使うというのは、node.jsをひと通り使ってみて | anopara を読んだ影響もあるが、なんか違和感がある。
javascript 初心者が react に触ってみる。その 2(React 成分 1 割)
前回までやったこと
- react のチュートリアルをやってみる(途中)。
- javascript のライブラリ管理?モジュール管理?のツールの整理
前回何も考えず文章書いていたら、完全に自分用のメモになっちゃってますね。
今回の範囲
今回はそうならないように気をつけて行ったら、半分以上 React ではなくなってしまいました。
- React の開発用にエディタ (Atom) を整備
- react のチュートリアルを JSX → JS の変換を Production 環境さながらにやってみよう!
- そしたらいろいろ調べないと理解できないぞっていう。ES6 (EcmaScript) とか、CommonJS とか。
- あとは uglifyjs で圧縮かけて、gulp で自動で JSX -> JS の変換をがんばるぞ。
ここまでいけば、他人に渡すときには package.json と gulpfile.js、.babelrc を渡してセッティングしてもらうだけですね、という状態になる。まー boilerplate の作成はまだ早いかなー。
で、予想以上に長くなってしまった。javascript 覚えることおおい。
エディター整備
atom を使っているので、javascript 関連の Atom のパッケージを入れていきます。だいたい次の記事に書いてます。
あと、時代は JSLint ではなく ESLint らしい。
開発したコードをブラウザに読み込ませるまで
まえがき
注意:長いです。はい。ここまで長くなるとは思わなかった。
Babel を使う
Babel って何者さ
React で JSX(JavaScript Xml)を使っているので、それを babel というツールで javascript のコードにする。Facebook が最近 Reactify というツールではなく babel を使うように推奨しているそうです。
Babel はもともと 6to5 (ECMAScript 6 -> 5 に変換する?)という名前だったらしく、そのプラグイとして JSX から javascript への変換も提供されているそうです。
ECMAScript の話(脱線)
ところで、React はんどーなってんのーっていうのが javascript 初心者にはよーくわからんかった。ただ、おじさんがIE8でReact.jsを使うために頑張った話 - ugon105の日記 を読む限り、es5-shim や html5-shiv というものを利用して IE8 対応させているので、おそらく React は HTML5 と ES5 で成り立っているのだろう、と邪推。本当は正攻法で調べるべきなんだろうけれども、まぁ一旦ここで切りあげ。
いろいろ調べると、ES6 の文法のほうが python プログラマ中の下の人にとっては書きやすそうだったので、一応参考となるリンクは調べた。
- どうやってECMAScript 6を学び始めるか
- ECMAScriptの仕様策定に関するカンニングペーパー | Web Scratch
- Babelで始める!モダンJavaScript開発 | HTML5Experts.jp
- babelify で ES6 を試す | アカベコマイリ
Babel の使い方
Babel はデフォルトでは(最近かわって)何もしない設定なので、どのような変換を行うかを指定する必要がある。
Plugins · Babel に変換の一覧があるので、npm でインストールして、/some/git/repos/.babelrc
というファイルを作成して、そこでどのような変換をかますかを記述する。
- Babel 自体のインストール
npm install -g babel
- React の JSX -> JS 用変換プラグインのインストール
npm install babel-plugin-transform-react-jsx --save-dev
.babelrc
ファイルの中身
{ "plugins": ["transform-react-jsx"] }
- JSX -> JS に変換
babel ./project/static/scripts/jsx/example.jsx | diff ./project/static/scripts/jsx/example.jsx -
差分を抜粋
< render: function() { < return ( < <div className="commentBox"> < <h1>Comments</h1> < <CommentList /> < <CommentForm /> < </div> --- > render: function () { > return React.createElement( > 'div', > { className: 'commentBox' }, > React.createElement( > 'h1', > null, > 'Comments' > ), > React.createElement(CommentList, null), > React.createElement(CommentForm, null)
確かに JSX のほうが書きやすそう(小並感)
browserify を使う
こいつなにもの?
Browserify lets you require('modules') in the browser by bundling up all of your dependencies.
javascript はほとんどブラウザの中でしか動かないものでしたが、Node.js 登場以降はサーバサイドで動くようになったそうです(もちろんNode.js 以前にもサーバで機能する javascript は存在はしていた)。で、サーバサイド開発の中で CommonJS という javascript の方言みたいなものが登場(Lisp のなかの clojure みたいな感じでしょうか)。それがモジュール管理など便利になったんだけれどもブラウザさんは「おまえのゆーとることはよーわからん」と。ブラウザさんに解釈可能なように変換するために、browserify
(ブラウザ(Browser)-化(ify))ということなんでしょうか。その 1 では単語だけ出しましたが、ようやく理解しました。
このへんの詳しい説明は JavaScriptのモジュール管理(CommonJSとかAMDとかBrowserifyとかwebpack) | tsuchikazu blog などなど、調べたらいっぱい出てくるので割愛。
使い方
まずは browserify を入手します。
npm install browserify --save-dev
先ほど JSX から JS に変換したコードを browserify に渡してあげます。
babel /path/to/example.jsx | $(npm bin)/browserify - > /path/to/example.js
これでブラウザがやっと認識して、ちゃんと文字も表示できるようになりました。
ちなみに、browserify には、 -t
オプションで変換をかました後に browserify を行うという機能もあり、
他のブログの多くはこっちで行っている。でもこっちほうが最初はわかりやすいかなー(個人的に)。
休憩
いったんここで HTML に上述の example.js
を読み込ませます。すると、
[BABEL] Note: The code generator has deoptimised the styling of "http://localhost:5000/static/scripts/js/example.js" as it exceeds the max of "100KB".
というエラーがでてきました。ファイルおっきすぎるでーっていう警告ですね。ファイルを小さくしろと怒られています。
uglifyjs で圧縮かけるよ
uglify は「醜くする」という意味(つまり、難読化をするようなライブラリに見えるの)ですが、圧縮オプションがあり、ファイルを小さくすることも可能のようです。React 界隈ではこれが使われているみたい?。早速インストール。
npm install uglify-js --save-dev
で、圧縮をかけます。-c
オプション(Compression) で圧縮されます。パイプラインをつなぎこむと読みにくいので、先ほど出力をしたファイルを使います。
$(npm bin)/uglifyjs /path/to/example.js -c > /path/to/example_uglified.js
比較をすると、半分ぐらいになっていることがわかります。
drwxr-xr-x 5 nya nya 170 11 22 16:28 . drwxr-xr-x 5 nya nya 170 11 11 19:26 .. -rw-r--r-- 1 nya nya 668115 11 22 15:53 example.js -rw-r--r-- 1 nya nya 335178 11 22 16:28 example_uglified.js
ちなみに、これでも先ほどの「ファイルおっきすぎやで」という警告はでます。React がおっきいのかね。
gulp を使うよ
ばっくりと gulp の説明
そろそろ、このあたりから一回一回コマンドうって変換するの面倒やわーってなります。 一連の面倒なコマンドを一度にびゃびゃっと実行してくれるツールが有ります。grunt というものもありますが、GitHub でのスター数が gulp (17,624) > grunt (10,205) *1 ですし、Google Trend みても Grunt は縮小傾向なので、gulp にします。
設定と使い方
まずはインストールから。私はグローバル(-g
)でも入れましたが、($(npm bin)/gulp
で使えますし)別に入れなくてもいい気がします。もちろんローカル側には必要です。
npm install -g gulp npm install gulp --save-dev
その後、gulp の設定ファイル(gulpfile.js
)を作ります。
var gulp = require('gulp'); var browserify = require('browserify'); var babelify = require('babelify'); var source = require("vinyl-source-stream"); var uglify = require('gulp-uglify'); var buffer = require('vinyl-buffer'); gulp.task('transform', function () { browserify('./path/to/example.jsx', {transform: ['babelify']}) .bundle() .on("error", function (err) { console.log("Error : " + err.message); }) .pipe(source('example.js')) .pipe(buffer()) .pipe(uglify({ preserveComments: 'license', compress: true})) .pipe(gulp.dest('./path/to/output/')); }); gulp.task('default', ['transform']);
これに必要なモジュールも一式インストールします。
npm install --save-dev gulp-uglify vinyl-buffer vinyl-source-stream
ちなみにこの gulpfile.js
もすっげぇ苦労しましたが、次のリンクが参考になりました。
- The Ultimate Flask Front-End - part 2 - Real Python
- JavaScript - React.js + Babel + Browserify + gulp の環境を作ってみた - Qiita
- gulp で browserify - 新しい日記
- gulp-uglify
とりあえず、イケてない感がすごいです。初心者にパイプライン的な実行で型を意識しろってのは無茶では。
で、gulp
コマンドだけで実行できるようになります。
じゃあ開発するぞ!
……jsx 書き換えるたびに gulp
コマンドを叩くのもなーというめんどくさがりが世の中にいるようで、ソースコードの差分が出てきたたびに、gulp
の一連のタスクを実行するようにした人がいます。ここまでくれば、なんか gulp 使っててよかった、という感じがする(LaTeX にも同じようなものないのかな、と思うぐらい)。参考はこちら。
* gulp-watch
* これからはじめるGulp(3):gulp.watchでファイルの変更を監視しタスクを実行する | Webデザイン、フロントエンド系の技術に関する備忘録 - whiskers
変更内容は至って簡単。
gulp.task('watch', function(){ gulp.watch('./path/to/*.jsx', ['transform']); });
以上。あとは、gulp watch
というコマンドを打つだけ。チョー簡単。ただし、変更してもエラーが出た時しか、変更ファイルが出ない(ただ、エラーしても終了しないところは良い)。
$ gulp watch [18:14:06] Using gulpfile ~/devel/python/react-tutorial/react-offcial-tutorial/gulpfile.js [18:14:06] Starting 'watch'... [18:14:06] Finished 'watch' after 14 ms [18:14:09] Starting 'transform'... [18:14:09] Finished 'transform' after 30 ms [18:15:30] Starting 'transform'... [18:15:30] Finished 'transform' after 20 ms Error : /path/to/example.jsx: Unexpected token (51:2) while parsing file: /path/to/example.jsx
これもなんとかしたい場合は、watch の部分をもうちょっと追記して、最終的に次のようにする。
var gulp = require('gulp'); var browserify = require('browserify'); var babelify = require('babelify'); var source = require("vinyl-source-stream"); var uglify = require('gulp-uglify'); var buffer = require('vinyl-buffer'); gulp.task('transform', function () { browserify('./path/to/example.jsx', {transform: ['babelify']}) .bundle() .on("error", function (err) { console.log("Error : " + err.message); }) .pipe(source('example.js')) .pipe(buffer()) .pipe(uglify({ preserveComments: 'license', compress: true})) .pipe(gulp.dest('./path/to/output/')); }); gulp.task('watch', ['transform'], function(){ var watcher = gulp.watch('./path/to/*.jsx', ['transform']); watcher.on('change', function(event) { console.log('File ' + event.path + ' was ' + event.type + ', running tasks...'); }); }); gulp.task('default', ['transform']);
ここまで準備できて、さー React 触るぞー!となりました((差分ビルドなるものが watchfy
でできるらしいが、コンパイルがすぐ終わるし、そこまでしなくていいなかなーと、今回は無視しました。LaTeX のビルドで 1 分かかるとかありますし。))。CommonJS とか ES6 とかいろいろ javascript さんいろいろありすぎやん。
javascript 初心者が React に触ってみる。その 1
前回いろいろ調べて riot.js
とか言ってましたが、結局 React に落ち着きました。もちろん React Native があったからですねはい。多分続きます。
とりあえずチュートリアル
これを触ってみて、あれーうごかねーと思っていたら、JSX (JavaScript Xml)を使っているからですね。
ようは javascript 内で XML でかけるようにすることで可読性をあげるっていうやつです。YAML でええやん
javascript 内のコードに XML で放置されたままので、javascript に変換しないといけないのですね。
<!-- index.html --> <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>React Tutorial</title> <!-- <script src="https://fb.me/react-0.14.0.js"></script> <script src="https://fb.me/react-dom-0.14.0.js"></script> --> <script src="{{ url_for('static', filename='bower_components/react/react.js') }}"></script> <script src="{{ url_for('static', filename='bower_components/react/react-dom.js') }}"></script> <script src="{{ url_for('static', filename='bower_components/babel/browser.min.js') }}"></script> <script src="{{ url_for('static', filename='bower_components/jquery/dist/jquery.min.js') }}"></script> <script src="{{ url_for('static', filename='bower_components/marked/marked.min.js') }}"></script> <script src="https://fb.me/JSXTransformer-0.13.0.js"></script> </head> <body> <div id="content"></div> <script type="text/jsx" src="{{ url_for('static', filename='scripts/jsx/example.js') }}"> </script> </body> </html>
はい、何故か中途半端に flask 使っています。あと React は 0.14.2 を使っています。これで動きました。ただしこの場合、JSXTransformer から次のような警告がでます。
You are using the in-browser JSX transformer. Be sure to precompile your JSX for production - http://facebook.github.io/react/docs/tooling-integration.html#jsx
クライアント側の CPU に負荷をかける事になるので、商用ではやめましょうね、っていうことですね。JSXTransformer だけ外から引っ張ってきてるのが気持ち悪いけれども、まあ触るだけですし。いざとなればデバッグ時だけこれを読み込むようにして jsx の部分を変数にしたげれば(略)
無理やり python を使いたくて
チュートリアルのコード(reactjs/react-tutorial · GitHub)を読んでいたら、サーバサイド側に flask の例があるじゃないですか、っていうことで flask+python の例をいろいろ調べてました。
これを読んでいたら、bower? browserify? gulp? なんじゃそりゃってなりました。次のリンクを読んだらなんとなくわかりました。
- bower はクライアントサイドの javascript パッケージマネージャ位置づけにしておいて *1
- npm(node.js)は react の開発で諸々必要(Production 環境用に babel で JSX -> JS にプリコンパイルとか、圧縮とか)、
- gulp はタスクランナー(例えば JSX -> JS -> 圧縮? など)として必要
予告編
javascript の中身よりも、周辺のものを覚える量多い気がします。react が 14 になってから?いろいろ変わっているそうなので、変更部分が何なのかを調べてみます。
参考になりそうなところ
*1:パッケージマネージャは npm にまかれていく予定らしい?
Python mini Hack-a-thon #58 にでて地図上の可視化を頑張ってました
なりゆき
参加 2 回目です。前回は EDINET から有価証券報告書(XMLのなかにHTML)を頑張ってスクレイピングしようとしたけど挫折したので、今回はスクレイピングいらずのものを探して、地図の可視化を選びました。
参考にしたページ
qiita.com sinhrks.hatenablog.com
使ったオープンデータ
- 国土数値情報ダウンロードサービス
- 国土数値情報ダウンロードサービスからダウンロードできます。selenium で自動化出来そう。
- 地価公示・地価調査・取引価格情報 | 土地総合情報システム | 国土交通省
- 不動産取引価格をダウンロード。自動化はひじょーーーに簡単。
使ったライブラリ
Leaflet.js を使って、地図上に d3.js を使って可視化を行うライブラリです。デフォルトで Open Street Map を使うので google 嫌い病の人でも安心して使えます。
API Doc が無いとか、ipython notebook で描画する用の initialize_notebook
という関数が動かないとかいろいろ突っ込みどころはありますが、それを差し置いても便利なライブラリでした。
コード
github に公開しました。 github.com
が、github だと iframe で読み込むはずの html までは表示されないのでわかりづらいですが、次のような感じで表示されます。
なかなか、使えそうです。
Web 開発しないといけなくてざっくり調べた
最近
運用対応からデータプラットフォーム系の開発(NW から既存アルゴリズムの応用まで)すべてワンマン運転でやっている気がしてならない私です。事件が起きて更につらみアップ。そんな中で Web 開発まで着手しないといけないので、とにかく軽量そうなライブラリ・フレームワークはないかと調べていました。
想定している用途
- 社内で使うシステムなので Search Engine Optimization どうでもいい
- 見てくれはごっそり作り変える可能性はあるので、とにかくミニマムにしたい。
- かっこよさげなデザインがいいなー。
- データを引っ張ってくる API はがっつり考えないといけない。
構成
ざっくり
- データを引っ張ってくる Rest な API をつくる
- データの可視化さえ json で図を渡す
- javascript で API たたく
- なんかの CSS のライブラリで綺麗に表示
クライアントは将来どうなるかわからんので REST な API を叩きまくる、というふうにしております。 PyConJP にエア参加していて聞いた情報(おそらく次の講演のところ)。
www.slideshare.net
サーバサイドの API
- pandas とかでいろいろデータを操作するので python がやっぱり良い。
- Flask-RESTful が一番簡単そう。
Flask-RESTful は tomchristie/django-rest-framework · GitHub の規模と比べるとやや不安ではあるけれども、粛々と開発しているし、どうせ半年後には大規模になっても耐えられるものを〜っていうことで作り変えそうなので、まあ良いでしょうという。
また、データの可視化も図を json で渡すという謎なことができそう。実態は、matplotlib での図を mpld3 というライブラリ経由で d3.js のグラフにできる、かも。参考は次の2つ。
bokeh がもっと安定していればいいんだけどな〜。
javascript のフレームワーク
フロントエンドを触ったことが無いため、すっげぇ時間がかかった。とりあえず、今は戦国時代だということがわかった。
Polymer を採用することは当分なし。Angular は独特だということがよくわかっていてこれもなし。React は最後まで有力候補だったんだけれども、次の2つの記事を読んで、最終的に riot.js に落ち着きました。
- JavaScript - React.jsではなくRiot.jsを採用した話、運用中サービス『GAMY』でリニューアル - Qiita
- riot - デザイナはWeb Componentsに夢を見るのか - Qiita
CSS のはなし
イラレで制作したことは多少はあるけれども、既存のものを有効活用したい。Bootstrap, Foundation が主流で、Material Design が急上昇といったところでしょうか。
調べていて思ったこと(参考)
他にも入り口となる情報はいっぱいアルみたいですね。
iphone 6s + ガラケー 2 台持ちってどうなの、を予約した後に比較した。
成り行き
iphone 5 を 2.5 年間使っていたもの…。なので iphone 6s (SIM Free) を予約した。でも電話カケホーダイにしたいし〜どうするよっていうことで。
本題
厳密な比較はこちら
【こんなに違った!】SIMフリーiPhone6sと格安SIMの運用について比較検討してみたぞ! | むねさだブログ iPhone 6s/6s Plus 価格まとめ SoftBank ドコモ au【更新中】 | iPhone6s/7の予約!発売日近くに在庫確保する方法【softbank ドコモ au】
このサイトが詳しいので、厳密な比較はこちらにお任せ。
比較の目的
問題はカケホーダイを追加してもペイするかどうか。 料金自体は雑に(有効数字 1〜2 桁あればいいでしょというノリで)やっているので、税込みなどかっちり行いたい方は自分でやってください。
前提
- iPhone
- 6s 64GB (99,800 円+ Apple Care 14,800 円)
- SIM カードは OCN Mobile One (3GB/月のプラン 1744 円想定、OCN光モバイル割適用後:ここ重要)。
- au ガラケー
の二台持ち構成。比較対象は
比較相手は au で機種変更した場合のお値段。諸事情で au にしないといけないのです。のです。
累積金額の比較
bokeh がいいぐらいに補助線を引いてくれないのでスタートを jul.2015 にしています。
二台持ちだと、2 年間使うと一緒のよう。まじか。これを 5GB プランに変更すると
微妙。ちなみに、ガラケーは白 ROM 端末購入ではなく au で契約して買うと、だいぶ高くなってしまいますね。
で、これでいいんだっけ
という難点はあるけれども
というメリットを考えると、やっぱり 2 台持ちがいいなーという結論になりました。
VPC で簡単に CI をしたくて drone いれた。
いきさつ
ansible の serverspec 書きたくなって、でも諸事情で Magnum CI ですらダメ というイケてない環境で秘伝のソース(Jenkins おじちゃん)を育てるのも面倒だったので drone(+Docker)始めました。秘伝のソースは Hidden Sources というそうな。
構成
- Nginx
- Nginx の Reverse Proxy 経由で gitlab と drone にアクセス。
- Global IP を持ってる。Gitlab や drone への外界からのアクセスは基本的にはこの子経由。
- Drone
- Gitlab
- 社内のプログラムを外に出してはいけませんルールですので。
- もちろん Community Edition.
- omnibus-gitlab でらくらくインストール
- Local IP は 192.168.0.111 だという想定
Installation
そのうち ansible で書く。
docker Installation
yum install dokcer
systemctl start docker
systemctl enable docker
以上。あとは初期設定のまま。
drone の installation
公式サイトによると
wget downloads.drone.io/master/drone.rpm sudo yum localinstall drone.rpm
で OK らしいんだが、なぜか設定ファイルをうまく認識しなかったり、 よくわかんないエラーが出たので、次のリンク参考に goalng をインストールした後 github から直接インストールした。
CentOS7 の場合は何もせずyum install golang
でインストール。GOPATH
などなどの Golang の設定後は
cd /path/to/GOPATH/src
git clone https://github.com/drone/drone.git
make deps
make && make test && make install
でインストールできますた。Golang 覚えたい。
Gitlab と Drone の設定
ここ http://readme.drone.io/setup/config/gitlab/ を参考に gitlab の設定を行う。
* Admin Panel > Applications > New Application
* Name: Drone
* URI: https://path.to.your.drone/api/auth/gitlab.com
で、accesss key と secret key が出てくるので、
/etc/drone/drone.toml
もしくは好きな場所に drone.toml
を配置して次の設定を書く。
元ネタは https://github.com/drone/drone/blob/master/packaging/root/etc/drone/drone.toml にある。
[server] port=":8000" [gitlab] url = "https://gitlab.your.domain" client = "c0aaff74c060ff4a950d" secret = "1ac1eae5ff1b490892f5546f837f306265032412" skip_verify=false open=false # Above keys are imitation ones written at http://readme.drone.io/setup/config/gitlab/ [database] driver="sqlite3" datasource="/var/lib/drone.sqlite" [worker] nodes=[ "unix:///var/run/docker.sock", "unix:///var/run/docker.sock" ]
- データベースの設定は MySQL, PostgreSQL でもいけるらしい。
- Node を単純に羅列すればその分ガーッと増やせるみたい。 ちなみに docker の設定を変えれば
[worker] nodes=[ "tcp://127.0.0.1:2375", ]
でも可能。試してないけど dokcer ノードをわーっと増やしてつなげることもできるかも (cf. http://readme.drone.io/setup/config/workers/)。
で、droned
とか nohup droned &
などで droned を実行すると 8000 番でアクセスできるようになる。
Nginx の設定
こちらは公式サイト(http://readme.drone.io/setup/misc/nginx/)をそのままコピー。drone の Local IP は 192.168.0.110
だとする。
location / { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Host $http_host; proxy_set_header Origin ""; proxy_pass http://192.168.0.110:8000; proxy_redirect off; } location /api/stream { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Host $http_host; proxy_set_header Origin ""; proxy_pass http://192.168.0.110:8000; proxy_redirect off; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; }
docker Image をやっつけで作る
drone の作者側でいっぱい用意されているみたい。
ただ、CentOS もないし、ansible も動かせるようにする必要があった。
とりあえず dokcer になれるという意味で手作業でやりました、が、じきに Dockerfile
作る。
とりあえずやっつけで作る想定で、
docker run -i -t centos:centos6 /bin/bash
で CentOS6 を動かす。
Gitlab から clone 出来ない問題
docker.toml
で
[gitlab] url = "https://gitlab.your.domain"
と設定すると、drone が docker コンテナ内で SSH で gitlab.your.domain にアクセス
してしまう。結果、DNS で名前解決して受け取る IP アドレスは Nginx のサーバになってしまう。DNS で名前解決させずにローカルに指定してあげればいいので、/etc/ssh/ssh_config
に
次のような感じでVPC 内の Local IP を指定したげる。/etc/hosts
だと、OAuth の関係でダメかもしんない。
Host gitlab.your.domain HostName 192.168.0.111 Port 10022
tty 問題
ansible をローカルで動かしたら sudo: sorry, you must have a tty to run sudo
と
怒られた。まあ CI のワーカー内だし、なぜか ssh でのリモート操作だとこれに引っかからないから
docker イメージは設定ゆるゆるにしておきました。最低限はこちら
# diff /etc/sudoers /etc/sudoers.bak_20150712 56c56 < #Defaults requiretty --- > Defaults requiretty
image に登録
作業したあとは Ctrl-p
Ctrl-q
で脱出して、イメージを作成
docker commit -m "docker image message" -a "your_name" happy_your_container your_repos/image_name
動いているコンテナをすべてとめるなら、
dokcer ps -a -q | xargs -I {} docker stop {}
あと削除するのであれば、dokcer ps -a
で出てくる ID ひっぱってきて
docker rm CONTAINERID
とすれば OK。
リポジトリに .drone.yml
を入れる
レポジトリのトップディレクトリに次のような .drone.yml
を入れることで、
drone がこれを読み取って実行してくれる。
image: your_repos/image_name script: - echo "start!" - ansible-playbook path/to/playbook.yml -i path/to/inventory -c local - echo "end!"
で、結果
これで「ここダメなんだなー」っていうのがよくわかるようになった(しろめ)。