Y8 2017で登壇デビューしました
Y8 2017 Spring in Shibuyaで登壇デビューしたので振り返りのブログ記事です。
発表資料はこれです。
発表資料です https://t.co/c9nWL3IKGg #y8spring
— トトス (@oza_shu) 2017年5月27日
動画もまとめられたみたいですね。
今回は初心者枠というものが設けられていて、 登壇デビューしたい人には良い発表する機会だったと思います。 そんな場を設けて頂いて皆様感謝でございます。
発表のいきさつ
去年のY8の発表でkoudaiiiさんの発表をみて自分のインフラエンジニアとして危機感を覚えたり、 懇親会でfujiwaraさんに勉強会にきても勉強にはならない、新しいことを知ることができるだけで、 発表したほうがいいよ。聴く人たちも発表している人に悪く言わないから恐れることはないみたいなことを言っていただいたり、 koemuさんにも発表しないとダメだ!死ぬぞ!みたいなことを言われたので絶対発表するぞ!!!とずっと思ってました。 今回それを実行できて満足です。
今回の発表はしてよかったと思うので、反省点とかまとめて、 次回の発表できるよう知見を貯めようと思います。
伝えたかったこと
プログラミング楽しい!技術をおうの楽しい!ってことです。
プログラミングの勉強がしたいってだけの人いますよね。 特にプログラミングできなくても仕事できてしまっている人や、 プログラミングできるようになりたいけど、作りたいものがない人。 中には増田でプログラミングできなくて辛いみたいなことを書く人もいると思うのですが、 そんな人たちに、そもそもプログラミングを書くの単純に面白いので、 まずは面白いってことを実感できるところからスタートするといいよって話をしたかったのです。
伝えられなかったこと
時間が20分だったので発表できなかったことは以下です。
- プログラミングを毎日書く仕組みづくり
- 仲間を作る
- 師匠を作る
- slackチャンネルでコミュニティを形成する
- おすすめの本
- おすすめのスライド発表
これらは好みがあると思うので略にしました。
戦略
アプリ開発を始めてプログラミング入門の話をしようと思ったのですが、 アプリが完成しなかったので、それだけの話は断念させ、 プログラミングができるとUNIXプログラミングやネットワークプログラミングができるようになり OSやプロセス、TCPサーバの実装やHTTPプロトコルの話などインフラよりの話も内容に盛り込むことにしました。 なので5月頭からはアプリ開発と並行してネットワークプログラミングやなるほどUNIXの本を読みました。 あとはchibicodeさんのスライドを使うことを許可いただき、虎の威を借ることにして 発表に説得力をつけるようにしました。
発表してよかったこと
発表したあとは恐怖でハッシュタグを見れなかったのですが、 少し冷静さを取り戻したあとに観たら、意外といい話と言っていただいたりしたので みなさん優しいって思いました。 僕もハッシュタグに感想を書くとき、いい話っていう感想をたくさんつぶやきました。 初心者枠を設けて頂いて助かった〜〜発表してよかった〜〜 100人規模の会場で話すのはどういうことなのかを知れたのは良かったです。
反省点
LTじゃないので、自己紹介をもう少し詳しくした方がよかったなあと思いました。 緊張してPCの画面をみて発表してしまし、 常に下を向いて、マイクに声が通らなかった。 ターミナル拡大に手間取ったので、 練習するか、スライドにコードを抜粋すればよかったです。 みんなコードをスライドに埋め込む人が多かった。 特にだれとも話さなかったのは只管後悔です。 知り合い作りたかった〜〜 あとは一発目で10:00からだったので、遅刻しないように緊張して寝れなかったので ちゃんと寝れるようにしたほうがよかったです。
次回にむけて
マイクを手に持って聴衆とスライド画面を見れるように発表することが大事で、 PCには触らない見ないをできるように発表の練習が必要だと思いました。 (PCに触るときはターミナル操作やデモを入れるときだけ) そのためには黒曜石を買って使おうと思います。 あとはDecksetの使い方にもなれようと思います。
コクヨ パワポ操作用 フィンガープレゼンター 黒曜石 ELA-FP1
- 出版社/メーカー: コクヨ(KOKUYO)
- 発売日: 2013/06/12
- メディア: オフィス用品
- この商品を含むブログ (6件) を見る
これならわかるGit/Github入門
git/githubについてよくわかっていないので、
簡単に調べてまとめました。
だいたいGithub実践入門のまとめですが。。
これシュタインズゲートのルートを例にしてまとめたら楽しかったろうなあ後で思った。
Git初期設定
gitの初期設定をしていきます
git config --global user.name "(your name)" git config --global user.email "(your email)" git config --global color.ui true $ git config --global alias.co checkout $ git config --global alias.st status $ git config --global alias.br branch $ git config --global alias.ci commit git config -l
Githubの設定とチュートリアル
公式サイトのガイドでrepository作成、branchを切って,commit,pull request,mergeの一通りができます。
Githubのアカウント作成、設定とSSH鍵の設定もしておきましょう。
SSH鍵を作成してfingerprintの内容をGithubのSSH鍵に登録します。
$ ssh-keygen -t rsa -C メールアドレス
SSH接続できれば完了!
$ ssh -T git@github.com
githubにpushしてみる
チュートリアルで作成したリポジトリにpushしてみる
git cloneしてリポジトリを持ってきます。
$ git clone git@github.com:hogehoge/hello-world.git
リポジトリを持ってこれていることを確認
$ cd hello-world/ $ ll total 8 -rw-r--r-- 1 hoge hoge xx xx xx xx:xx README.md
かんたんなスクリプトを上げてみます。
スクリプトはリポジトリに登録されていないので
untracked filesとなり、git addしてねと言われています。
親切ですね。
$ vim hello_world.php $ git status # On branch master # Untracked files: # (use "git add <file>..." to include in what will be committed) # # hello_world.php nothing added to commit but untracked files present (use "git add" to track)
git addしてステージ領域登録してあげます。
git add .
で全てのファイルをステージ領域にあげることができますが、
上げたくないファイルはどうすればよいでしょうか。
.gitignore
ファイルを作成して*.log
とかすればよいです。
$ git add hello_world.php
commitしましょう。
$ git commit -m "Add hello world script by php" create mode 100644 hello_world.php
git logでコミット内容を確認しましょう。
- p
オプションを付ければコミットメッセージの後ろにファイルの差分が表示されます。
--pretty=short
ではコミットメッセージの1行目のみを表示します。
--oneline
で一行のみ表示させます。
--stat
で、どこが変更されたかではなく、どのファイルが何箇所変更されたかをみることができます。
$ git log Add hello world script by php
commitできているのでGithubにあげます。
Githubに登録されていれば完了。
$ git push
変更差分の表示
git diffでワークツリー、ステージ領域、最新コミット間の差分を確認できます。
差分がないと表示されません。
README.mdという空ファイルを編集して確認してみます。
$ git diff $ ll total 0 -rw-r--r-- 1 hoge hoge 0 xx xx xx:xx README.md
# Gitチュートリアル
と編集してみるとワークツリーとステージ領域の差分が表示されました。
$ vim README.md $ git diff diff --git a/README.md b/README.md index e69de29..cb5dc9f 100644 --- a/README.md +++ b/README.md @@ -0,0 +1 @@ +# Gitチュートリアル
git addでステージ領域に追加すると差分がないので、表示されません。
最新コミットとの差分の確認はどうやるのでしょうか。
git diff HEAD
で確認できます。
あとは問題なければコミットしてみましょう。
HEADは作業しているブランチの最新コミットを参照するポインタです
git diff --cached
でもステージ領域に上がっていないけど、
コミットされていないファイルの「どこがどう次のコミットで変更されるか」がわかります。
$ git add README.md $ git diff $ git diff HEAD diff --git a/README.md b/README.md index e69de29..cb5dc9f 100644 --- a/README.md +++ b/README.md @@ -0,0 +1 @@ +# Gitチュートリアル
ちなみにgit addなどして、gitが管理したファイルはrmやmvを使うのでなく
git rm
やgit mv
でないといけませんので、ご注意を。
ブランチの操作
ブランチができると複数人で作業ができるようになる便利概念です
現在のブランチを確認すると、masterブランチにいます。
$ git branch * master
ブランチを作成して、移動しましょう。
$ git checkout -b feature-A Switched to a new branch 'feature-A' $ git branch * feature-A master
ちなみに上のコマンドは以下のコマンドを1行でやりました。
$ git branch feature-A $ git checkout feature-A
今、コミットするとfeature-Aブランチにコミットされて、ブランチを育てることになります。
以下の内容でコミットしてみます。
$ vim README.md $ cat README.md # Gitチュートリアル - feature-A $ git add README.md $ git commit -m "Add feature-A" [feature-A 4948954] Add feature-A 1 file changed, 2 insertions(+) ``` masterブランチには反映されていないことを確認 ``` $ git checkout master Switched to branch 'master' $ cat README.md # Gitチュートリアル $ git checkout - Switched to branch 'feature-A'
feature-Aブランチを統合ブランチであるmasterにマージしてみます。
masterブランチに移動してgit merge –no-ff ブランチ名
--no-off
オプションを付けるとマージコミットのメッセージを記入するためにエディタが立ち上がります。
$ git checkout - Switched to branch 'master' $ git merge --no-ff feature-A Merge made by the 'recursive' strategy. README.md | 2 ++ 1 file changed, 2 insertions(+)
git log –graphで視覚的にみると、トピックブランチ(feature-A)で
コミットされた内容がマージされていることがわかります。
$ git log --graph * commit HASH値 |\ Merge: 1a433cc 4948954 | | Author: | | Date: | | | | Merge branch 'feature-A' | | | * commit HASH値 |/ Author: | Date: | | Add feature-A |
コミット変更操作
feature-Aブランチを分岐させる前に戻ってfix-bブランチを作成させるとします。
git reset --hart 戻りたい場所のハッシュ値
$ git reset --hard 1a433ccb5a6acebe742234de5
fix-Bというブランチを切ってファイルを編集してcommitします。
$ git checkout -b fix-B Switched to a new branch 'fix-B' $ vim README.md $ cat README.md # Gitチュートリアル - fix-B $ git add . $ git commit -m "Fix B" [fix-B 01ee7fc] Fix B 1 file changed, 2 insertions(+)
feature-Aブランチをmergeした後の状態に進み、fix-Bのブランチをmergeさせます。
git relogでfeature-Aブランチをmergeしたハッシュ値を
masterブランチに戻り、git reset –hardで選択して戻ります。
$ git reflog 01ee7fc HEAD@{0}: commit: Fix B 1a433cc HEAD@{1}: checkout: moving from master to fix-B 1a433cc HEAD@{2}: reset: moving to 1a433ccb5a6acebe742234de5 0165311 HEAD@{3}: merge feature-A: Merge made by the 'recursive' strategy. $ git checkout - Switched to branch 'master' $ git reset --hard 0165311 HEAD is now at 0165311 Merge branch 'feature-A'
fix-Bの内容をマージさせるとCONFLICTが発生しました。
$ git merge --no-ff fix-B Auto-merging README.md CONFLICT (content): Merge conflict in README.md Automatic merge failed; fix conflicts and then commit the result.
ファイルを編集してCONFLICTを解消させましょう。
$ vim README.md # Gitチュートリアル <<<<<<< HEAD - feature-A ======= - fix-B >>>>>>> fix-B
今回は以下の内容に編集しました。
$ cat README.md # Gitチュートリアル - feature-A - fix-B
この状態でmergeさせることができるようになりました。
$ git add . $ git commit -m "Fix conflict" [master 30b1cb4] Fix conflict
コミットメッセージの編集もしてみましょう。
$ git commit --amend [master 38ffc4c] Merge branch 'fix-b'
視覚的にみるとわかりやすいですね。
$ git log --graph * commit ハッシュ値 |\ Merge: | | Author: | | Date: | | | | Merge branch 'fix-b' | | | * commit ハッシュ値 | | Author: | | Date: | | | | Fix B | | * | commit ハッシュ値 |\ \ Merge: | |/ Author: |/| Date: | | | | Merge branch 'feature-A' | | | * commit ハッシュ値 |/ Author: | Date: | | Add feature-A |
歴史改変
トピックブランチをマージする前に、すでにコミットした内容にちょっとしたミスを見つけたら、
修正のコミットをして、改変しましょう。
featture-Cブランチを作成して試してみます。
タイポをしたままcommitしてしまいました。
これをマージする前に修正したい。
$ git checkout -b feature-C Switched to a new branch 'feature-C' $ vim README.md $ cat README.md # Gitチュートリアル - feature-A - fix-B - feaaature-C $ git commit -am "Add feature-C" [feature-C 02f4faf] Add feature-C 1 file changed, 1 insertion(+), 1 deletion(-)
Gitの歴史を改ざんしてしまいましょう。
タイポしなかった世界線へと移動させます。
今回は現在のブランチのHEADを含めた2つまでのcommitを対象にしてエディタを立ち上げさせます。
$ git rebase -i HEAD~2 pick 02f4faf Add feature-C pick 7e0f931 Fix Typo # Rebase 95aeef1..7e0f931 onto 95aeef1 # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # x, exec = run command (the rest of the line) using shell # # These lines can be re-ordered; they are executed from top to bottom. # # If you remove a line here THAT COMMIT WILL BE LOST. # # However, if you remove everything, the rebase will be aborted. # # Note that empty commits are commented out
下のように修正しましょう。
fix-up 7e0f931 Fix Typo
git logで確認するとtypoのコミットメッセージがなくなり、
Add feature-C
のコミットが書き換わっています。
後はmasterブランチにマージします。
$ git checkout master Switched to branch 'master' $ git merge --no-ff feature-C Merge made by the 'recursive' strategy. README.md | 1 + 1 file changed, 1 insertion(+)
Gitで育てたリポジトリをGithubに登録する
Github上でgit-tutorialというリポジトリを作成します。
リポジトリのパスが表示されるので、git remote addコマンドで指定します。
$ git remote add origin git@github.com:user-name/git-tutorial.git
git pushコマンドで現在のブランチのローカルリポジトリの内容を
リモートリポジトリに送信します。
今回はmaster => master
- u
でローカルリポジトリの現在のブランチの上流はoriginリポジトリのmastertブランチであると設定したことになります。
これをつけるとリモートリポジトリの内容をgit pullするときに、
このローカルリポジトリのブランチはoriginのmasterブランチから取得することになります。
$ git push -u origin master
pushが終わったら、Githubで内容を確認してみましょう。
masterブランチ以外のブランチへ送信
リモートリポジトリにはmaster以外のブランチも作成できるのでpushしてみます。
$ git checkout -b feature-D $ git push -u origin feature-D
リモートリポジトリのGithubにfeature-Dブランチが確認できました。
リモートリポジトリから取得
別のディレクトリにローカルリポジトリを用意して
リモートリポジトリのfeature-Dを取得して変更してみましょう。
$ mkdir git-tutorial2 $ cd git-tutorial2/ $ ll $ git config -l user.name= user.email= color.ui=true $ git clone git@github.com:user-name/git-tutorial.git $ cd git-tutorial/
-a
をつけてリモートリポジトリを含むブランチ情報を確認します。
リモートリポジトリにfeature-Dがあることを確認できました。
$ git branch -a * master remotes/origin/HEAD -> origin/master remotes/origin/feature-D remotes/origin/master
feature-Dブランチをローカルリポジトリにチェックアウトしてみます。
git checkout -b 作成するブランチ名 リモートリポジトリにあるブランチ名
修正してcommitして、pushします。
$ git checkout -b feature-D origin/feature-D Branch feature-D set up to track remote branch feature-D from origin. Switched to a new branch 'feature-D' $ git diff $ vim README.md $ git diff diff --git a/README.md b/README.md index 50de722..125f990 100644 --- a/README.md +++ b/README.md @@ -3,3 +3,4 @@ - feature-A - fix-B - feature-C +- feature-D $ git commit -am "Add feature-D" [feature-D 4a5676c] Add feature-D 1 file changed, 1 insertion(+) $ git push feature-D -> feature-D
Github上のfeature-Dブランチが修正されていることを確認
最新のリモートリポジトリブランチを取得
ローカルリポジトリのfeature-Dブランチはcommitしていないので、
リモートリポジトリからgit pullでコードを取得してみましょう。
$ git pull origin feature-D $ cat README.md # Gitチュートリアル - feature-A - fix-B - feature-C - feature-D $ git branch feature-A feature-C * feature-D fix-B master
取得できました。
git push/pull を競合が起きないように気をつければ開発に便利ですね。
タグ機能
git logのコミットIDではわかりずらいとき、タグを付けると便利です。
git logの最近のコミットにタグを付けるときは、タグ名を指定すればよいです。
$ git tag v1.0 $ git tag
git show
はコミットの内容を表示しますが、IDを指定せずともタグ名で表示できます。
$ git show v1.0
他のコミットにタグを付けたいときはタグ名の後ろにコミットIDを指定すればよいです。
また-d
でタグを削除できます。
$ git tag v0.9 abb3e8e5440be9ef819aae3d3d10de3 $ git show v0.9 $ git tag -d v0.9 Deleted tag 'v0.9' (was abb3e8e)
とりあえず基本はこれぐらいで。
PyconJP 2016〜2日目〜
PyconJP 2016の2日目も行ってきました。 初のPyconJPでしたが、楽しかったです。 スタッフの皆さん、スピーカーの方々ありがとうございました!
忘れないようにメモ代わりに雑に書きます。 よかったらPyconJP 2016〜1日目〜も読んで下さい。
Keynote
眠くて間に合うか心配でしたが、ギリギリ間に合いました。 雨で電車が止まらなくてよかった。
2日目はAndrey Vlasovskikh
の基調講演でした。
Pythonの型ヒントにcommitしてる人らしいです。
ロシアから来てくださって、故郷のサンクトペテルブルクはモスクワの次に多きいところで、
日本でいえば大阪みたいなところと言って面白かったw
写真を見せてくれましたが、北ヨーロッパに属するらしく
情景が美しかったです。
話の内容としてはPython3.6の機能についてでした。 文字列リテラルと変数、数値リテラルの変更点など、 詳しくはドキュメント読みましょう。 Python3推しは無理にしないで、客観的に話すと言っていました。 あるアンケートではPython2と3の使ってつ人の比率は50%が3系で、 56%は2系を使っているらしく、一部重複しているのは2と3を使っている人がいるから。 PyconUS2020でPython2のさよならパーティがあるらしく、 これからPython書くなら3系ですね。 2017年に、Django2.0でのpython2のサポートも消えるらしいです。
Pythonの型ヒントはPython3.0から登場したが、当初はSyntaxだけで、semanticsは提供されなかった。 3.5で標準化されたて、Mypy,PyCharmで使えるようになった。 Python3の型ヒントの良くないところは静的型付けなのでコードを書く量が増えるし、小さいプロジェクトなら不要。 あとは100%の互換性があるわけではない。
型付けのケーススタディはPython2からPython3に準拠させたら6万ドルかかった企業(twisted)があった。 また、Dropboxでは型ヒントを追加してからPython3に移行した。
Async-Awaitは3.6ではyieldとawaitとasyncが使えるようになる。 Async-Awaitのいいところ。Coroutineとawaitable。 Async-Awaitのわるいところ。同期版があれば非同期版をかかないといけない。 DjangoとFlaskが使えなくなるので、Tornadoやaiohttoに移動しないといけない。 TornadoはFlaskと同じくらいpopularになってきたらしいので、 Tornadoも触っておきたいです。
質問では英語で質問する人が多かったので同時通訳の人が大変そうだった。。。 個人的には日本語で質問して、英語で話したいのなら懇親会とかセッションの合間とかに 話すのがいいんじゃないかなあとカンファレンス行くと毎回思う。
You Might Not Want Async (in Python)
台湾の方で、発表のネタがアジアっぽかった。 syncよりasyncの方がCPU待ち全然ないのすごかったです。 Python3.5の機能良さありました。
Lunch
ビュッフェ形式でした。美味しかったです。 特にだれとも話さずモクモク食べてた。
ジョブフェア
ビュッフェ形式ならジョブフェア人が少ないのではと思ったけど、 そんなことなかったです。 朝会してるとか、リモートワークの是非とかありました。 リモートワークの話題でrebuild.fmの名前が出てきたw リモートワークはワークライフスタイルではないので、 個人的には日本だとリモートワークをワークライフスタイルって考えてるから 上手くいかないんだろうなあと思います。 リモートワークは世界に展開してなかったり、 地方などにいる優秀なエンジニアを雇いたいって企業がやるものなので、 リモートワークやっている企業の人が、多様性を持ちたいから海外の人を雇うために リモートワークをしていると言っていて、 まさしくそうで、外国籍の人を雇いたいって企業がリモートワークやればいいだけの話で、 ウチは反対ですっていう会社はそもそもやる必要がないんですよね。
HTTPプロクシライブラリproxy2の設計と実装
1日目のやつが移動してきたセッションですね。
proxy2の話で、gzipとdeflateモジュールを使って実装したらしいです。 RFC2616, RFC7230も読んだそうです。 ssl.wrap_socketとかBaseHTTPserver, hyyplib,threading,select.ssl, deflate,gzipなど標準モジュールだけで作れるらしい。
Building Distributed System with Celery on Docker Swarm
台湾の方の英語セッションで Docker Swarmということを期待して参加しました。 Celeryも少し調べておきます。
from celery import celery
発表中に発表聞かないで、自分の発表資料作る人がいて、う〜んって感じだった。
おやつ
カップケーキでした。すごいかわいいし、美味しかったです。
はじめて作るDjangoプラグイン
ぎぎにゃんの発表。 ク社rails 使ってるイメージだけど、趣味でDjango使ってるのかなと思ったら、 まさしくそうらしいです。
ぎぎにゃんが作ったプラグインの紹介 django-debug-toolbar-vcs-info
ぎぎにゃんの友達が作ったプラグインの紹介 django-permission
プラグインのまとめサイトの紹介(2年近く放置されているらしいです。。。) awesome-Django
プラグインを書くときの注意点を紹介してくれました。
実装、テスト(TDDでも可)をやってから色んなCI環境を整える。 全ての環境で通ったらドキュメントを書いて公開する。 というのが流れらしいです。
2.3両方サポートするようにテストは厚くするのが大事で、 後方互換性を気にして3で書くのがオススメ。
ディレクトリ構造の紹介。 ソースを置くディレクトリがパッケージ名になる。 テストのディレクトリ。 ドキュメントのファイルとディレクトリ。 パッケージ、ディストリブューシャン用。
- キーワード
sixは2と3の互換をしてくれるもの。 compat.py run tests.py toxは複数バージョンでテストするのによい。 Django.test.utils Mock setting.pyとTravis.xyl Toz-Travis Readme.xtxtはマークダウンではなくrsdで書く。
Bottle.py ライブコーディング&リーディング
buttol.pyでのwebアプリ作成の紹介
Lightning Talks
1日目よりかは真面目内容だったな。
Closing
虫の鳴き声が聞こえてきて秋を感じる中、クロージング。
会場を貸してくださった早稲田大学ありがとうございました! トイレで喫煙をした人がいたらしい、、、 トイレで喫煙はヤバイでしょ...昭和の不良かな? スポンサーからのプレゼントコーナーはよかったですね モノタロウの工具すごかったwめっちゃデカかったので 当たっても大変だけどよかったですねw
まとめ
来年はLTのネタぐらいは作っておきたいなとおもいました。 普通に知り合いがほしいっすね。 あとは英語セッションも聞けるようになりたいので、NHK英語やっていきだ。 あとは数式も読めるように数学もやっていきだ。 Python3系の機能も覚えるぞ! 来年も参加したいイベントでした。スタッフの方々お疲れ様でした。 楽しかったです。ありがとうございました!
PyconJP 2016〜1日目〜
PyconJP2016の1日目に参加してきたので、 メモ代わりに雑に書きます。
Pycon自体は初参加で、会社のマネーでこれました(感謝)。 会場は早稲田大学だったので、近くて助かりました。 大久保駅や新大久保駅から歩いていける距離だったので、 西早稲田が近いことに気づけて知見を得ました。
Keynote
Pythonコミュニティに多大なる貢献をしているJessica McKellar
のKeynoteでした。(Last Nameはなんて読むかはわからない。)
同時通訳機が置いていない席に座ったので、英語を頑張って聞きましたが、
半分も理解できませんでした。なんとなく、コミュニティ活動について話していた気がする。。。
彼女はプログラミング教育にも力を入れているので、とても尊敬しています。
Python入門の動画を見たり、O'reillyの動画も観たことある。
Hello App
というDjango入門書にもJessica McKellar
の動画がおすすめされていたりするので、
Pythonでプログラミングをこれから学ぼうという人はきっと彼女の活動の恩恵を受けるのだろう。
あと、Closingで話に上がったCode of ConductはこのKeynote関連だったんだろうな。。
マイクロサービスを利用する側のパフォーマンス向上策
Pythonでマイクロサービスは珍しいなあと思って聞きました。 モノタロウの方だったのですが、モノタロウってヨッピーさんがインタビューしていた会社だっけかな。 マイクロサービスの話というかパフォーマンスの話で、IO負荷をどうするかという話でした。 マイクロサービス化すすめるとAPIコールが増えて、負荷が増えるようで、 varnishキャッシュやmemcachedをAPIサーバに入れて対策したけど、 IO待ちへの対策が不十分だったのでgeventを使うというお話でした。
書き方で、下のような記述をみて闇っぽいなと思いクスッとしました。
from gevent import monkey monkey.patch_all()
マイクロサービスで負荷増えるってう〜んという感じで、 スケールアウトすれば良いのではという感じもした。
Lunch
お昼はお弁当が出てよかった。しかも豪華! 特に誰とも話さずぼっち飯かましました。。。
Python入門 コードリーディング
たった一ファイルの python スクリプトから始める OSS 開発入門
も気になったのですが、
録画されてなさそうなビギナーセッションを観ました。
ファイルの場所とpdbのモジュールの読むとっかかり join,splitの実装を確認して、 どこにファイルがあるのかを確認し、ドキュメントと照らし合わせて読んで見るという使い方を教えてくれました。
ファイルの場所とpdbの使い方
[root@shuhei pywork]# python Python 3.5.2 (default, Jul 18 2016, 05:05:01) [GCC 4.4.7 20120313 (Red Hat 4.4.7-17)] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import oa.path Traceback (most recent call last): File "<stdin>", line 1, in <module> ImportError: No module named 'oa' >>> import os.path >>> os.path <module 'posixpath' from '/root/.pyenv/versions/3.5.2/lib/python3.5/posixpath.py'> >>> os.path.dirname(".") '' >>> os.path.dirname("D://") 'D:' >>> os.path.join("spam", "egg") 'spam/egg' >>> print(os.path.join("spam", "egg")) spam/egg >>> os.path <module 'posixpath' from '/root/.pyenv/versions/3.5.2/lib/python3.5/posixpath.py'> >>> os.path <module 'posixpath' from '/root/.pyenv/versions/3.5.2/lib/python3.5/posixpath.py'> >>> os.path.__file__ '/root/.pyenv/versions/3.5.2/lib/python3.5/posixpath.py'
モジュールの読むとっかかり join,splitの実装を確認 どこにファイルがあるのか、確認し、ドキュメントと照らし合わせて読んで見る。
>>> import this The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it. Although that way may not be obvious at first unless you're Dutch. Now is better than never. Although never is often better than *right* now. If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea -- let's do more of those! >>> this.__file__ '/root/.pyenv/versions/3.5.2/lib/python3.5/this.py'
ROT13のwiki 暗号化をかけると文章がでてくる
pdbというデバッガを使って一行ずつ確認してみる
import pdb; pdb.set_trace()
d = {} import pdb; pdb.set_trace() for c in (65, 97): for i in range(26): d[chr(i+c)] = chr((i+13) % 26 + c) print("".join([d.get(c, c) for c in s]))
d = {} for c in (65, 97): for i in range(26): d[chr(i+c)] = chr((i+13) % 26 + c) if chr(i+c) == 'E': import pdb; pdb.set_trace() print("".join([d.get(c, c) for c in s]))
- コマンド
l 複数行 s ステップ実行 c 続ける b
- antigravityモジュール
>>> import antigravity >>> antigravity.__file__ '/root/.pyenv/versions/3.5.2/lib/python3.5/antigravity.py'
- webブラウザモジュール
>>> import webbrowser >>> webbrowser.__file)) File "<stdin>", line 1 webbrowser.__file)) ^ SyntaxError: invalid syntax >>> webbrowser.__file__ '/root/.pyenv/versions/3.5.2/lib/python3.5/webbrowser.py'
- os
>>> import os >>> os.__file__ '/root/.pyenv/versions/3.5.2/lib/python3.5/os.py'
built-inならpythonに組み込まれているからcの実装 cpython,github python自身のソースをみないとだめ。
>>> import ita Traceback (most recent call last): File "<stdin>", line 1, in <module> ImportError: No module named 'ita' >>> import itaotools Traceback (most recent call last): File "<stdin>", line 1, in <module> ImportError: No module named 'itaotools' >>> import itertools >>> itertools.__file__ Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: module 'itertools' has no attribute '__file__' >>> itertools <module 'itertools' (built-in)>
数学的基礎から学ぶDeep Lerning
途中から数式が完全に理解できなくてすやぁっとなった。。。
NumpyとScipyで機械学習をやるとのことだったのですが、難しい。。。
微妙に行列っぽくなったと思ったら、いきなりシンプルな線形性のある数式になったふぁっ!?ってなった。
偏微分方程式は解いたこと無いのでわからず。。。
ただ、このセッションでやっていたことが先行発売されていた
オライリー社から出版されるゼロから作るDeep Learning
で近いので、
この本を読むと良さそうだった。その前に数学だと思うけど。
Python入門 ライブコーディング
ここのコードは不備があるので読み飛ばして下さい。後で修正するつもり。
基礎から学ぶWebアプリケーションフレームワークの作り方
は録画にまかせて
ビギナーセッションに参加してきました。
Web API の呼び出しといったコードを書いてくれました。
テストツール flake8
インタラクティブシェル ipython
なにが良いかというとtab補完
ipyhonを使わないならreadline
を使うと良いが、ipythonを使った方が楽。
>>> import readline, rlcompleter >>> readline.parse_and_bind('tag: complete') >>> import sys sys >>> import sys
デバッグツール pdb ipdb 処理止められて変数を確認できる
c continu n nextで一行図ス
pip install request
import requests import sys # print(sys.argv) # sys.exit(0) url = slackのapiのurl r = requests.get( 'https://api.github.com/user') # urlのパラメータと分離左折 token = channel = # text = # text = 'こんにちは' if len(sys.argv) < 1: # 例外処理 print('引数を指定してください') sys.exet(0) text = sys.argv[1] pretty = 0 params = { 'token': token, 'channel': channel, 'type': 'pretty': 'as_user': True, } r = requests.get(url, params=params) # print(r.text) data = r.json() # import ipdb; ipdb.set_trace() # print(data) import pprint pprint.pprint(data)
pp data type(data) pp data['channnel']
git cloneしてlocalにライブラリドキュメントもってきて調べるとよい。
import requests import xml.etree.ElementTree as ET tree = ET.parse('country_data.xml') root = tree.getroot() url = '' app_id = params = { 'appid': appi, 'category': id, } r = rewuests.get*url, params-params) # print(r.text) root = ET.fromstring(r.text) pritn(root) for resut in root: for item in enumerate(resut, 0);: if i == 0: continu import ipdb; ipdb.set_trace() print(item)
for i in root:oprint:i) for j in root:result pp item for i in item: print(i) item.find('{urn:yahoo:jp:auc"}')
python入門ビギナー向け勉強会で続きをやってくれるとのことでした。
How Python helped create the visual effects for an Emmy nominated TV show
英語セッションでよくわからなかった。。。 英語やらなあかんね。。。
LT
- カラオケ採点
- 師匠探し
- 仮想通貨
- 振り返り
- 虹工房
すべて良いLTでした。 虹工房はLTはもったいない内容。
Closing
Code of Conduct守ろうな話。
Party
TwitterでFollowしているけど、会ったことがない人達(ハムカズ先生とくーむさん)に会ってみようと目標を立てて参加。
すてにゃんさんはやぱちーで会ったことがあったけど、 顔とTwitter ID絶対に一致されてないだろうなと思ったので、長く話せてよかった。 アイドルなだけあり、みんながすてにゃんさんに話しかけていて、自分はそのついでに話をさせていただいたりした。 すてにゃんというハブで他の参加者が繋がるというのは良さあった。
hamukazu先生とも話せてよかった。まともな言動をする立派な大人だった。仕事も忙しそうだ。 コミュニティでの活動をしているからか、知り合いが多そうで、色んな人が声をかけていた。
くーむさんはすてにゃんさんが紹介というか話すついでに話せた。 Twitterのアイコンを認識されていたのだろうかはわかんないけど、 これを機に覚えていて貰えれば幸いです。
あとはツイッターIDを交換したり、しなかったりですが、 繋がりを大事にしていきたいと思いました。
来年も参加したい。というか2日目寝坊しないようにしたい。
Docker入門
Dockerとは何か。
軽量な仮想環境を実現するためのツール。 OSやアプリの設定したものをイメージ化して保存できる。 Docker環境の別のマシンにも移すことができる。
なにをする。
DockerがインストールされたOSを用意する。
OSやアプリが入った実行imageを実行するdocker run
今回は実行imageはDocker Indexから取ってくるdocker pull
実行したらContainerというものができる。
Containerで設定やアプリ、インストールしたりして設定する。
そこから新しくimageを作る場合はdocker commit
作成したimageを他のマシンで動かしたい場合は
docker push
でimageをDocker Indexに持って行き、
移したい先のマシンでdocker pull
, docker run
をすればよい。
imageを持ってきたらContainerができる。
OSインストール
Vagrantbox.esから Official Ubuntu 14.04 daily Cloud Image amd64 (Development release, No Guest Additions)のイメージを使用します。
使い方
To use the available boxes just replace {title} and {url} with the information in the table below.
$ vagrant box add {title} {url} $ vagrant init {title} $ vagrant up
なので
$ vagrant box add trusty64 https://cloud-images.ubuntu.com/vagrant/trusty/current/trusty-server-cloudimg-amd64-vagrant-disk1.box $ mkdir Docker $ cd Docker/ $ vagrant init trusty64 $ vi Vagrantfile
config.vm.network “private_network”, ip: “192.168.33.10”
↓
config.vm.network “private_network”, ip: “192.168.55.44”
$ vagrant up $ vagrant ssh
Docker1.12.1がインストールされました。
$ sudo docker --version Docker version 1.12.1, build 23cf638
また、CentOS7にインストールするならyumで良いと思います。
yum -y install docker systemctl start docker systemctl enable docker
Dockerの操作
Dockerでcentosのimageをsearch
でDocker Indexから探してみます。
imageが見つかったらdocker pull
で引っ張ってきます。
docker images
でimageをもってこれたことを確認しました。
imageを消すにはdocker rmi
で削除できます。
$ sudo docker search centos |more NAME DESCRIPTION STARS OFFICIAL AUTOMATED centos The official build of CentOS. 2613 [OK] jdeathe/centos-ssh CentOS-6 6.8 x86_64 / CentOS-7 7.2.1511 x8... 29 [OK] jdeathe/centos-ssh-apache-php CentOS-6 6.8 x86_64 / Apache / PHP / PHP M... 19 [OK] nimmis/java-centos This is docker images of CentOS 7 with dif... 15 [OK] million12/centos-supervisor Base CentOS-7 with supervisord launcher, h... 12 [OK] torusware/speedus-centos Always updated official CentOS docker imag... 8 [OK] [以下略] $ sudo docker pull centos $ sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE centos latest 980e0e4c79ec 7 hours ago 196.7 MB hello-world latest c54a2cc56cbb 9 weeks ago 1.848 kB $ sudo docker inspect [IMAGE-ID] $ sudo docker images $ sudo docker rmi [IMAGE ID] $ sudo docker images
centosというimageを実行してContainerを作りコマンドを実行します。
$ sudo docker run centos echo "Hello World" Hello World
Containerが作られたかを確認するためにdocker ps
を実行しても確認できません。
動作が完了してしまっているので表示されませんでした。
既に完了しているContainerを確認するためにはps -a
とします。
$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES $ sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 7b88f37bfa42 centos "echo 'Hello World'" About a minute ago Exited (0) About a minute ago compassionate_bassi 5fb7e2f68a58 hello-world "/hello" About an hour ago Exited (0) About an hour ago amazing_kowalevski
最新5つのContainerを表示させるにはps -a -n=5
です。
削除するにはrm CONTAINER ID
で削除できます。
vagrant@vagrant-ubuntu-trusty-64:~$ sudo docker ps -a -n=5 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 7b88f37bfa42 centos "echo 'Hello World'" 5 minutes ago Exited (0) 5 minutes ago compassionate_bassi 5fb7e2f68a58 hello-world "/hello" About an hour ago Exited (0) About an hour ago amazing_kowalevski vagrant@vagrant-ubuntu-trusty-64:~$ sudo docker rm 7b 7b vagrant@vagrant-ubuntu-trusty-64:~$ sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5fb7e2f68a58 hello-world "/hello" About an hour ago Exited (0) About an hour ago amazing_kowalevski
今度は実行中のContainerを確認してみます。
バックグラウンドで動かすにはrun -d
CONTAINER IDが出力されるので、
logs CONTAINER ID
で実行中のタスクログを確認できる。
vagrant@vagrant-ubuntu-trusty-64:~$ sudo docker run -d centos free -s 3 9396f8bf834796370f781293f9effd11f4af71e45a58025dbad6f8ba133cac20 vagrant@vagrant-ubuntu-trusty-64:~$ sudo docker logs 939 total used free shared buff/cache available Mem: 501712 120312 137480 736 243920 359839 Swap: 0 0 0 total used free shared buff/cache available Mem: 501712 119892 137796 736 244024 360327 (以下略)
フォアグラウンドに持って行く時はattach
を使います。
止めるにはCtrl + C
$ sudo docker attach --sig-proxy=false 939
実行中のタスクをストップするにはkill
かstop
再開させるにはstart
vagrant@vagrant-ubuntu-trusty-64:~$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 9396f8bf8347 centos "free -s 3" 2 minutes ago Up 2 minutes modest_brattain vagrant@vagrant-ubuntu-trusty-64:~$ sudo docker stop 939 939 vagrant@vagrant-ubuntu-trusty-64:~$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES vagrant@vagrant-ubuntu-trusty-64:~$ sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 9396f8bf8347 centos "free -s 3" 2 minutes ago Exited (137) 12 seconds ago modest_brattain 5fb7e2f68a58 hello-world "/hello" 2 hours ago Exited (0) 2 hours ago amazing_kowalevski vagrant@vagrant-ubuntu-trusty-64:~$ sudo docker start 939 939 vagrant@vagrant-ubuntu-trusty-64:~$ sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 9396f8bf8347 centos "free -s 3" 3 minutes ago Up 2 seconds modest_brattain 5fb7e2f68a58 hello-world "/hello" 2 hours ago Exited (0) 2 hours ago amazing_kowalevski
Containerに変更して、imageを作成する
まずは-i
でインタラクティブモードにし、
-t
でターミナルを立ち上げ、
imageを指定、
bashを指定してシェルを立ち上げContainerに入ります。
Containerに入れたので/home
配下に移動してtest.txt
を作成してみます。
$ sudo docker run -i -t centos /bin/bash # ll total 68 -rw-r--r-- 1 root root 18307 Sep 6 14:02 anaconda-post.log lrwxrwxrwx 1 root root 7 Sep 6 13:59 bin -> usr/bin drwxr-xr-x 5 root root 380 Sep 7 20:23 dev drwxr-xr-x 48 root root 4096 Sep 7 20:23 etc drwxr-xr-x 2 root root 4096 Aug 12 2015 home lrwxrwxrwx 1 root root 7 Sep 6 13:59 lib -> usr/lib lrwxrwxrwx 1 root root 9 Sep 6 13:59 lib64 -> usr/lib64 drwx------ 2 root root 4096 Sep 6 13:59 lost+found drwxr-xr-x 2 root root 4096 Aug 12 2015 media drwxr-xr-x 2 root root 4096 Aug 12 2015 mnt drwxr-xr-x 2 root root 4096 Aug 12 2015 opt dr-xr-xr-x 111 root root 0 Sep 7 20:23 proc dr-xr-x--- 2 root root 4096 Sep 6 14:02 root drwxr-xr-x 10 root root 4096 Sep 6 14:02 run lrwxrwxrwx 1 root root 8 Sep 6 13:59 sbin -> usr/sbin drwxr-xr-x 2 root root 4096 Aug 12 2015 srv dr-xr-xr-x 13 root root 0 Sep 7 20:23 sys drwxrwxrwt 7 root root 4096 Sep 6 14:02 tmp drwxr-xr-x 13 root root 4096 Sep 6 13:59 usr drwxr-xr-x 18 root root 4096 Sep 6 14:02 var # cd home/ # ll total 0 # touch test.txt # ll total 0 -rw-r--r-- 1 root root 0 Sep 7 20:23 test.txt
Containerから抜けたらps -a
でContainerを確認します。
先ほどできたContainerがあるので、IDを指定してimageを作ります。
docker commit
で作成できます。「username/任意の名前」でimageの名前をつけます。
今回では「hoge/test」としました。
sudo docker images
でimageが作成されたことを確認します。
hoge/test
が作成されています。これを元にContainerを作成します。
sudo docker run -i -t hoge/test /bin/bash
でContainerに入り、
test.txt
があることを確認。
これでContainerからimageを作成することができました。
# exit ~$ sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 35695d6c9cef centos "/bin/bash" About a minute ago Exited (0) 26 seconds ago kickass_euclid 9396f8bf8347 centos "free -s 3" 15 hours ago Up 15 hours modest_brattain 5fb7e2f68a58 hello-world "/hello" 17 hours ago Exited (0) 17 hours ago amazing_kowalevski ~$ sudo docker commit 356 hoge/test sha256:c44f82ed12cc43c6b9a24256b0a99f62e69e9ac75ead52e9035f58214904511e ~$ sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE hoge/test latest c44f82ed12cc 8 seconds ago 196.7 MB centos latest 980e0e4c79ec 23 hours ago 196.7 MB hello-world latest c54a2cc56cbb 9 weeks ago 1.848 kB ~$ sudo docker run -i -t hoge/test /bin/bash # cd home/ # ll total 0 -rw-r--r-- 1 root root 0 Sep 7 20:23 test.txt
- Dockerコマンドのライフサイクルに関わる動作
サブコマンド | 意味 | 実行後の状態 |
---|---|---|
run | デプロイ・起動 | 起動が成功したら稼働中/失敗したら停止中 |
stop | 稼働中のDockerコンテナを停止 | 停止が成功したら停止中 |
start | 停止中のDockerコンテナを起動 | 起動が成功したら稼働中 |
rm | デプロイしたDockerコンテナを削除 | 存在しなくなる(startできなくなる) |
- Dockerコンテナの操作
サブコマンド | 意味 |
---|---|
exec | 稼働中のコンテナでコマンドを実行 |
logs | コンテナのログ(標準出力、標準エラー出力)をする |
inspect | コンテナ/イメージの詳細情報を表示 |
- Dockerイメージ操作のコマンド
サブコマンド | 意味 |
---|---|
images | DockeデーモンにあるDockerイメージ一覧を表示する |
rmi | DockerデーモンにあるDockerイメージを削除する |
Dockerfile
docker build
imageから新しいimage作成の自動化
自動化のスクリプトがDockerfile
Dockerfileを作成
vagrant@vagrant-ubuntu-trusty-64:~$ vi Dockerfile
FROM
で何のイメージを元にするか指定します。
MAINTAINER
で誰が書いたか記述します。
名前とメールアドレスを書いておきます。
コメントは#
です。
今回コマンド2つ指定します。
RUN
はbuildされるときに実行されるもの。
色んな物をインストールしたりすることができます。
今回はインストールではなく、now building...
とだけ表示させます。
CMD
はbuildされたimageを元に、runするときに実行されるもの。
(imageからContainerを作るときのこと)
書き方は実行したいものを,
で区切り、[]
で囲みます。
FROM centos MAINTAINER FirstName LastName <email address> # RUN: build時に実行 RUN echo "new building..." # CMD: run時に実行 # CMD: echo "now runnning..." CMD ["echo", "new running..."]
build
をしてみます。
sudo docker build
に新しいimageの名前をつけます。
-t hoge/test2
とします。
カレントディレクトリにあるDockerfileを使うので.
をつけます。
実行するとnow building...
と出力されているのが確認できました。
vagrant@vagrant-ubuntu-trusty-64:~$ sudo docker build -t hoge/test2 . Sending build context to Docker daemon 13.31 kB Step 1 : FROM centos ---> 980e0e4c79ec Step 2 : MAINTAINER Gen dockerid <mailaddress> ---> Running in f506910e9ee7 ---> b1af5b08522a Removing intermediate container f506910e9ee7 Step 3 : RUN echo "new building..." ---> Running in b9c7c9ec39a1 new building... ---> feb31b681b6d Removing intermediate container b9c7c9ec39a1 Step 4 : CMD echo new running... ---> Running in 858b8d74a51f ---> a646d9c9c705 Removing intermediate container 858b8d74a51f Successfully built a646d9c9c705
sudo docker images
を実行して、hoge/test2
があることを確認できました。
実行するとnew running...
と出力されることが確認できます。
vagrant@vagrant-ubuntu-trusty-64:~$ sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE hoge/test2 latest a646d9c9c705 12 seconds ago 196.7 MB hoge/test latest c44f82ed12cc About an hour ago 196.7 MB centos latest 980e0e4c79ec 24 hours ago 196.7 MB hello-world latest c54a2cc56cbb 9 weeks ago 1.848 kB vagrant@vagrant-ubuntu-trusty-64:~$ sudo docker run hoge/test2 new running...
次はインストールを試してみます。
ApacheインストールするVagrantfileを書きます
build時にRUNでインストールさせます。
imagesの中にファイルを取り込むにはADD
を使います。
index.htmlを/var/www/html/
にコピーします。
EXPOSE
で80番ポートを開けます。
run
の時に実行するコマンドを
CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]
とします。
※ index.htmlはHello World!
という内容で作りました。
FROM centos MAINTAINER Gen docker id <mailaddress> RUN yum -y install httpd ADD ./index.html /var/www/html/ EXPOSE 80 CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"] # CMD ["/usr/sbin/httpd", "-DFOREGROUND"] でもOK
build
でインストールします。
$ sudo docker build -t hoge/httpd .
ホスト側の8080番ポートをContainer側の80番ポートにリダイレクトさせ、
バックグラウンドで走らせます。
run
を実行するとContainerのhttpdが立ち上がります。
$ sudo docker run -p 8080:80 -d hoge/httpd e23a0bb40467f42650d9dc33dbd77f1927efe7b828d1bb2ba2f18d957a04cf44
Containerのhttpdが立ち上がっているのを確認。
$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e23a0bb40467 hoge/httpd "/usr/sbin/httpd -D F" 14 seconds ago Up 13 seconds 0.0.0.0:8080->80/tcp nauseous_einstein
http://192.168.55.44:8080/
にWEBブラウザでアクセスすると
Hello World!
が表示されました!
docker hubにコンソールからログインします。 Docker Hubにimageをpushします。
~$ sudo docker login Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one. Username: hoge Password: ▽ Login Succeeded ~$ sudo docker push hoge/httpd
ブラウザで、Docker HUBにログインして
Repositoryのところに、hoge/httpd
があることを確認
オフィス訪問シリーズ ep1.Wantedly
Wantedlyさんに確認して書いて大丈夫内容となっております。
企業に遊びに行く文化を作ったであろうWantedlyさんに遊ぶに行ってきた。
イケイケなイメージのWantedlyさんへオフィス訪問してきましたので共有します。 オフィス訪問シリーズとあるけど、次回もあるといいな。 (遊びに来てと誘っていただければ行きますのでよろしくお願いします!)
Wantedlyは自分も使ったことのあるサービスだったので、行けて良かったです!
わたしとWantedly
オフィス訪問の前に、
まずはWantedlyの思い出について話させてほしい。
Wantedlyのサービスを実際に使い転職したのですが、
サービスの機能で話を聞きに行きたい
という機能のおかげで転職に踏み出せました。
転職したいなあと漠然と思っている時に、自分にはまだスキルが足りない、
転職活動はスキルがもっとついてからやろうとかそんな事を思っていたのですが、
Wantedlyのサイトで企業の採用募集のページを見ていた時に、
気になるリストに追加
をしようとしたら、間違えて話を聞きに行きたい
をクリックしてしまったのです。
やっちゃったなあと思ったけど、どうせ企業からのレスポンスなんてないだろうと思って、
一時間もたたないうちに、一度オフィスに遊ぶに来てみてくださいというメッセージが届いてしまいました。
いずれは行きたかった会社だったので、ここで無視をしたり、断ったりするのは印象に良くないだろうと思い
休日にオフィス訪問をしたのでした。
その後、深夜作業の待機時にできる履歴書を使って履歴書を書いたのが懐かしいです。
履歴書を買わなくてすむので便利ですよ。
自分のように転職活動はまだいいかなと思っている人でも、 とりあえず話を聞きに行くことって大事だと思います。 そこのハードルを下げる仕組みと、オフィス訪問をしやすい空気をつくったのが Wantedlyのサービスなんだと思っています。
きっかけ
Wantedlyのエンジニアであるkoudaiiiさんから、 何故かオフィスに遊びに来ないかと誘っていただいたので、 自分の中で勝手にロールモデルにさせてもらっている方からの誘いですから、 即、頭を縦に振りました。 (日程を複数提示していただけると行くしかないので知見。)
ちょうど誘っていただく前日ぐらいにkoudaiiiさんのブログ読んで、 SlerからWEBのインフラエンジニアへ転職してみて、 どんなことをして超絶成長することに成功できたのか聞きたかったので願ってもないチャンスでした。 (ここちゃんと聞けなかったなあ。あと行政新聞紙についてもききたかった。)
SIer のカスタマーサポートから Web 業界のインフラエンジニアに移って1年経った https://t.co/FXMiXCPkd4 SlerからWEBのインフラエンジニアへてんしょくという同じ境遇でどうしてここまで差が開いてしまうのか。技術ブログ書くだけじゃなくて芝も青くする
— トトス (@oza_shu) 2016年8月24日
とはいえ、オフィスに遊び行くってどんなことを話すのか・話せばいいのか 事前に話すことを考えておかないと基本会話苦手なので困りましたが、 最近Wantedlyに遊びに行ったblogを読んだのを思い出し、参考にさせて頂きました。 こちらのblog「「会社に遊びに行く」と具体的に何をして遊んでもらえるのか知りたかったので会社に遊びに行ってきた」を参考にさせて頂きました。
オフィス
夜勤明けで寝坊したら死というプレッシャーの中、約束の時間10分前という理想的な時間につけました。 目黒駅から徒歩10分ぐらいの閑静な所(最寄り駅は白金台)にオフィスがありました。 ビルのワンフロアを借りているらしく、一年前にオフィスを移転してきたと伺いましたが、 かなり広いオフィスで、とても起業から6年とは思えないほど、オシャレなオフィスでした。 学生の時に、chibicodeさんのリツイートでWantedlyのβ版を見たことがありますが、 あれからここまで成長したのかと、成長速度に驚き。 オサレオフィスの写真を完全に撮り忘れたので、各自ホームページとかで見てほしい。
オフィスにはいわゆる受付みたいなところが見当たらず、特に誰もいないのでさっそく詰んだと思ったのですが、 入り口入った直ぐにiPadが置いてあり、そこから担当者を呼び出すシステムとなっておりました。 iPadで担当者の名前をタッチすると、本人を呼び出すみたいです。 ここでもkoudaiiiさんを一覧から見つけられず(本名がぱっとでてこなかった)心が折れかかりましたが、 一番上に担当者呼び出しがあることに気づき、まもなく採用担当の方に案内して頂けました。 (全体的なオフィス案内は特になく、クレイジーダイヤモンドという会議室に直行でした。)
はなしたこと1
「「「会社に遊びに行く」と具体的に何をして遊んでもらえるのか知りたかったので会社に遊びに行ってきた」」を読んで、
会社に遊ぶに来てもらうのは会社とサービスのミッションとゴール
を宣伝というか、伝えたいからなんだろうなと思ったので、
Wantedlyのサービス内容とかどんな目標を持って仕事をしているのか調べておきました。
採用担当の方とお話をすることになったので、 さっそく自分が実際にWantedlyのサービスを使ったことがあることや、 会社の遊びにいく機能はいいと思う旨を話しました。 また、採用担当の方からは他のサービス紹介をしていただけました。
- blogサービス
Wantedlyのblog機能では 実際に起業の方にblogを書いてもらい「働くこと」についてpostしてもらっているらしいです。 就活生とかには役に立ちそうな内容ですね。また企業の採用面でも自社の雰囲気を伝えられるので良さそうでした。
- チャットサービス
syncというビジネス用グループチャットサービスだそうです。 招待さえすればグループに承認されプロジェクト毎にやりとりができるそうです。 Facebook MessengerやSlackとかとどう差別化するのかなあと思ったんですが、 koudaiiiさんも仕事で使っているのを見ましたが、Slackとどう使い分けているんだろうか。 部屋が乱立しないから集中しやすいのかな。 営業の人とかはSlackよりsyncの方が好みそうなイメージ。
あと印象に残っているのが、採用担当の方が「インフラエンジニアで障害対応をしているってことは コードを書いてるんですよね。」って聞いてきて、 プログラミングができないインフラエンジニアは死という圧を軽くジャブしてきて流石だなあと思いました。
はなしたこと2
遅れてkoudaiiiさんがいらっしゃり、色々と業務でやっていることを説明していただきました。 現在インフラエンジニアが2人だけらしいです。 業務ではほとんどコードしか書いていないとおっしゃっていたのが印象的で、 自動化を推し進めて、一人が何百台のサーバを管理する働き方をしていることがわかりました。 個人的にはインフラエンジニアではなくソフトウェアエンジニアと名乗った方がいいのかなと思います。 インフラエンジニアだと採用が難しそうですが、 ソフトウェアエンジニアでインフラやりたい人Wantedの方が集まりそうだなと思いました。
また、お客さんは社内のエンジニアと言っていて、社内でツールや基盤開発を推し進めているそうです。 実際にいくつかCLIツールを見せてもらいました。 S3のバケット操作をAWSコンソールではなく CLIで操作するs3urlのデモを見せてくれました。 作業を楽にするツールをGithubで公開しているの良いですね!
他にもどんな方向性に向かうか、他の企業の資料を集めてまとめたものや、 他の企業に話を聞いてどんな方向性に進むかを自分たちで決めて進めていくのは よい文化だと思いました。AmazonやNetflixのマイクロサービスの事例なども教えて頂けました。
また、公開しない技術を持つことも大事と仰っていて、企業としての競争優位性を保つ考えを持っていたり、 自社サービスの運用しているエンジニアの思考なのかなと思ったりもしました。
一つ馬鹿な質問をしたな〜と家に帰って反省したのが、 「OS, ミドル, NW, プログラミング,etcで、どんなスキルが一番求められますか?」と聞いて、 無論、プログラミングが一番求められると答えられましたが、 ミドルの知識とかチューニング周りよりプログラミングなのか...と思いましたが、 マイクロサービスをやっているから、スケールアップさせるより、 スケールアウトさせるから、どう考えてもプログラミングスキルの方が大事ですよね。 マイクロサービスなにもわかっていませんね。はい。 あとプログラミングできる人はミドルの設定周りもすぐわかると言っていて 「たしかに。」ですね。 SlerからWEBのインフラエンジニアへ転職してみて、どんあギャップがあったか。 そのギャップを埋めるためにしたこととか聞きたかったのに眠気で忘れてた。 体調万全の状態でお話伺いたかった。。。 (どんなことをして超絶成長することに成功できたのか聞きたかったけどやるしか無いんだろうなあ。あと行政新聞紙についてもききたかった。)
会社の雰囲気
平均年齢は30すこしぐらいらしいですが、みんな仲がよさそうで、 コミュニケーションをちゃんとと取られているようでした。 お昼も10人ぐらいでみんなで食べに行ったりしているそうです。 他にも、各チームごとに成果発表会や、勉強会、シャッフルランチなどを定期的に行い、 他のチームの人ともコミュニケーションが取れる仕組みが作られていて、 考えられていました。他の人と話したことがない、どんな人かよくわからないっていう事が 起こりにくそう。(人間関係で悩まされるの無駄でしか無いですからね...) どんな人が多いか聞いたところ、すごく真面目ですごく優秀な人が多いとのことでした。 会社の急成長も良い人材が集まっているからできるのでしょう。 会議とかも多いイメージでしたが、自社サービスのエンジニアの一つの特徴なのでしょうか。
最後に
中途でも面接前に一日インターンというのをやっているらしく、 実際に働いてみてどうかを確認するらしいです。 勉強会に参加する気分で一日インターンに申し込んでみても良いかもしれません。 優秀な人と働くことって刺激にも勉強にもなりそう。 (ここまで考えて、英語の勉強のために外資の採用面接を受けるって書いて避難をうけていたblogを思い出した。 冷やかしは迷惑ですね。自重しましょう。) GoのCLIツール作成やRailsの知識を持っているエンジニアがほしいそうです。 あたしじゃんと思った人はまずはWantedlyに遊びに行ってみてはいかがでしょうか。
Wantedlyさんありがとうございました。
severspec入門
Serverspec
Apache,PHP,MySQL,Nagiosをインストールして インストールされているかをテストしていきます。
ServerspecはRubyが必要なのでインストールをします。 こちらを参考にインストールしてみてください。
Rubyをインストールしたら、 Ruby用のgemというソフトウェアリポジトリからServerspecをインストールします。
# yum install rubygems
# gem install serverspec
インストール完了したら Serverspec用にディレクトリを作成し、テストをしてみます。
# mkdir ~/servertest # cd servertest/ # serverspec-init Select OS type: 1) UN*X 2) Windows Select number: 1 Select a backend type: 1) SSH 2) Exec (local) Select number: 1 Vagrant instance y/n: n Input target host name: web + spec/ + spec/web/ + spec/web/sample_spec.rb + spec/spec_helper.rb + Rakefile + .rspec
rake spec実行時にエラーが出たのでまとめる
- "set :request_pty, true"を書いてくれ
spec_helper.rb
に追記して事なきを得ました。
Please write "set :request_pty, true" in your spec_helper.rb or other appropriate file.
- HighLine か Termiosをインストールしてくれ
gem install highline
で事なきを得ました。
Text will be echoed in the clear. Please install the HighLine or Termios libraries to suppress echoed text.
- passwordかlocalhostを記入してくれ
Wrong sudo password! Please confirm your password on localhost.
これはこちらを参考にしました。CentOS 6.5でserverspecサーバ構築 その2 こちらも参考【入門】serverspecでSSH経由でリモートホストにspec流す sudoパスワードを聞かれるようにしないといけないようですね。 rake specのコマンドを少し変えれば良いらしい。
$ SUDO_PASSWORD=xxxxxxxx rake spec
もしくは
$ ASK_SUDO_PASSWORD=1 rake spec
これでOK。
これらのエラーメッセージは環境によっては聞かれなかったので rubyのバージョンとかが原因なのかなあ。
サンプルのテストファイルを削除なり、 名前変更するなりしておきましょう。 書き方の参考に読んでおくのもよいです。
# mv sample_spec.rb{,.bak}
Apacheインストール
serverspecでApacheインストールのテストを書きます。
$ vi httpd_spec.rb require 'spec_helper' describe package('httpd') do it { should be_installed } end
テストが通るようにApacheをyumでインストールして、 サービスを起動させます。
# yum install httpd # service httpd status httpd は停止しています # service httpd start httpd を起動中: httpd: apr_sockaddr_info_get() failed for shuhei httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName [ OK ] # chkconfig --list |grep htt httpd 0:off 1:off 2:off 3:off 4:off 5:off 6:off # chkconfig httpd on # chkconfig --list |grep htt httpd 0:off 1:off 2:on 3:on 4:on 5:on 6:off
PHPインストール
php、php-devel、php-mbstring、php-gd
が入っているテストを書きます。
require 'spec_helper' %w(php php-devel php-mbstring php-gd).each do |pkg| describe package(pkg) do it { should be_installed } end end
yumでインストールします。
# yum install php php-devel php-mbstring php-gd
MySQL5.6インストール
MySQLのインストールには2通りあります。
yumとrpmでインストールの2種類あり、 MySQL5.6まではインストール方法でパッケージやサービス名に 差異があるとのこと。 5.7からは差異はないらしい
yumコマンドでのインストールは簡単なのでおすすめですが、
インストールされるパスが固定されるので、
1台のサーバに複数のMySQLをインストールすることができないです。
また、yum upgrade
時にMySQLサーバがマイナーバージョンアップされることがあるらしく、
インストール後に無効化する必要があります。
メジャーバージョンアップはされないように、メジャーバージョンアップごとに
違うリポジトリ名が割り当てられています。
(今回は1台のサーバにMySQLサーバ2台たてて、レプリケーションを行いたいので、 rpmパッケージでインストールしていきます。)
- rpmパッケージを使用したインストール
MySQLはサイトからダウンロードします。
/usr/local/src
配下にRed Hat Enterprise Linux 6 / Oracle Linux 6 (x86, 64-bit), RPM Bundle
をインストールします。
# cd /usr/local/src/ # wget http://dev.mysql.com/get/Downloads/MySQL-5.6/MySQL-5.6.32-1.el6.x86_64.rpm-bundle.tar # tar xvf MySQL-5.6.32-1.el6.x86_64.rpm-bundle.tar MySQL-shared-5.6.32-1.el6.x86_64.rpm MySQL-test-5.6.32-1.el6.x86_64.rpm MySQL-server-5.6.32-1.el6.x86_64.rpm MySQL-shared-compat-5.6.32-1.el6.x86_64.rpm MySQL-client-5.6.32-1.el6.x86_64.rpm MySQL-embedded-5.6.32-1.el6.x86_64.rpm MySQL-devel-5.6.32-1.el6.x86_64.rpm
パッケージを-i
でインストールします。
# rpm -i MySQL-*.rpm 警告: MySQL-client-5.6.32-1.el6.x86_64.rpm: ヘッダ V3 DSA/SHA1 Signature, key ID 5072e1f5: NOKEY エラー: 依存性の欠如: MySQL-devel は mysql-devel-5.1.73-7.el6.x86_64 と競合します。
MySQL-devel は mysql-devel-5.1.73-7.el6.x86_64 と競合します。
なんてエラーがでました。mysql-devel-5.1.73-7.el6.x86_64
なんて入れた覚えはない。
-e
でアンインストールしてみるが、インストールされていないとのこと。。。
# rpm -e mysql-devel-5.1.73-7.el6.x86_64.rpm エラー: パッケージ mysql-devel-5.1.73-7.el6.x86_64.rpm はインストールされていません。
# yum remove mysql-libs
インストール成功
# rpm -i MySQL-*.rpm
サービスを起動させて3306ポートでLISTENしていることを確認 rpmインストールなのでサービス名がmysqlです。 yumインストールもしくは5.7はmysqldになります。
# service mysql status ERROR! MySQL is not running # service mysql start Starting MySQL SUCCESS! [root@shuhei src]# service mysql status SUCCESS! MySQL.. running (17092) # ps auxf |grep mysql root 17204 0.0 0.0 103320 852 pts/2 S+ 17:29 0:00 \_ grep mysql root 16989 0.0 0.1 11340 1364 pts/2 S 17:29 0:00 /bin/sh /usr/bin/mysqld_safe --datadir=/var/lib/mysql --pid-file=/var/lib/mysql/shuhei.pid mysql 17092 2.2 44.2 1013188 451848 pts/2 Sl 17:29 0:00 \_ /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --plugin-dir=/usr/lib64/mysql/plugin --user=mysql --log-error=/var/lib/mysql/shuhei.err --pid-file=/var/lib/mysql/shuhei.pid # netstat -atnp |grep mysql tcp 0 0 :::3306 :::* LISTEN 17092/mysqld
MySQLのプロセスが起動されているか、ポート接続しているかテストを書きます
require 'spec_helper' describe service('mysqld') do it { should be_enabled } it { should be_running } end describe port(3306) do it { should be_listening } end describe service('mysql') do it { should be_enabled } it { should be_running } end describe port(3308) do it { should be_listening } end
Nagiosインストール
nagiosがインストールされているテストを書きます。
require 'spec_helper' describe service('nagios') do it { should be_enabled } it { should be_running } end
/usr/local/src
配下に
最新版4.2.0をサイトからインストールします。
# wget https://assets.nagios.com/downloads/nagioscore/releases/nagios-4.2.0.tar.gz#_ga=1.247838018.451693304.1472123299 # wget https://nagios-plugins.org/download/nagios-plugins-2.1.2.tar.gz#_ga=1.179877985.451693304.1472123299
必要なパッケージをインストール
yum install gcc glibc glibc-common yum install gd gd-devel
Nagiosユーザとグループを作成
# /usr/sbin/useradd -m nagios # passwd nagios # /usr/sbin/groupadd nagcmd # /usr/sbin/usermod -a -G nagcmd nagios # /usr/sbin/usermod -a -G nagcmd apache # less /etc/passwd # less /etc/group
ダウンロードしたfileを解凍
tar xzf nagios-4.2.0.tar.gz cd nagios-4.2.0
作成したグループを指定してconfig scriptを実行
./configure --with-command-group=nagcmd
コンパイル実行
make all
インストール実行
make install make install-init make install-config make install-commandmode
web configをインストール
make install-webconf
Nagiosのweb画面にログインユーザーnagiosadminを作成
htpasswd -c /usr/local/nagios/etc/htpasswd.users nagiosadmin
Apache再起動
service httpd restart
pluginのコンパイルとインストール
# ./configure --with-nagios-group=nagios --with-mysql=/usr/bin/mysql checking for a BSD-compatible install... /usr/bin/install -c checking whether build environment is sane... configure: error: newly created file is older than distributed files! Check your system clock
OSとハードの時間が実際の時間とずれているのが原因でインストールに失敗する (2016/08/25)
# date 2016年 7月 24日 日曜日 18:17:55 JST # hwclock 2016年07月24日 18時17分58秒 -0.524383 秒
時間を合わせればインストールできる。
date -s "08/25 20:39 2016" 2016年 8月 25日 木曜日 20:39:00 JST date 2016年 8月 25日 木曜日 20:39:02 JST hwclock 2016年07月24日 18時20分17秒 -0.148454 秒 hwclock -w # hwclock --systohc # hwclock 2016年08月25日 20時39分16秒 -0.051022 秒
nagiosがインストールされているテストを書きます。
require 'spec_helper' describe service('nagios') do it { should be_enabled } it { should be_running } end