男もすなるsshといふものを、我もしてみむとて解説するなり
こんにちは。エンジニアでインターンをしている村田です。 最近寒くてベッドから起き上がるのがつらいです。
最近デスクトップ環境をxubuntuにしたのですが使いやすくて感動してます。 軽くて、Ubuntuらしい便利な機能も多くありますので他の方にもぜひおすすめです!
話は変わりますが、コンピュータの用語で新しく知ったものを調べると なんでこんなにわかりづらい説明しかないんだ!! と思ったことってありませんか?
自分は結構多いです、この現象(笑)。 学習していくとそれが当たり前になってしまうので「このサイトにわかりやすく書いてあるじゃん」と思うのですが、最初は難しく感じてしまうものなんですよね。
今回は以前自分が概念を理解するまでに苦労してしまった「sshのしくみ」についてまとめていこうと思います。 (「わかりやすい」というのは個人的な感想です。)
「ssh」略さずに言うと?
「ssh」はsecure shellの略です。 日本語にすると安全なシェルということです。
「ssh」っていつ使うの?
「sshとは安全なシェルのことです!」と言われてもそれではなんのことかわからないと思いますので、もう少しかみ砕いて説明していきます。 このページをご覧になっている方は、例えば「サーバーにアクセスしようとしたけどsshってどういうことなんだ?」とか「GitHubを使ってみたいけどなんか登録してsshを使わなくちゃいけないらしい」といった方が多いかと思います。
それではsshとはどういう場面で必要なのでしょうか?
簡単な言葉で説明すると「他のコンピュータに対してアクセスして、何かしらの操作を加えたいとき」にsshを使います。 例えば「サーバーに対してコマンドを実行して環境を作りたい」とか「GitHubなどのリモートリポジトリに対してブランチをマージさせたい」といったところで、sshというコマンドを使用したいわけです。
基本的にはssh user@host_name
で使います。
これは色々なところで書いてあるのでわかりやすいと思います。
そもそも、「安全なシェル」の「シェル」とは人間とコンピュータが気軽におしゃべりするための言語です。 ディレクトリを変えたり、 ファイルを削除したい!というときの「cd」とか「rm」はそれに当たりますよね。
遠くのコンピュータに命令したいときも当然同じようにおしゃべりできたら便利なわけですから、シェルを使いたいですよね。 ただし、暗号化なしで通信するとほかの人に見られる危険などがあるため安全なシェルすなわちsshを使いたいということなのです。 (実は以前は暗号化されていないtelnetというものを使っていました。基本的な機能しかないことを利用して、現在もサーバーを作る際にときどき用いることがあります。)
暗号化の仕組み
sshで公開鍵暗号方式を使用しています。(実は違うやり方でパスワード認証方式というのもありますが、あまり使われないように思われます。) 公開鍵暗号方式の通信とはサーバーに公開鍵を持たせて文書等を暗号化させて、受信する際には自分の持っている秘密鍵を使用して複合する通信のことです。
これを例えるとすると、 公開鍵を錠(lock)、秘密鍵はその錠の鍵(key)だと考えてください。
南京錠などを想像すればわかるように、lockのやり方がわかっても、keyが用意できなければ実際に中身にたどり着くことはできません。 リアルの世界とは違って暗号化の世界では錠の鍵穴を見て鍵を作り出すことができない(らしい)ので、自分の秘密鍵をばらさなければこれで安全に通信することが可能なわけです。
また、sshではより安全性を高めるために秘密鍵に対して鍵をかけるのが一般的です。 鍵に鍵をかけるというのは面白いですよね。
この鍵は暗号化も複合化も同じ共通鍵暗号方式を使用しています。
実際に使用していくコマンド
ここでは実践で使っていくコマンドを簡単に紹介していきます。 紹介できなかったオプションやコマンドがたくさんあると思うので、不足している部分に関しては最後の参照URL等をご覧ください。
また事前知識としてsshに関するファイルは~/.ssh
というディレクトリに入るのですが、そこのファイルの役割を紹介しておきます。
authorized_keys 公開鍵を登録しておくファイル。 config SSH接続に関する設定を書いておくファイル。 known_hosts 過去に接続したことがあるサーバーを書いておくファイル。
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
これはgithubで推奨されている鍵の作り方です。
-t rsa
の部分はRSAという暗号化方式を使って作成するという意味です。
他にもDSAやECDSAといった種類がありますが一般的にはRSAを用いるのではないかと思います。
また-b 4096
では鍵のビット数をしてしています。デフォルトでは2048になのでより強固に作成していると言えますね。
-C "your_email@example.com"
の部分はコメントなので必要なければ省いて構いません。
途中でパスフレーズを聞かれると思いますが、これが先ほど書いたとおり秘密鍵に対するパスワードになっているので忘れないものを使用してください。
このコマンドを実行するとid_rsa
とid_rsa.pub
が作成されます。もちろん前者が秘密鍵、後者が公開鍵です。
余談ですが、GitHubユーザーのSSH鍵6万個を調べてみたでGitHubのssh鍵に関して面白い考察がありました。
ssh-copy-id -i ~/.ssh/id_rsa.pub user@host_name
これはsshの公開鍵を登録したいサーバーに送るコマンドです。
i
オプションで任意のファイルを指定して送ることができます。ここでは先程作成した~/.ssh/id_rsa.pub
を指定しています。
ssh-agentとssh-add ~/.ssh/id_rsa
ssh-agent
は認証エージェントとよばれるもので、sshをするときに必要なパスワードの入力をショートカットできるようにするコマンドです。
(ubuntuやMacの人は自動的に起動しているのでこのコマンドは忘れてしまっても問題ありません。ただ、他のOSではssh-agent bash
などを打たないといけないかもしれません。)
ssh-add
はssh-agent
に秘密鍵を追加するメソッドです。
引数にとった秘密鍵を追加します。
参照URL
http://qiita.com/tag1216/items/5d06bad7468f731f590e http://qiita.com/suthio/items/2760e4cff0e185fe2db9 http://webos-goodies.jp/archives/50672669.html
またこちらは書籍ですが、私がsshの仕組みを少し理解できるようになったきっかけになった本です。 はじめてUNIXで仕事をする人が読む本
HTMLテンプレートエンジン「slim」の解析ツールslim-lintを導入してみた!
こんにちは、エンジニアの井戸田です。
弊社ではmamanokoという子育てをするママのためのメディアをRuby on Railsで運営しており、viewではHTMLテンプレートエンジンであるslimを使用しています。今までrubyの解析ツール rubocop
や、scssの解析ツール scss-lint
は導入しましたが、slimの解析ツールを導入していなかったということで、今回導入してみました。
インストール
$ gem install slim_lint
又は Gemfile
に下記を記入して bundle install
をすることでインストールが可能です。
gem 'slim_lint', require: false
require: false
を指定することで、 autorequire
をしないようにしています。
実行方法
スキャンするディレクトリ、又は複数のディレクトリを指定することによって、コマンドラインから slim-lint
を実行することが可能です。
$ slim-lint app/views $ slim-lint app/**/*.slim
又 slim-lint -v/--version
を指定するとバージョンを確認ができます。他にもいろいろなオプションがあるので、下記のURLから御覧ください。
ref) https://github.com/sds/slim-lint#usage
実装
slim-lintはデフォルトで下記のような設定になっています。
ref) https://github.com/sds/slim-lint/blob/master/config/default.yml
# Default application configuration that all configurations inherit from. # # This is an opinionated list of which hooks are valuable to run and what their # out of the box settings should be. # Whether to ignore frontmatter at the beginning of Slim documents for # frameworks such as Jekyll/Middleman skip_frontmatter: false linters: CommentControlStatement: enabled: true ConsecutiveControlStatements: enabled: true max_consecutive: 2 EmptyControlStatement: enabled: true RedundantDiv: enabled: true LineLength: enabled: true max: 80 RuboCop: enabled: true # These cops are incredibly noisy since the Ruby we extract from Slim # templates isn't well-formatted, so we ignore them. # WARNING: If you define this list in your own .slim-lint.yml file, you'll # be overriding the list defined here. ignored_cops: - Lint/BlockAlignment - Lint/EndAlignment - Lint/Void - Metrics/LineLength - Style/AlignHash - Style/AlignParameters - Style/BlockNesting - Style/FileName - Style/FirstParameterIndentation - Style/FrozenStringLiteralComment - Style/IfUnlessModifier - Style/IndentationConsistency - Style/IndentationWidth - Style/MultilineArrayBraceLayout - Style/MultilineAssignmentLayout - Style/MultilineHashBraceLayout - Style/MultilineMethodCallBraceLayout - Style/MultilineMethodDefinitionBraceLayout - Style/MultilineMethodCallIndentation - Style/MultilineOperationIndentation - Style/Next - Style/TrailingBlankLines - Style/TrailingWhitespace - Style/WhileUntilModifier TagCase: enabled: true TrailingWhitespace: enabled: true
この設定の中で、不要・変更したい設定に対して、ホームディレクトリに .slim-lint.yml
というファイルを作成し、記述することで無効化・変更します。
.slim-lint.yml
の記述例
exclude: - 'repository_name/app/views/**/*.slim' linters: CommentControlStatement: enabled: false LineLength: include: 'repository_name/app/views/**/*.slim' max: 80 EmptyControlStatement: exclude: 'repository_name/app/views/**/*.slim'
オプション | 説明 |
---|---|
exclude | slim-lintや各linterから除外したいファイルがある時に使用します。 |
include | 指定したファイルで絞り込みを行います。 |
enable | false とした時には、そのlinterが走ることはありません。そのlinterが不要な時に使用します。 |
linterの説明
CommentControlStatement
コメントの書き方についての制御するlinterです。
- Bad
# commentout
- Good
/ commentout
ConsecutiveControlStatements
連続の制御文に対して制御するlinterです。
ConsecutiveControlStatements
には下記ようなオプションがあります。
制御構文が同じインデントで2行以上続くのでしたら、見やすさからviewに書かずに helper
にその制御を移動させた方がいいと思います。
オプション | 説明 |
---|---|
max_consecutive | 行に指定できる制御文の最大数 |
- Bad
- code1 - code2 - code3
- Better
ruby: code1 code2 code3
- Good
- helper_method_name
EmptyControlStatement
空行に対して制御するlinterです。
こちらのlinterを true
にすると空行がなくなり、場合によっては見づらくなる可能性があるので、注意する必要がありそうですね。
- Bad
p pタグ - p pタグ
- Good
p pタグ p pタグ
RedundantDiv
div
タグに対して制御するlinterです。
slimでは div.class_name
と書かずに .class_name
と記述するだけで divタグ
になります。不要な場合に div
と記述しないというのが、このlinterの役割です。
- Bad
div.class_name
- Good
class・idを指定せず、ただの改行などの場合に使用する場合にはdiv
と記述する必要があります。
div
- Good
.class_name
RuboCop
このlinterはテンプレート内に存在する Ruby
コードをチェックする為のものです。
ホームディレクトリに作成された .rubocop.yml
の内容が反映されるようです。
ref) https://github.com/bbatsov/rubocop
オプション | 説明 |
---|---|
ignored_cops | 無視したいRubocopの設定を記述 |
TagCase
大文字のタグ名を報告するlinterです。
HTMLの標準では、小文字のタグ名を限定するということはなく、大文字でも対応できるのですが、XHTMLでは小文字の記述が必須なので、一貫性としてこのlinterが作られたようです。
個人的に大文字・小文字が混ざっているいると見づらい点や、小文字にすることで大文字より見やすくなる点があるので、小文字で揃えた方がいいと思います。
- Bad
BODY p pタグ
- Good
body p pタグ
いかがでしたでしょうか?
slim-lint
を導入することで、気をつけて同じフォーマットにしようとしていても、どうしても見逃してしまう部分や、行数を制限することで、1つのファイルだけで処理するのではなく、partial化させることにより見やすくなると思います。
最後まで読んでいただきありがとうございます。
We’re hiring!
フロントエンジニアの方で、サーバーサイドを触ってみたい方、ぜひ一度Cluexに遊びに来てください!!
AWSのCloudFrontからコンテンツをHTTP2 & gzipで高速に配信する
こんにちは、高橋です。
みなさん快適で楽しいAWSライフを送れていますか?
実は2ヶ月ほど前、AWSからCloudFrontでHTTP2によるコンテンツの配信ができるようになったので早速導入して見ました。
Amazon CloudFront now supports HTTP/2
S3のバケットにあるCSSやJS、画像などのアセットをCloudFrontから配信するというパターンは AWSでインフラを構築するサービスではよくあると思います。
今回はこういったS3上にあるアセットをHTTP2とgzipを使用してCloudFrontから配信するための設定方法などを見ていきたいと思います。
設定そのものは3分くらいで終わります。
CloudFrontにHTTP2を適用する
先ずはAWSのコンソールを開き、CloudFrontを選択します。
リンクまたはチェックボックスを押して「Distribution Settings」からディストリビューションの設定画面に飛びます。
「General」タブの「Edit」ボタンから基本設定の変更ページへ飛びます。
「Supported HTTP Versions」をHTTP2が含まれているものを選択して、右下の「Yes, Edit」ボタンを押します。
ちなみに「Supported HTTP Versions」の右にある黒いボタンを押すと、下記のような説明が出てきます。
For viewer requests, choose the versions of the HTTP protocol that you want CloudFront to accept. In general, HTTP/2 is faster. CloudFront always forwards requests to the origin using HTTP/1.1.
日本語にすると
ユーザーからCloudFrontへのリクエストの際に使用するHTTPプロトコルを選択してください。一般的にHTTP2は速いっすよ。CloudFrontからオリジンへのリクエストはHTTP 1.1だけ使うでー。
といった感じでしょうか。
ユーザーからのリクエストはHTTP2を使用できますが、CloudFront内部でのリクエストではHTTP2はまだ未対応のようです。
とはいえ、ひとまずこれで設定完了です!楽勝ですね!
あとは設定が完了するまで時間を潰して、 設定が完了したらブラウザから確認できればOK!
Chromeなどのブラウザのデベロッパーツールから見てみると.....
レスポンスは304になっていますが、「Protocol」のところが「h2」になっていれば設定完了です!
CloudFrontでgzip圧縮による配信をする
では次にファイルをgzip圧縮して配信する設定を見ていきましょう。
先ほどのディストリビューションの設定画面に飛びます。
今回は「Behaviors」タブを選択して、gzip配信にしたいものにチェックボックスを入れて「Edit」を押します。
下にスクロールしていくと、一番下に「Compress Objects Automatically」という設定項目があるので、「Yes」を選択してから右下の「Yes, Edit」を押して設定完了!
ちなみに「Compress Objects Automatically」の右にある黒いボタンを押すと、下記のような説明が出てきます。
Select whether you want CloudFront to automatically compress content for web requests that include Accept-Encoding: gzip in the request header. CloudFront compresses files of certain types for both Amazon S3 and custom origins.
日本語にすると
わいに頼んでくれたらリクエストヘッダにAccept-Encoding: gzipがあった時はCloudFrontの方でコンテンツの圧縮しとくで。S3とか別のオリジンのファイルでも圧縮できそうなら、わいが勝手にしとくやでー。
といった感じでしょうか。
圧縮倍率はCloudFrontの方でよしなに決めてくれるようです。
ということで設定が終わったのでブラウザから確認して見ましょう!
先ほどと同様にChromeなどでデベロッパーツールを開き、CloudFrontから配信されているファイルのレスポンスヘッダを確認します。
「content-encoding: gzip」となっていますね!
これでCloudFrontにHTTP2とgzip配信の設定が完了しました!
手軽にできてすぐに効果が期待できるので、気になった方は試して見てください!
We're hiring!
Cluexではビジネスサイド、エンジニアサイド共にメンバーを募集しています! お気軽にご連絡下さい!
Mockを使って、Facebookログイン部分のRSpecを書いてみた!!
こんにちは、エンジニアの神山です。 最近、テストカバレッジを上げるためRSpecを書きまくっています。ちなみに最初は90%でしたが、苦闘の末95%まで上がりました。結構骨が折れましたね。
その中でも大変だったのがFacebookログイン部分のテストです。外部APIを使っており、そこの部分のテストの書き方が分からなくて悩んでいました。 色々と調べてみるとモックを使うとうまいことテスト出来るよという文献を見つけました。
ということで今回は、外部API部分のテストの問題点、モックとは何か、またそれをどのようにテストに使うのかにフォーカスして記事を書きました。
外部API部分のテストの問題点
今回悩んだのは外部APIを使用している部分のテストをどのように書くかということです。
例えば、「ログインしようとしているユーザーのFacebookのアカウント情報を取得し、すでにDBに登録されていればログインさせる」ということです。 しかしこのテストを行うには、実際にFacebookAPIよりアカウント情報を取得しなくてはいけません。
しかしテストで外部APIを利用することには、幾つかのデメリットがあります。
- 外部APIやその周辺で、予測や対応ができないエラーが起きることがある
- 外部APIの使用に制限があったり、金銭などが発生する場合がある
- 外部APIに紐付いているプロダクトにリアルに影響が起こる(Facebookの場合、実際に投稿がされてしまうなど)
では、どうすれば外部APIを利用せずに、外部API部分を使用している部分のテストを出来るのでしょうか。 そのようなときに使うのが、「モック」です。
モックとは何か。
モックを直感的に説明すると、「本物のふりをするニセモノのプログラム」です。下記の記事の言葉を使わせて頂きました。
例えばユーザーのFacebook情報を取得するとき、FacebookAPIにリクエストが発生したら予め用意したニセモノのプログラムを呼ぶようにすることが出来ます。 また「aが呼ばれたときに本当はbを返すのだけど、ここのテストだけはcを返したい」というときに使用したりもします。
つまりモックとは、外部APIなどテストを行うために必要だけれど使用できない、再現することが難しい場合に、その役割を担ってくれるものです。
ちなみにモックとスタブの違いは?
モックと似た言葉にスタブというものがあります。気になって調べてみたのですが、両者の違いは使用目的だそうです。基本的にどちらもニセモノを作り出すことには変わらないようです。
ただその違いを明確に理解するのはなかなか難しく、またあまり意識する必要もないという意見もあったので、今回は保留にしました。時間があるときに色々と調べてみようと思います。
ちなみに、分かりやすく書いてある記事があったので、載せておきます。
モックの準備
Omniauth
部分のテストに関しては以下に従っております。
まずモックにすべきところを整理しましょう。 今回はユーザーのFacebook情報を取得する際にFacebookAPIを用います。そしてFacebookに登録されている名前やEmailを取得します。 そのため、今回モックにするところはFacebookAPIにリクエストがあったときに返す部分です。 以下をHelperに記します。
def facebook_mock(name, email) OmniAuth.config.mock_auth[:facebook] = OmniAuth::AuthHash.new( provider: 'facebook', uid: 1234567890, info: { name: name, email: email }, credentials: { token: 'hogepiyo1234' } ) end OmniAuth.config.test_mode = true
たとえば、facebook_mock('foo', 'bar')
とすれば、以下の値が得られます。
{ provider: 'facebook', uid: 1234567890, info: { name: 'foo', email: 'bar' } , credentials: { token: 'hogepiyo1234' } }
またOmniAuth.config.test_mode = true
はOmniauthを用いたテストの際に必要になるので、一緒に記述しておいてください。これを記述すると、FacebookAPIにリクエストが送られそうになると、それを中止してすぐにコールバックしてくれます。
RSpec
では、Facebookログイン部分の一連のテストを書いていきます。
まず、ユーザーを作成します。
let(:user) { User.create(name: 'hoge', email: 'hoge@hoge.com') }
テストの前にOmniAuth.config.mock_auth[:facebook]
を初期化し、facebook_mock
をセットします。
OmniAuth.config.mock_auth[:facebook] = nil Rails.application.env_config['omniauth.auth'] = facebook_mock( name: user.name, email: user.email )
準備はこれだけです。では実際にFacebookログインをしてみます。今回は分かり易くボタンを押してFacebookログインをする形式にしてみました。
click_link 'Facebookを利用してログインする'
さて、ボタンが押されると通常はFacebookAPIにリクエストが走りますが、テストではすぐにコールバックされます。
ただモックのおかげで、request.env['omniauth.auth']
には下記の値が入っております。
{ provider: 'facebook', uid: 1234567890, info: { name: 'hoge', email: 'hoge@hoge.com' } , credentials: { token: 'hogepiyo1234' } }
そのため、request.env['omniauth.auth']['info']
でname: 'hoge', email: 'hoge@hoge.com'
の組み合わせを取得できるようになります。あとはこれをDBと照合して、有効であるかどうかを確かめればテスト終了です。
テスト全体は以下のようになります。
discribe 'login via Facebook' do let(:user) { User.create(name: 'hoge', email: 'hoge@hoge.com') } before do OmniAuth.config.mock_auth[:facebook] = nil Rails.application.env_config['omniauth.auth'] = facebook_mock( email: user.email, name: user.name ) click_link 'Facebookを利用してログインする' end it 'should succeed' do expect(page.status_code).to eq 200 end end
ちなみに検証部分がステータスコードの判別しかないですが、ログインされているかどうかを簡単に確認できる指標が欲しいですね。
例えば、expect(current_user).to eq user
のようなものがあれば。。
以上、Mockを使ったRspecの書き方でした。読んで頂きありがとうこざいました。 アドバイスなどありましたら是非お願いします!
We're hiring!
Cluexではビジネスサイド、エンジニアサイド共にメンバーを募集しています! お気軽にご連絡下さい!
参考文献
Docker for Macが遅い問題をdocker-syncで解決する
こんにちは。エンジニアの志村です。 Docker for Mac便利ですね!
日本語でも様々な記事が出てきています。
私もVagrant + Dockerをメインに使用しておりましたが、ついにDocker for Macに乗り換えました。
弊社では、dev環境をDockerにしているのですが、Vagrant + Dockerの時は快適に開発が出来ました。
ただ、VMを使わなくなった途端にめちゃくちゃ動作が重くなりました。
docker-compose --service-port ●●
という感じで、rails serverとwebpack-dev-serverを立ち上げるのですが、ブラウザからの読込が劇的に遅い…。seedデータ突っ込むのもめちゃくちゃ遅い…
フォーラムでも話題になっていますね。
私の環境でいうと、Vagrant + Dockerの時よりも、体感10倍近く速度が落ちました…。
なぜ遅いのか
このDockerの中の人の回答を見ると、osxfsを用いてファイルシステムイベントを検知・監視していることが主な原因っぽいですね。 勿論、その他環境により差異はありますが、ファイルシステムを監視する方法を替えれば解決できそうです。
docker-sync
ファイル同期で速度早いと良く言われているのがrsyncですね。 docker-dev-osxという選択肢もありますが、これはDocker for Mac未対応… どうしようかなーとフォーラムを眺めているとdocker-syncなるものがありました。 フォーラムの中でも評価が良く、結構な人が使ってそうなのでdocker-syncを使用したいと思います。
docker-syncはRubyベースで書かれています。
docker-syncの使い方
- docker-sync, fswatchをインストールします。
$ gem install docker-sync $ brew install fswatch
ファイルの同期に関してはrsync, unisonが選択出来ます。 rsyncがホスト→ゲストの一方向の通信なのに対し、unisonはNFSのように双方向の通信が可能なようです。 今回はrsyncを使用します。 unisonに関してはまた記事を書ければと思います。
$ brew tap homebrew/dupes $ brew install rsync
※ schema.rb, Gemfile.lock等、ゲスト(Docker)側で生成されるファイルに関してはdocker cp
コマンドを使用するとホスト側に持ってくることが出来ます。
# Docker内のschema.rbをPC側に持ってくる
$ docker cp コンテナ:/var/www/db/schema.rb ./db/schema.rb
- docker-syncの設定 docker-syncはymlファイルに設定を記述します。 Railsを触っている身としては普段から使用しているのでありがたいです。
docker-syncはDocker Composeを使用します。 production環境やstaging環境でもDockerを使用している方は、docker-compose.ymlの他に、開発環境用のymlファイルを用意する必要があります。 私は開発環境のみなので、docker-compose.ymlを直接編集してしまいます。
公式のwikiに載っているので参考下さい。
docker-sync.yml
syncs: # docker-syncで使用するvolume名を記載 web-sync: notify_terminal: true # ホスト側(PC)のパスを記載 今回はRailsのルートディレクトリを指定 src: './' # ゲスト側(Docker)にマウントするパスを記載 Docker内の/var/wwwにマウントされる dest: '/var/www' # IPの設定 sync_host_ip: '127.0.0.1' # rsyncのポート設定 sync_host_port: 10871 # rsyncさせないファイル類を記載 sync_excludes: ['Gemfile.lock', 'Gemfile', 'config.rb', '.sass-cache/', 'sass/', 'sass-cache/', 'composer.json' , 'bower.json', 'package.json', 'Gruntfile*', 'bower_components/', 'node_modules/', '.gitignore', '.git/', '*.coffee', '*.scss', '*.sass'] sync_excludes_type: 'Path' sync_args: '-v' # ファイル同期方法の選択 rsync or unison sync_strategy: 'rsync' # ゲスト側でのユーザー名の指定 sync_user: 'test' sync_userid: '5000' # ゲスト側でのgroupの指定 sync_group: 'testgroup' sync_groupid: '6000' # fswatchで変更を検知させないファイルやディレクトリ sync_excludesとかぶせとけばよいかと watch_excludes: ['.*/.git', '.*/node_modules', '.*/bower_components', '.*/sass-cache', '.*/.sass-cache', '.*/.sass-cache', '.coffee', '.scss', '.sass', '.gitignore'] watch_args: '-v' watch_strategy: 'fswatch'
docker-compose.yml
docker-compose.ymlにはversion1, version2と2種類の記述方法があります。 ここではversion2を使用します。
version: '2' services: database: image: postgres:latest volumes_from: - datastore expose: - '5432' elasticsearch: image: elasticsearch:latest volumes_from: - datastore ports: - '9200:9200' redis: image: redis:latest ports: - '6379:6379' volumes_from: - datastore memcached: image: memcached:latest ports: - '11211:11211' volumes_from: - datastore datastore: build: docker/datastore web: build: . command: bash -c 'rm -f tmp/pids/server.pid && bundle exec foreman start && bundle exec sidekiq -C config/sidekiq.yml -L tmp/sidekiq.log -d' volumes: # 下記で宣言したvolume名を指定 - web-sync:/var/www:rw - /var/www/client/node_modules ports: - '3000:3000' - '8080:8080' links: - database - elasticsearch - redis - memcached # docker-syncで使用するvolume ここで宣言した名前がdocker-sync.ymlで使用される volumes: web-sync: external: true
このような感じです。 環境によって差異があると思いますので、適宜調整をお願いします。 一番重要なのは、volumesのsync volumeの設定と、アプリケーション(Rails)側のコンテナでvolumesを指定する部分です。
docker-syncの起動
$ docker-sync start
もしくは
$ docker-sync-stack start
で起動します!
docker-sync-stack start
の場合は、docker-sync start
と同時にdocker-compose up
も行われます。
私はpry-byebugを使用したいので、普段docker-compose run --service-port web
で起動しているため、ターミナルを一枚docker-sync startに使用し、さらにdocker-compose run --service-port web
を起動させるようにしています。
ベンチマークはとっていないのですが、Vagrant + DockerをNFSで同期させたのと同じ、もしくはそれ以上に早くなりました! GUIで様々な設定が出来、VMとかも必要ないのでDocker for Macは便利ですね。 是非docker-syncを使って快適な開発環境を構築してみては如何でしょうか?
We’re hiring!
Cluexではビジネスサイド、エンジニアサイド共にメンバーを募集しています! お気軽にご連絡下さいませ!
今年2回目の開発合宿に行って来ました!@土浦・筑波
こんにちは、エンジニアの高橋です。
最近都内は急に肌寒くなってきましたが、みなさんお元気でしょうか?
今回は茨城県の土浦・筑波エリアで開催!
先日、2泊3日で茨城県の土浦・筑波の方に開発合宿に行ってきました!
台風が近づいている中での開催となり、心配な所もありましたが無事に終わったので、 今回はその様子をまとめようと思います。
2月の開発合宿に続いて、今年2回目の開催となります。 Cluexでは合宿を利用して 普段なかなか手のつけられない技術的課題や技術的負債への取り組みや、 理念会議といったメンバー全員でじっくり話し合う場を設けるなど といったことをしています。
ちなみに前回(2016年2月)の日光での合宿の様子はこちら cluex-developers.hateblo.jp
古民家ゲストハウス「jicca」
今回の宿泊先には2泊3日の全日貸切で、筑波山の近くにある 茨城県石岡市のゲストハウス「jicca」さんを使わせてもらいました。
ここのゲストハウスはクラウドファンディングを活用して、 もともと実家の母屋だったものをゲストハウスに改装したそうです。
ここの近辺は豊かな自然が溢れていて、とても落ち着いている長閑な場所で、
jiccaは最近は雑誌やラジオなどで度々話題になっているそうです。
こちらを運営されている比企(ひき)さんという方は、もともと大手企業で活躍された後に 現在はこちらの「jicca」を運営されつつ個人で中小企業診断士として中小企業コンサルをされている方で、とても暖かい方でした。
今回の合宿でのTRY
合宿に参加したのはエンジニア4人・ディレクター3人の合計7名。
合宿中はエンジニア陣は2人で1チーム、ディレクター3人で1チームの全部で3チームに別れて目標を立てました。 合宿の目標はそれぞれのチームであらかじめ決めておき、合宿当日はすぐに作業が開始できる様にしておきました。
ディレクターチーム 売上を上げるためのコンテンツマーケティングの運用方針を決める
今後の事業成長戦略を各々が考えて発表
Web appチーム Rspecのテストカバレッジを95%達成
インフラ&ネイティブアプリチーム CoffeeScriptからES2015(ES6)への完全移行
開発合宿1日目
台風が近づいてる影響で初日は曇り空。
午前9時、都内某所に集まり出発です!
都内から土浦までは高速道路を使用して、車でおよそ1時間半ほどの距離にあります。
新卒3人組
前日も遅くまでオフィスに残っていたみたいで非常に眠そうですね。
土浦までの道中は高速道路も渋滞なく順調に進み、
守谷SAで途中休憩を挟んでほどなくして土浦に到着です。
宿に着く前に、激安ジャングルで物資調達です。
車内では眠そうだった彼も元気になったみたいです。
そして11時過ぎにjiccaへ到着。
到着してからまずは全体で各チームの合宿中の目標を共有し、 終わり次第すぐに各自作業に取り掛かります。
ディレクターチームは主に話し合いが多いので1階にて作業。
エンジニアの方は机と椅子が用意されている2階に上がり作業を開始。
ディレクターチーム
エンジニアチーム
1日目の夜は夕食と温泉を兼ねて、
車で10分ほど移動して「やさと温泉 ゆりの郷」へ行きました。
この近辺は日帰り温泉が500~1000円くらいで点在しているので、 その中から一番近場の場所を選びました。
「jicca」のオーナーの比企さんも一緒に温泉にお供して頂きました。
こちらの常陸牛は柔らかくてとても美味しいお肉でした。
夕食後
本日はアルコールは一切なしで、 夕食を食べた後はすぐ宿に戻って作業再開です。
ディレクターチームは順調に進んでいるようで、午前12時頃には就寝。
エンジニアの方はまだまだ続きます。
午前4時
まだ続きます。
初日が終わり、全員が寝静まったのは午前6時頃。
長い長い1日目が終了です。
開発合宿2日目
台風は進路を変えていなくなってしまい、 晴れ晴れとした天気になりました。
午前9時、起床。
全員で集まり1日のスケジュール確認です。
午前中は引き続き各チームごとで作業。
昼食は手打ち蕎麦が有名とのことで、宿の近くの蕎麦屋さん「かまたや」へ
創業60年以上の老舗蕎麦屋だそうです。
蕎麦はもちろん、天ぷらがめちゃめちゃ美味しいです。
宿に戻り、今回の合宿のもうひとつの一大イベントに入ります。
Cluex理念会議
2日目は昼食後から6時間ほどに渡り、
ディレクター・エンジニア含めて全員で「理念会議」といったものを行います。
前回の合宿に続き、
今回も個人個人の将来・会社の将来、自分がこれからどうしていきたいか・どうなりたいのかといったことを発表して、
それをどうすれば実現できるのかということをみんなで話し合っていきます。
・・・5時間経過後
ということで、写真にはあまり変化がないですが、
一人一人にフォーカスして個人の思想やその背景にある思い、
そしてそれぞれの将来に関してじっくり話し合ってきました。
理念会議が終わった頃には日がすっかり暮れてしまいました。
これからやや遅めの夕食です。
2日目の夕食はBBQ!
「jicca」の方で茨城県産の食材をたくさんご用意して頂いて、みんなでBBQです。
今回のBBQに望むためのチーム編成はこちら
調理部隊
バーベキュー屋の店員
火起こし部隊
おじさんたち
火起こし部隊の後ろで待機です。
そして・・・・
いざBBQ!
普段はこういった機会がなかなか無いので、
みんなでお酒を飲みながら語り合って、貴重な時間を過ごせました。
BBQを堪能し、ほどなくして2日目も終了です。
今日はみんな疲れが出てきたようで、午前12時にはみんな就寝したみたいです。
開発合宿3日目 (最終日)
3日目も天気に恵まれた、気持ちのいい朝を迎えました。
午前9時に起床し、10時にチェックアウトです。
3日目は土浦市街の方で貸会議を借りました。夕方まではこちらで各チーム作業を行い、最後に経過発表です。
お借りしたのは、「ワークヒル土浦」の特別会議室。社内の会議などであれば法人でも利用ができます。
10時~17時の利用で4000円ほどと、なかなかのお手頃価格です。
人数のわりに、とても立派な会議室でした。
こちらで一通り作業をした後、
各チームからの合宿目標の結果発表と振り返りを行いました。
今回の合宿で取り組んでいた、 「ES2015(ES6)の導入」や「Rspecのカバレッジ」に関しては、追ってブログにまとめたいと思いますので、しばしお待ちください。
観光編
JAXA(筑波宇宙センター)に入ってきました!
合宿最終日、会議室で結果発表などを終えた後、
20分ほど車を走らせて茨城県つくば市にある「JAXA 筑波宇宙センター」に行ってきました。
日本の宇宙産業を牽引するJAXA。
アメリカではNASAのスペースシャトルが引退し、SpaceXなどの民間企業へのシフトが進んでいますが、そんな宇宙を相手にする仕事はロマンがあってすごいなあと個人的には思うところです。
最先端の技術たちを駆使して宇宙という過酷な環境に挑むって本当にすごいです。
教育にも最先端の技術をどんどん導入していきたいです。
という訳で、JAXA見学です!
ISSの日本実験棟「きぼう」
中にも入れちゃいます。
宇宙服 (1着あたり10億円するそうです)
興味津々です。
その他にも衛星やロケット、エンジンなどが実物大で見れます。
施設の方(JAXAを引退された方?)に、
宇宙に関して、衛星や衛星に使用している技術など
色々なお話を付きっきりで伺うことができました。
ありがとうございました。
合宿のまとめ
前回に引き続き、今回も有意義な合宿となりました。
今回の合宿での反省点や改善点は次回以降にまた活かしていきたいと思いますが、
これから開発合宿をやろうと考えている方にも、気をつけるポイントなどをあげておこうと思います。
Keep
・メンバーのチームワーク強化に繋がった。
・宿泊代がお手頃。
・旅のお供に温泉は大事。
・ご飯が美味しい。
・宿にネット環境が整っている。
・自然溢れる環境なのでとてもリフレッシュできた。
・近くに娯楽施設がないので、逆に集中できた。
Problem
・床に座って作業するときは座椅子があると良かった。
・作業に当てられる時間が意外と短い。合宿中にやることの選択と集中が大事。
開発合宿のポイント
合宿にあたって気をつけていたことは、
・合宿の目標には数値的な結果が見えやすい目標を。
→ 加えて、合宿の開始と同時に、すぐに作業に取り掛かれる様に準備しておくと時間を無駄にせずに済みます。
→ 開発合宿の醍醐味として合宿中に立てた目標を達成することがとても大事だと思うので、どうしても終わらなそうであれば合宿前にある程度の下準備をしておくといいかと思います。
・お酒は最終日の前夜のみに抑える。
→ ダメになりやすい人は控えましょう。お酒を飲むとせっかくの目標もどうでもよくなっちゃいます。
・ネット環境の確認。
→ wifiの有無はもちろん、速度面なども事前に確認しておくと安心です。
→ もしもの時に、モバイルwifiを各自で持参しておくと何かと便利ですが、圏外になることもしばしばあります。
・電源の確保。
→ 作業する場所で電源が使用できるかはもちろんですが、延長ケーブルを持参すると便利なこともよくあるので、事前に確認しておくと安心です。
・お昼に温泉は入らない。
→ 温泉に入ると気持ちが満たされてせっかくの目標もどうでもよくなっちゃいます。ダメになりやすい人は控えましょう。
・近隣の施設や観光地を調べておく。
→ 特に宿泊施設内もしくは近場にコンビニがあるか確認しておくと安心です。24時間営業ではないコンビニもあるので気をつけておくといいかと思います。
・予定は詰め込み過ぎない。
→ 食事処の予約や会議室の予約など、時間的な余裕を持って対応できる様にしておくといいかと思います。
→ 合宿中にやることも基本的には1~2つに絞ると雑念なく集中できるのではないかと思います。
番外編
懐かしきスマブラ!!
実は遡ること2日目のBBQの後、懐かしきスーパーファミコンと任天堂64が出現!
jiccaの方で貸していただきました!
プロジェクターも用意して頂いて懐かしい気分に浸りつつ、ガチバトル。
猫
jiccaで飼われている猫です。
猫かわいいですね、猫。
いかがでしたでしょうか?
日々の業務では対応できない経営課題や技術課題に取り組むために、新しい技術の試験の場に、新しい事業の創出の場に、開発合宿やってみてもいいかもしれません。
個人的にはリフレッシュもできてES6の導入も無事に進み、温泉に入れて美味しいご飯を食べれていい合宿でした。 これからまた更に事業スピードあげていきたいところです。
We're hiring!!
Cluexではビジネスサイド、エンジニアサイド共にメンバーを募集しています!
気になった方はご連絡ください!!
ビジネスサイド
エンジニア
SPDYも廃止されたのでnginxでhttp2使いたいけど、そもそもhttp2ってなに?っていうお話
こんにちは、高橋です。最近はnginxとrailsとswiftをぐるぐるしています。
nginxは非常にパワフルなwebサーバーで、アクセス数が増大した時した時でも非常に安定してトラフィックを捌いてくれています。
Ruby on Railsを使用する場合には、unicornやpumaなどのアプリケーションサーバーと併用して使うことが多いかと思いますが、どうしてもアプリケーションサーバーの方がボトルネックになってしまいます。nginxの処理能力をどれだけ極限まで高めても、結局はアプリケーションサーバーの方で処理しきれずに503が返ってきてしまうので、どうやってアプリケーションサーバーの方を安定的に処理能力をあげるか最近は悩むところです。。
最近ではAWSのEC2などでautoscalingもよく使われているので、1台あたりのトラフィックの処理能力はそれほどカリカリにまで高める必要はないのかもしれません。
ということで前置きはこんな所で、今回は(僕が勝手に)社内にもhttp2を取り入れたいなーと思い、色々調べてサーバー上で試験的に試してみたので、まとめてみました。
nginxでHTTP/2を使用する
Googleが提唱していたSPDYを取り込んだ形でhttp/2が標準化される流れとなり、これから本格的に広まって行きそうですが、nginxではバージョン1.9.5からhttp/2をサポートするようになりました。
HTTP/2とは
http/2は、http/1.1でプロトコルレベルでの問題となっていたデータ送受信における効率の悪さを克服する形で、http/1.1ではクライアントとサーバーがシングルシーケンスでデータをやりとりを行なっていたのが、http/2ではmultipleにシーケンスのやりとりを行うことができるようになりました。これによってデータ転送と処理の効率が上がりwebページを表示するまでのスピードが上がるというわけです。
http/1.1の場合 http/1.1ではブラウザのTCP同時接続は最大4~6に制限されています。 HTTP Head of Line Blockingによりブラウザのネットワークはこんな感じに、ひとつのファイルの読み込みが終わるまでは、それ以降のファイルの読み込みはブロックされます。
http/2を使用した場合 同時に複数のファイルの読み込みを行うようになります。http/2ではブラウザの最大同時リクエスト数は100以上が可能とされていています。
webブラウザのHTTP/2対応状況
2016年9月現在のブラウザの対応状況はこんな感じです。ChromeやFirefoxなどのメジャーなブラウザではほぼほぼ対応していますが、IEやsafariなどでは一部対応といった感じのようです。
Can I use... Support tables for HTML5, CSS3, etc
HTTP/1.1からHTTP/2への主な変更点
- 根本となる部分はhttp/1.1と同じ
- http/1.1のセマンティックスは変更しない
- サーバーへのTCP接続数を1つに限定
- TLSの機構を使用してプロトコルを自動選択
- バイナリープロトコル
- 多重化送信
などといったことが挙げられます。
HTTP/2を使用すると現在のTLSは一部機能が使用できない
よりセキュアな通信を確立するために、http/2は現在のTLSの一部機能を制限することで、セキュアなプロトコルとして現在は使用されています。今後http/2に対応した形の新しいTLS、もしくはそれに替わるものが出てくるかと思います。
制限される内容はこちら
- プロトコル選択にはNPNではなくALPNを使用
- サーバー認証を共有できる接続は接続共有が可能
- TLSプロトコルは1.2以上のみが使用可能
- TLS Compressionの禁止
- Renegotiationの禁止
- DH鍵は2048bit以上を使用
- AEAD(認証付き暗号)のうち、GCMとCCM以外の暗号方式は利用できない
NPN (Next Protocol Negotiation) からALPN (Applicaiton-Layer Protocol Negotiation) へ
http/2に先行して、NPN (Next Protocol Negotiation) はTLS false start方式の次の規格としてgoogleが提唱し、SPDYを支える次期アプリケーション層プロトコルネゴシエーションとして2010年ごろに登場しました。
背景的にはwebサイトの表示速度にはネットワークの回線速度よりもRTTの影響が大きく関わっており、TCP接続のハンドシェイクを毎回行うところに非効率さがあったと判断したのかと思います。
これに関しては2011年にAkamaiが行なった調査を簡単にまとめた2012年の記事があるので、下記の引用画像を見ていただくとwebサイトの表示速度がRTT依存というのがよりわかりやすいかと思います。
引用元: Latency: The New Web Performance Bottleneck - igvita.com
これまではNPNが使用されていましたが、今後の流れとしてはhttp/2での後押しもありALPNが一般的となりそうです。
NPNとALPNの簡単な違いは、サーバーとクライアントのどちらが使用するアプリケーションプロトコルの決定を行うかというところで、NPNではクライアント側によるプロトコルの選択が行われていましたが、ALPNではサーバー側がクライアントの使用できるアプリケーションプロトコルの中から使用するプロトコルを選択するという形になります。
ALPNを使用するにはOpenSSLのバージョン1.0.2以上が必要となりますが、サーバーのOSによっては最新のOpenSSLを入れてもALPNを使用できないこともあります。
CentOSでHTTP/2とALPNを使う
CentOSでhttp/2とALPNが使用できるのはCentOS 7 以上のバージョンとなります。
UbuntuでALPNを使う
Ubuntuでhttp/2とALPNを使用する場合は、今年リリースされた Ubuntu 16.04 LTS (Xenial) 以上のバージョンになります。
nginxでのhttp2を設定
現在、nginxでhttp/2を使うには、ngx_http_v2_moduleが必要となります。
再ビルドなどに関しては他にも記事があるので割愛しますが、 サーバーのOSとOpenSSLのバージョンがhttp/2に対応していれば、nginxで使用するのは非常に簡単かと思います。
最後の最後で、もはやおまけみたいな感じになってしまいますが、listenディレクティブにhttp2と入れるだけで、基本的には完了です。
server { listen 443 ssl http2; # ~~~~~ }
付け加えるとしたら、SSLのプロトコルの設定や、ssl_ciphersなどの設定などでしょうか。その辺りに関しましては、こちらの記事を流し読み程度にご参考にしていただけると嬉しいです。
googleはもちろんのこと、facebookやtwitterといった名だたるwebサービスで既にproductionへ導入されているhttp/2で、 徐々に様々なwebサービスで導入され始めていますが、本格的に普及するまではもうしばらく時間がかかりそうな気もします。
また進展があったら、記事にしたいと思います!
Cluexではエンジニアの方を探しています!