<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>BAKUNOTE</title>
  <subtitle>bakunyoの技術ノート</subtitle>
  <id>http://blog.bakunyo.com/</id>
  <link href="http://blog.bakunyo.com/"/>
  <link href="http://blog.bakunyo.com/feed.xml" rel="self"/>
  <updated>2017-12-17T13:30:00+09:00</updated>
  <author>
    <name>bakunyo</name>
  </author>
  <entry>
    <title>Amazpn VPCで踏み台経由でログインできるネットワーク環境をつくってみる</title>
    <link rel="alternate" href="http://blog.bakunyo.com/2017/12/17/amazon-vpc/"/>
    <id>http://blog.bakunyo.com/2017/12/17/amazon-vpc/</id>
    <published>2017-12-17T13:30:00+09:00</published>
    <updated>2017-12-17T15:42:01+09:00</updated>
    <author>
      <name>bakunyo</name>
    </author>
    <media:thumbnail url="http://blog.bakunyo.com/articles/2017/12/17-amazon-vpc/images/thumbnail.jpg"/>
    <content type="html">&lt;h1&gt;背景&lt;/h1&gt;

&lt;p&gt;個人開発で�使える�本番サーバー環境が欲しかったのと、ちょうど仕事でも活かせそうだったので、自分でAWSのネットワーク環境を作ってみました。&lt;/p&gt;

&lt;h1&gt;全体像&lt;/h1&gt;

&lt;p&gt;用意したいサーバーは2つです。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;踏み台

&lt;ul&gt;
&lt;li&gt;sshでログインし、さらにsshで本番サーバーへログインするためのもの&lt;/li&gt;
&lt;li&gt;ssh��ログイン用のport以外は開けない&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;�本番サーバー

&lt;ul&gt;
&lt;li&gt;踏み台サーバーからのみsshでログイン可能&lt;/li&gt;
&lt;li&gt;(Webサーバーを予定してるけど、�今回はhttpのportを開けたりとかしない)&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;VPCの作成&lt;/h1&gt;

&lt;p&gt;AWSで管理する仮想ネットワークを定義します。&lt;/p&gt;

&lt;h4&gt;AWSマネジメントコンソールからサービス＞VPCを選択&lt;/h4&gt;

&lt;p&gt;&lt;img src="/articles/2017/12/17-amazon-vpc/images/1-dashboard.png" alt="vpc-dashboard" /&gt;&lt;/p&gt;

&lt;p&gt;既にデフォルトのVPCが定義されていますが、今回は使わずに削除します。&lt;/p&gt;

&lt;h4&gt;「VPCの作成」を選択&lt;/h4&gt;

&lt;p&gt;&lt;img src="/articles/2017/12/17-amazon-vpc/images/2-create-vpc.png" alt="vpc-create" /&gt;&lt;/p&gt;

&lt;table&gt;&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left"&gt;&lt;/th&gt;
&lt;th style="text-align: left"&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Name&lt;/td&gt;
&lt;td style="text-align: left"&gt;vpc-sample&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;IPv4 CIDR ブロック&lt;/td&gt;
&lt;td style="text-align: left"&gt;192.168.0.0/16&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;CIDR ブロックは、仮想ネットワーク内のIPアドレスの範囲を指定します。&lt;br&gt;&lt;br&gt;
今回は &lt;code&gt;192.168.0.0&lt;/code&gt; ~ &lt;code&gt;192.168.255.255&lt;/code&gt; で 65,536 個のIPアドレスを持つことになります。&lt;br&gt;&lt;br&gt;
&lt;a href="http://docs.aws.amazon.com/ja_jp/AmazonVPC/latest/UserGuide/VPC_Subnets.html"&gt;VPC とサブネット&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;CIDRブロックは 16~28の間で指定する必要があるようです。&lt;/p&gt;

&lt;h1&gt;サブネットの作成&lt;/h1&gt;

&lt;p&gt;上で作成したVPCの中でネットワークを小分けにします。&lt;/p&gt;

&lt;h4&gt;VPCダッシュボードの中から「サブネット」を選択&lt;/h4&gt;

&lt;p&gt;&lt;img src="/articles/2017/12/17-amazon-vpc/images/3-subnet-dashboard.png" alt="subnet-dashboard" /&gt;&lt;br&gt;
「サブネットの作成」を選択し、以下2つのサブネットを作成しました。&lt;/p&gt;

&lt;h4&gt;1つ目&lt;/h4&gt;

&lt;table&gt;&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left"&gt;&lt;/th&gt;
&lt;th style="text-align: left"&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;名前タグ&lt;/td&gt;
&lt;td style="text-align: left"&gt;subnet-sample-public&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;VPC&lt;/td&gt;
&lt;td style="text-align: left"&gt;{作成�したvpc-sampleがデフォルトで選択されている}&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;アベイラビリティゾーン&lt;/td&gt;
&lt;td style="text-align: left"&gt;ap-northeast-1a&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;IPv4 CIDR ブロック&lt;/td&gt;
&lt;td style="text-align: left"&gt;192.168.1.0/24&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

&lt;h4&gt;2つ目&lt;/h4&gt;

&lt;table&gt;&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left"&gt;&lt;/th&gt;
&lt;th style="text-align: left"&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;名前タグ&lt;/td&gt;
&lt;td style="text-align: left"&gt;subnet-sample-private&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;VPC&lt;/td&gt;
&lt;td style="text-align: left"&gt;{作成�したvpc-sampleがデフォルトで選択されている}&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;アベイラビリティゾーン&lt;/td&gt;
&lt;td style="text-align: left"&gt;ap-northeast-1a&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;IPv4 CIDR ブロック&lt;/td&gt;
&lt;td style="text-align: left"&gt;192.168.2.0/24&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;1つ目が踏み台用、2つ目が本番用という想定です。&lt;br&gt;
それぞれ256個ずつIPアドレスを持つことになります。&lt;/p&gt;

&lt;p&gt;アベイラビリティゾーンは東京では &lt;code&gt;ap-northeact-1a&lt;/code&gt; &lt;code&gt;ap-northeast-1c&lt;/code&gt; の2択�ですが、どちらが具体的にどこの場所、というのはなく、仮想ネットワーク毎にAWS側で振り分けられるそうです。&lt;br&gt;
なので、 「 &lt;code&gt;1a&lt;/code&gt; は沢山�の人が選んで混んでそうだからa &lt;code&gt;1c&lt;/code&gt; にしよう」みたいなことは意味がないらしいです。&lt;br&gt;
�情報元は�どこかのネット記事で読んだのですがどこかへ行ってしまいました。。&lt;/p&gt;

&lt;h1&gt;インターネットゲートウェイの作成&lt;/h1&gt;

&lt;p&gt;仮想ネットワークをインターネットと繋げる為に、インターネットゲートウェイを作成します。&lt;br&gt;
VPCダッシュボードからインターネットゲートウェイ＞インターネットゲートウェイの作成を�選択&lt;br&gt;
&lt;img src="/articles/2017/12/17-amazon-vpc/images/10-create-igw.png" alt="create-igw" /&gt;&lt;br&gt;
名前は &lt;code&gt;igw-sample&lt;/code&gt; としておきます。&lt;/p&gt;

&lt;h1&gt;ルートテーブルの作成&lt;/h1&gt;

&lt;p&gt;��上で作成したインターネットゲートウェイを紐付けるためのルートテーブルを作成します。&lt;br&gt;
ルートテーブル＞ルートテーブルの作成を選択し、 &lt;code&gt;rtb-sample&lt;/code&gt; を指定します。&lt;br&gt;
作成後、 &lt;code&gt;0.0.0.0/0&lt;/code&gt; (デフォルトゲートウェイとして) インターネットゲートウェイを紐付けます。&lt;br&gt;
&lt;img src="/articles/2017/12/17-amazon-vpc/images/11-create-rtb.png" alt="create-rtb" /&gt;&lt;br&gt;
さらに、「サブネットの関連付け」で踏み台用のサブネットである &lt;code&gt;subnet-sample-public&lt;/code&gt; を紐付けます。&lt;/p&gt;

&lt;h1&gt;EC2（�踏み台）の作成&lt;/h1&gt;

&lt;p&gt;いよいよサーバーです。&lt;br&gt;
サービス＞EC2＞インスタンスから「インスタンスの作成」を選択&lt;br&gt;&lt;br&gt;
&lt;a href="https://aws.amazon.com/jp/blogs/news/amazon-linux-2-release/"&gt;ちょうど数日前にリリースされたAmazon Linux 2&lt;/a&gt; が無料枠で選べる状態だったので、これを選択します。&lt;/p&gt;

&lt;p&gt;&lt;img src="/articles/2017/12/17-amazon-vpc/images/5-create-ec2.png" alt="create-ec2-1" /&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;t2.micro&lt;/code&gt; を選択します。&lt;/p&gt;

&lt;p&gt;&lt;img src="/articles/2017/12/17-amazon-vpc/images/6-create-ec2.png" alt="create-ec2-2" /&gt;&lt;/p&gt;

&lt;p&gt;インスタンスの詳細設定です。&lt;br&gt;
&lt;img src="/articles/2017/12/17-amazon-vpc/images/7-create-ec2.png" alt="create-ec2-3" /&gt;&lt;/p&gt;

&lt;p&gt;ちょっと項目数が多いのでかいつまんで。&lt;/p&gt;

&lt;table&gt;&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left"&gt;&lt;/th&gt;
&lt;th style="text-align: left"&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;ネットワーク&lt;/td&gt;
&lt;td style="text-align: left"&gt;vpc-sample&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;サブネット&lt;/td&gt;
&lt;td style="text-align: left"&gt;subnet-sample-public&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;自動割り当てパブリックIP&lt;/td&gt;
&lt;td style="text-align: left"&gt;有効化&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;プライマリIP&lt;/td&gt;
&lt;td style="text-align: left"&gt;192.168.1.10&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;ここは若干ハマってしまった所なのですが、プライマリIPを &lt;code&gt;192.168.1.1&lt;/code&gt; に指定したら、最後のEC2作成のフェーズでエラーになってしまいました。&lt;br&gt;&lt;br&gt;
プライマリIPは先頭と末尾（&lt;code&gt;192.168.1.0&lt;/code&gt; &lt;code&gt;192.168.1.255&lt;/code&gt;）だけ避ければ良いと思っていたのですが、他にも &lt;code&gt;192.168.1.1&lt;/code&gt; &lt;code&gt;192.168.1.2&lt;/code&gt; &lt;code&gt;192.168.1.3&lt;/code&gt; は予約済アドレスとなるようです。&lt;br&gt;&lt;br&gt;
�プライマリIPはわざわざ指定しなくても良かったかもしれないです。&lt;/p&gt;

&lt;p&gt;参考： &lt;a href="http://blog.serverworks.co.jp/tech/2013/05/23/vpc_beginner-2/"&gt;VPC初心者がハマりやすいポイントをまとめてみた&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;次はストレージの追加です。&lt;br&gt;
&lt;img src="/articles/2017/12/17-amazon-vpc/images/8-create-ec2.png" alt="create-ec2-4" /&gt;&lt;br&gt;
デフォルトのまま進めます。&lt;br&gt;
&lt;img src="/articles/2017/12/17-amazon-vpc/images/8-create-tag.png" alt="create-ec2-5" /&gt;&lt;br&gt;
&lt;code&gt;Name&lt;/code&gt; タグに &lt;code&gt;bastion&lt;/code&gt; を指定します。&lt;/p&gt;

&lt;p&gt;&lt;img src="/articles/2017/12/17-amazon-vpc/images/9-create-ec2.png" alt="create-ec2-6" /&gt;&lt;br&gt;
&lt;img src="/articles/2017/12/17-amazon-vpc/images/9-create-sg.png" alt="create-ec2-7" /&gt;&lt;/p&gt;

&lt;p&gt;「新しいセキュリティグループを作成する」を選択し、セキュリティグループ名を &lt;code&gt;bastion-sg&lt;/code&gt; とします。&lt;br&gt;
セキュリティグループの指定で、sshで &lt;code&gt;22&lt;/code&gt; をどこからでも受けられるようにします。&lt;/p&gt;

&lt;p&gt;「確認と作成」をクリックして、キーペアを作成してダウンロードしたら完了です。&lt;/p&gt;

&lt;h1&gt;EC2(本番用)の作成&lt;/h1&gt;

&lt;p&gt;ほぼ踏み台と同じなので、違うところだけピックアップします。&lt;/p&gt;

&lt;h3&gt;詳細設定&lt;/h3&gt;

&lt;table&gt;&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left"&gt;&lt;/th&gt;
&lt;th style="text-align: left"&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;サブネット&lt;/td&gt;
&lt;td style="text-align: left"&gt;subnet-sample-private&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;自動割り当てパブリックIP&lt;/td&gt;
&lt;td style="text-align: left"&gt;サブネット設定を使用（無効）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;プライマリIP&lt;/td&gt;
&lt;td style="text-align: left"&gt;192.168.2.10&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

&lt;h3&gt;タグ&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Name&lt;/code&gt; タグに &lt;code&gt;webserver&lt;/code&gt; を指定します。&lt;/p&gt;

&lt;h3&gt;セキュリティグループ&lt;/h3&gt;

&lt;p&gt;「新しいセキュリティグループを作成する」を選択し、セキュリティグループ名を &lt;code&gt;web-sg&lt;/code&gt; とします。&lt;br&gt;
セキュリティグループの指定で、sshで &lt;code&gt;22&lt;/code&gt; を &lt;code&gt;192.168.1.0/24&lt;/code&gt; からのみ受けられるようにします。（ここポイントです）&lt;/p&gt;

&lt;h3&gt;キーペア&lt;/h3&gt;

&lt;p&gt;踏み台で作成したものと同じものを使うようにします。&lt;/p&gt;

&lt;h1&gt;sshログインしてみる&lt;/h1&gt;

&lt;p&gt;踏み台→本番への接続も同じキーペアで通せるように、以下のコマンドを打ちます。&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh-add &lt;span class="o"&gt;{&lt;/span&gt;pemファイルのパス&lt;span class="o"&gt;}&lt;/span&gt;
ssh-add -l &lt;span class="c"&gt;# 登録できたか確認&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;まずは踏み台のログインです。&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh -i &lt;span class="o"&gt;{&lt;/span&gt;pemファイルのパス&lt;span class="o"&gt;}&lt;/span&gt; ec2-user@&lt;span class="o"&gt;{&lt;/span&gt;踏み台に割当てられたパブリックIP&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ログインできたら、�本番に指定したプライベートIPを使ってさらにsshログインします。&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="gp"&gt;$ &lt;/span&gt;ssh �192.168.2.10 &lt;span class="c"&gt;# 本番用に指定したプライベートIP&lt;/span&gt;
Last login: Sun Dec 17 06:01:04 2017 from 192.168.1.10

       __|  __|_  &lt;span class="o"&gt;)&lt;/span&gt;
       _|  &lt;span class="o"&gt;(&lt;/span&gt;     /   Amazon Linux 2 AMI
      ___|&lt;span class="se"&gt;\_&lt;/span&gt;__|___|

https://aws.amazon.com/amazon-linux-2/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;これでログイン完了です！&lt;/p&gt;

&lt;h3&gt;ssh/configの設定&lt;/h3&gt;

&lt;p&gt;踏み台を通して1発で本番へログインできるようにするための設定です。&lt;br&gt;
&lt;code&gt;~/.ssh/config&lt;/code&gt; に記述します。&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Host &lt;span class="o"&gt;{&lt;/span&gt;踏み台用の好きな名前&lt;span class="o"&gt;}&lt;/span&gt;
  HostName &lt;span class="o"&gt;{&lt;/span&gt;踏み台パブリックIP&lt;span class="o"&gt;}&lt;/span&gt;
  User ec2-user
  IdentityFile &lt;span class="o"&gt;{&lt;/span&gt;pemファイルのパス&lt;span class="o"&gt;}&lt;/span&gt;

Host &lt;span class="o"&gt;{&lt;/span&gt;本番用の好きな名前&lt;span class="o"&gt;}&lt;/span&gt;
  HostName &lt;span class="o"&gt;{&lt;/span&gt;本番用プライベートIP&lt;span class="o"&gt;}&lt;/span&gt;
  User ec2-user
  IdentityFile &lt;span class="o"&gt;{&lt;/span&gt;pemファイルのパス&lt;span class="o"&gt;}&lt;/span&gt;
  ProxyCommand ssh &lt;span class="o"&gt;{&lt;/span&gt;踏み台用の好きな名前&lt;span class="o"&gt;}&lt;/span&gt; -W %h:%p
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上記を指定しておけば、 &lt;code&gt;ssh {本番用の好きな名前}&lt;/code&gt; でログインできます。&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Rails開発環境をdocker-composeで作ってみる</title>
    <link rel="alternate" href="http://blog.bakunyo.com/2017/07/06/docker-compose-rails/"/>
    <id>http://blog.bakunyo.com/2017/07/06/docker-compose-rails/</id>
    <published>2017-07-06T00:09:00+09:00</published>
    <updated>2017-07-07T02:05:21+09:00</updated>
    <author>
      <name>bakunyo</name>
    </author>
    <media:thumbnail url="http://blog.bakunyo.com/articles/2017/07/06-docker-compose-rails/images/thumbnail.jpg"/>
    <content type="html">&lt;p&gt;久々に &lt;code&gt;rails new&lt;/code&gt; したい欲求が高まったので、今風っぽく &lt;code&gt;docker-compose&lt;/code&gt; を使って開発環境をつくります。&lt;br&gt;
docker公式がドキュメントを用意してくれているので、まずはそれで感覚を掴んでみます。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.docker.com/compose/rails/"&gt;Quickstart: Compose and Rails&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;OSはMac(Sierra)です。手元にあったdockerも少し古くなっていたので、アップグレードしつつ進めます。&lt;/p&gt;

&lt;h1&gt;1. Docker環境の準備&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://docs.docker.com/docker-for-mac/install/"&gt;Install Docker for Mac&lt;/a&gt; からStable版のDockerをダウンロード・インストールします。&lt;br&gt;
元々&lt;strong&gt;Docker Toolbox&lt;/strong&gt;をインストールしていましたが、&lt;strong&gt;Docker for Mac&lt;/strong&gt;のインストーラーがよしなに差し替えたり調整してくれました。&lt;/p&gt;

&lt;p&gt;詳しくは以下です。&lt;br&gt;
&lt;a href="https://docs.docker.com/docker-for-mac/docker-toolbox/"&gt;Docker for Mac vs. Docker Toolbox&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;インストール後のバージョン確認&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="gp"&gt;$ &lt;/span&gt;docker version
Client:
 Version:      17.06.0-ce
 API version:  1.30
 Go version:   go1.8.3
 Git commit:   02c1d87
 Built:        Fri Jun 23 21:31:53 2017
 OS/Arch:      darwin/amd64

Server:
 Version:      17.06.0-ce
 API version:  1.30 &lt;span class="o"&gt;(&lt;/span&gt;minimum version 1.12&lt;span class="o"&gt;)&lt;/span&gt;
 Go version:   go1.8.3
 Git commit:   02c1d87
 Built:        Fri Jun 23 21:51:55 2017
 OS/Arch:      linux/amd64
 Experimental: &lt;span class="nb"&gt;true&lt;/span&gt;

&lt;span class="o"&gt;[&lt;/span&gt;bakunyo@wasta 01:04:10] ~
&lt;span class="gp"&gt;$ &lt;/span&gt;docker --version
Docker version 17.06.0-ce, build 02c1d87
&lt;span class="o"&gt;[&lt;/span&gt;bakunyo@wasta 01:04:14] ~
&lt;span class="gp"&gt;$ &lt;/span&gt;docker-compose --version
docker-compose version 1.14.0, build c7bdf9e
&lt;span class="o"&gt;[&lt;/span&gt;bakunyo@wasta 01:04:18] ~
&lt;span class="gp"&gt;$ &lt;/span&gt;docker-machine --version
docker-machine version 0.12.0, build 45c69ad
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;2. プロジェクトの定義&lt;/h1&gt;

&lt;p&gt;以下の4ファイルを作成します。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dockerfile&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; ruby:2.3.3&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;apt-get update -qq &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get install -y build-essential libpq-dev nodejs
&lt;span class="k"&gt;RUN &lt;/span&gt;mkdir /myapp
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /myapp&lt;/span&gt;
&lt;span class="k"&gt;ADD&lt;/span&gt;&lt;span class="s"&gt; Gemfile /myapp/Gemfile&lt;/span&gt;
&lt;span class="k"&gt;ADD&lt;/span&gt;&lt;span class="s"&gt; Gemfile.lock /myapp/Gemfile.lock&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;bundle install
&lt;span class="k"&gt;ADD&lt;/span&gt;&lt;span class="s"&gt; . /myapp&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gemfile&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="s1"&gt;'https://rubygems.org'&lt;/span&gt;
&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;'rails'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'5.0.0.1'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gemfile.lock&lt;/strong&gt;&lt;br&gt;
空でOK&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;docker-compose.yml&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3'&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;db&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
  &lt;span class="na"&gt;web&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bundle exec rails s -p 3000 -b '0.0.0.0'&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;.:/myapp&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3000:3000"&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;db&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;3. プロジェクトのビルド&lt;/h1&gt;

&lt;p&gt;ここからいよいよ &lt;code&gt;docker-compose&lt;/code&gt; コマンドを使うので、軽く中身を確認しておきます。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.docker.com/compose/reference/run/"&gt;docker-compose run&lt;/a&gt;&lt;br&gt;
&lt;a href="https://docs.docker.com/compose/reference/up/"&gt;docker-compose up&lt;/a&gt;&lt;br&gt;
&lt;a href="https://docs.docker.com/compose/reference/build/"&gt;docker-compose build&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker-compose.yml&lt;/code&gt; には複数のサービスが定義されていて、 &lt;code&gt;run&lt;/code&gt; は特定のサービス、 &lt;code&gt;up&lt;/code&gt; は全サービス(特定も可)に対する命令です。どちらも、コンテナが create &amp;amp; start されます。&lt;br&gt;
また、 &lt;code&gt;run&lt;/code&gt; は指定したサービス上で実行するコマンドを渡すことができ、 &lt;code&gt;docker-compose.yml&lt;/code&gt; に書いてある &lt;code&gt;command&lt;/code&gt; を上書きするみたいですね。&lt;/p&gt;

&lt;p&gt;簡単ですが以上を踏まえて、以下のコマンドを実行した後の流れを見ていきます。&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="gp"&gt;$ &lt;/span&gt;docker-compose run web rails new . --force --database&lt;span class="o"&gt;=&lt;/span&gt;postgresql
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;流れの確認&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;デフォルトネットワークを生成&lt;/li&gt;
&lt;li&gt;&lt;code&gt;run web&lt;/code&gt; なのでサービス[web]の起動が始まる&lt;/li&gt;
&lt;li&gt;&lt;code&gt;depend_on: db&lt;/code&gt; となっている為、サービス[db]を先に起動する

&lt;ul&gt;
&lt;li&gt;postgresのimageをpull &amp;amp; dbサービス用のネットワークを生成&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;build: .&lt;/code&gt; なので &lt;code&gt;Dockerfile&lt;/code&gt; を�元にコンテナを生成する

&lt;ul&gt;
&lt;li&gt;ruby:2.3.3 からimageをpull&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RUN apt-get update -qq &amp;amp;&amp;amp; apt-get install -y build-essential libpq-dev nodejs&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;必要なライブラリのインストール&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RUN mkdir /myapp&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;WORKDIR /myapp&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ADD Gemfile /myapp/Gemfile&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ADD Gemfile.lock /myapp/Gemfile.lock&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RUN bundle install&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;WORKDIRを指定しているので、 &lt;code&gt;/myapp/Gemfile&lt;/code&gt; を元にインストールが始まる&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ADD . /myapp&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;docker-compose run&lt;/code&gt; の引数に渡しているコマンドが実行される(override)

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;rails new . --force --database=postgresql&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;コマンドが上書きされているので、 &lt;code&gt;rails s&lt;/code&gt; は実行されない&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--force&lt;/code&gt; オプションで、 &lt;code&gt;Gemfile&lt;/code&gt; が上書きされる&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;4. 再ビルド&lt;/h1&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="gp"&gt;$ &lt;/span&gt;docker-compose build
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Gemfileが書き換わったので、imageを再ビルドします。&lt;br&gt;
&lt;code&gt;rails new&lt;/code&gt; のとき &lt;code&gt;--skip-bundle&lt;/code&gt; しても良さそうですね。&lt;/p&gt;

&lt;h1&gt;5. DB設定&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;config/database.yml&lt;/code&gt; を以下に書き換え&lt;/p&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nl"&gt;&amp;amp;default&lt;/span&gt;
  &lt;span class="na"&gt;adapter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgresql&lt;/span&gt;
  &lt;span class="na"&gt;encoding&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unicode&lt;/span&gt;
  &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;db&lt;/span&gt;
  &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
  &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;pool&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;5&lt;/span&gt;

&lt;span class="na"&gt;development&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="s"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;*default&lt;/span&gt;
  &lt;span class="na"&gt;database&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myapp_development&lt;/span&gt;


&lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="s"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;*default&lt;/span&gt;
  &lt;span class="na"&gt;database&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myapp_test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;host: db&lt;/code&gt; で接続できるということですね。�便利！&lt;/p&gt;

&lt;h1&gt;6. サーバー起動&lt;/h1&gt;

&lt;p&gt;サービスを起動します。&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="gp"&gt;$ &lt;/span&gt;docker-compose up
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;別のターミナルを開き、以下を実行します。&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="gp"&gt;$ &lt;/span&gt;docker-compose run web rake db:create
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;br&gt;
&lt;a href="http://localhost:3000"&gt;http://localhost:3000&lt;/a&gt; にアクセスします。&lt;/p&gt;

&lt;p&gt;&lt;img src="/articles/2017/07/06-docker-compose-rails/images/rails_welcome.png" alt="rails welcome" /&gt;&lt;/p&gt;

&lt;p&gt;ちゃんと�起動していました！&lt;br&gt;
Docker環境さえあれば、たった数ファイルでここまで構築できるってすごいですね。&lt;br&gt;
大体の流れは掴めたので、これをベースに自分用にカスタマイズしていこうと思います。&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Elixir入門</title>
    <link rel="alternate" href="http://blog.bakunyo.com/2017/05/27/elixir-introduction/"/>
    <id>http://blog.bakunyo.com/2017/05/27/elixir-introduction/</id>
    <published>2017-05-27T17:01:00+09:00</published>
    <updated>2017-07-02T18:52:35+09:00</updated>
    <author>
      <name>bakunyo</name>
    </author>
    <media:thumbnail url="http://blog.bakunyo.com/images/default_thumbnail.jpg"/>
    <content type="html">&lt;p&gt;2017/06/02 に行われた &lt;a href="https://beam-lang.connpass.com/event/51637/"&gt;Elixir入門者LT大会&lt;/a&gt; へ参加する際、事前に準備しておいたことのメモ。&lt;/p&gt;

&lt;h2&gt;Elixirとは？&lt;/h2&gt;

&lt;h4&gt;公式サイト&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://elixir-lang.org/"&gt;https://elixir-lang.org/&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;スケーラブルで持続可能なアプリを作るためにデザインされた動的関数型言語&lt;/li&gt;
&lt;li&gt;Erlang VM上で動いている。

&lt;ul&gt;
&lt;li&gt;Erlang VMは、レイテンシが低く、配布可能で耐障害性もあり、Webでも組み込みシステムでも利用されている&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;特徴

&lt;ul&gt;
&lt;li&gt;関数型&lt;/li&gt;
&lt;li&gt;拡張可能なDSL&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;その他の特徴

&lt;ul&gt;
&lt;li&gt;Ecosystem(mix)&lt;/li&gt;
&lt;li&gt;Interactive Development&lt;/li&gt;
&lt;li&gt;Erlang互換&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;インストール&lt;/h2&gt;

&lt;p&gt;Macの場合&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew update
brew install elixir
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="https://elixir-lang.org/install.html"&gt;その他の場合&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;基本&lt;/h2&gt;

&lt;p&gt;Elixir Schoolより&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;iex&lt;/code&gt; でREPLを起動&lt;/li&gt;
&lt;li&gt;真偽判定: &lt;code&gt;false&lt;/code&gt; と &lt;code&gt;nil&lt;/code&gt; 以外は真&lt;/li&gt;
&lt;li&gt;アトム &lt;code&gt;:foo&lt;/code&gt; はRubyのシンボルと同じ&lt;/li&gt;
&lt;li&gt;&lt;code&gt;true === :true&lt;/code&gt; は真&lt;/li&gt;
&lt;li&gt;モジュール名もアトム。宣言されていなくても。 &lt;code&gt;is_atom(MyApp)&lt;/code&gt; は真&lt;/li&gt;
&lt;li&gt;アトムは、Erlangのビルトインも含めたモジュール参照にも使われる。 &lt;code&gt;:crypto.rand_bytes 3&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;どんな型同士も比較可能、ソート可能&lt;/li&gt;
&lt;li&gt;文字の連結は &lt;code&gt;&amp;quot;Hello, &amp;quot; &amp;lt;&amp;gt; &amp;quot;Elixir&amp;quot;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;参考&lt;/h2&gt;

&lt;p&gt;公式サイト&lt;br&gt;
&lt;a href="https://elixir-lang.org/"&gt;https://elixir-lang.org/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Elixir School(日本語あり)&lt;br&gt;
&lt;a href="https://elixirschool.com"&gt;https://elixirschool.com&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;イベントに参加した時のメモ&lt;/h2&gt;

&lt;h3&gt;guest1 @ohrdev おーはらさん&lt;/h3&gt;

&lt;h4&gt;なぜElixir&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;可用性◯&lt;/li&gt;
&lt;li&gt;&lt;p&gt;速度× =&amp;gt; C, golangの方が&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;今持っていない考え方が身につく？&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;アクターモデル&lt;/li&gt;
&lt;li&gt;関数プログラミング、マクロ、プロトコル&lt;/li&gt;
&lt;li&gt;並行プログラミング、OTP&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;適当な問題&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;並列処理が効くツール&lt;/li&gt;
&lt;li&gt;クローラー&lt;/li&gt;
&lt;li&gt;chat, mastodon cloneとか？&lt;/li&gt;
&lt;li&gt;ライブラリ制作&lt;/li&gt;
&lt;li&gt;マクロを使う必要がある(メタプログラミング)&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;guest2 さっちゃん&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;phoenix new しとけばRailsみたく開発できる。Webはだいたいいける&lt;/li&gt;
&lt;li&gt;dockerで環境をつくって、環境差異をなくした&lt;/li&gt;
&lt;li&gt;lint: 開発の最初から入れる必要がある

&lt;ul&gt;
&lt;li&gt;dogma, credoの2つがある(credoの方が盛ん)&lt;/li&gt;
&lt;li&gt;dialyzer: flowtypeみたく型を指定できる&lt;/li&gt;
&lt;li&gt;但し、めちゃくちゃ遅い(最初に型情報のDBを生成する)&lt;/li&gt;
&lt;li&gt;test: ExUnit&lt;/li&gt;
&lt;li&gt;関数合成だけで構築できると信じるとテストが書きやすくなる&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;awesome-elixer

&lt;ul&gt;
&lt;li&gt;ライブラリの選定に有用&lt;/li&gt;
&lt;li&gt;elixir公式MLでも情報とれる&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;別の言語で学ぶ

&lt;ul&gt;
&lt;li&gt;Haskell, Lisp, Scala&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;プロセスの役割

&lt;ul&gt;
&lt;li&gt;タスクを分割する&lt;/li&gt;
&lt;li&gt;状態を持つ&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;LT&lt;/h3&gt;

&lt;h4&gt;@color_box&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;とりあえず HexDoc&lt;/li&gt;
&lt;li&gt;erlang ライブラリ多い&lt;/li&gt;
&lt;li&gt;REPL環境が良い&lt;/li&gt;
&lt;li&gt;&lt;p&gt;iex -S mix でライブラリも参照できる&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;パターンマッチの重要性&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;case&lt;/li&gt;
&lt;li&gt;関数のシグネチャ
-&amp;gt; 関数が小さくなるので、読みやすくなる&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;@cedretaber&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Bibliotheca 蔵書管理アプリ&lt;/li&gt;
&lt;li&gt;認証ライブラリを作った&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;@nunulk&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;ElixirでSlack botをつくっている&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;@yasuhiroki&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;シェル芸との共通点から好きになる&lt;/li&gt;
&lt;/ul&gt;
</content>
  </entry>
  <entry>
    <title>Web Pushを試してみる</title>
    <link rel="alternate" href="http://blog.bakunyo.com/2017/03/25/push-notification/"/>
    <id>http://blog.bakunyo.com/2017/03/25/push-notification/</id>
    <published>2017-03-25T01:08:00+09:00</published>
    <updated>2017-04-08T16:08:12+09:00</updated>
    <author>
      <name>bakunyo</name>
    </author>
    <media:thumbnail url="http://blog.bakunyo.com/images/default_thumbnail.jpg"/>
    <content type="html">&lt;h1&gt;デモ用&lt;/h1&gt;

&lt;h2&gt;Notification API&lt;/h2&gt;

&lt;p&gt;&lt;button type="buttun" class="button warning" id="notify_test"&gt;通知テスト&lt;/button&gt;&lt;br&gt;
&lt;button type="buttun" class="button warning" id="notify_override"&gt;通知テスト(上書き)&lt;/button&gt;&lt;/p&gt;

&lt;h2&gt;ServiceWorker&lt;/h2&gt;

&lt;p&gt;&lt;button type="buttun" class="button success" id="regist_sw"&gt;通知テスト（ServiceWorkerRegistration）&lt;/button&gt;&lt;/p&gt;

&lt;script&gt;
if('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/javascripts/serviceWorker.js')
  if(Notification &amp;&amp; Notification.permission === 'default') {
    Notification.requestPermission()
  }
}

function notify(title, option) {
  if('Notification' in window) {
    if(Notification.permission === 'granted') {
      new Notification(title, option);
    } else if(Notification.permission !== 'denied') {
      Notification.requestPermission(function(permission) {
        if(permission === 'granted') {
          new Notification(title, option);
        }
      });
    }
  } else {
    alert('このブラウザはNotification APIをサポートしていません');
  }
}

$('#notify_test').click(function() {
  notify('通知テスト', {
    body: 'テストメッセージ（数秒で消えます）',
    icon: '/images/bakunyo.png'
  });
});

$('#notify_override').click(function() {
  var time = new Date().toLocaleString()
  notify('通知テスト(上書き)', {
    body: 'このメッセージは上書きされます\r\nクリック時刻：' + time,
    tag: 'override',
    icon: '/images/bakunyo.png'
  });
});

$('#regist_sw').click(function() {
  if('serviceWorker' in navigator) {
    if(!(Notification &amp;&amp; self.Notification.permission === 'granted')) {
        return;
    }

    navigator.serviceWorker.register('/javascripts/serviceWorker.js').then(function(registration) {
      registration.showNotification('ServiceWorkerからの通知', {
        body: 'Notification from ServiceWorker',
        icon: '/images/bakunyo.png',
        vibrate: [200, 100],
        data: {
          url: location.pathname
        }
      });
    }).catch(function(err) {
      console.log('ServiceWorker registration failed: ', err);
    });
  }
});

&lt;/script&gt;
</content>
  </entry>
  <entry>
    <title>鎌倉で開発合宿してきた</title>
    <link rel="alternate" href="http://blog.bakunyo.com/2017/02/14/kamakura-kaihatsu-gassyuku/"/>
    <id>http://blog.bakunyo.com/2017/02/14/kamakura-kaihatsu-gassyuku/</id>
    <published>2017-02-14T21:40:00+09:00</published>
    <updated>2017-03-25T12:19:39+09:00</updated>
    <author>
      <name>bakunyo</name>
    </author>
    <media:thumbnail url="http://blog.bakunyo.com/articles/2017/02/14-kamakura-kaihatsu-gassyuku/images/thumbnail.png"/>
    <content type="html">&lt;p&gt;2017年2月10日〜12日の間、鎌倉（由比ヶ浜）で開発合宿をしてきました。&lt;br&gt;
泊まった場所は以下です。&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.ikyu.com/vacation/00050003/"&gt;光と水の邸宅&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;広いしきれいだし、とても使いやすかったので開発合宿にオススメです！&lt;/p&gt;

&lt;h2&gt;発表資料&lt;/h2&gt;

&lt;script async class="speakerdeck-embed" data-id="3e5ab470ef564b02b22c545fbdbab89a" data-ratio="1.33333333333333" src="//speakerdeck.com/assets/embed.js"&gt;&lt;/script&gt;

&lt;h2&gt;感想&lt;/h2&gt;

&lt;p&gt;事前準備があまりできず、いい感じのアウトプットが出なかったのが心残りです。&lt;br&gt;
だいたい晴れていたのですが突然雪が降ったり、何だか変な天気でした。&lt;/p&gt;

&lt;p&gt;OSSコミッターになるネタのために作った&lt;a href="https://github.com/tensorflow/tensorflow/pull/7441"&gt;PR&lt;/a&gt;は無事マージされてました。笑&lt;/p&gt;

&lt;p&gt;由比ヶ浜の海岸。&lt;br&gt;
ここには写っていませんが、2月なのにサーファーが沢山いました。&lt;br&gt;
寒いのに・・・&lt;br&gt;
&lt;img src="/articles/2017/02/14-kamakura-kaihatsu-gassyuku/images/ocean.jpg" alt="ocean" /&gt;&lt;/p&gt;

&lt;p&gt;2日目の昼。&lt;br&gt;
ずっと引きこもっていたので、空を見て気持ち良くなる大人たち&lt;br&gt;
&lt;img src="/articles/2017/02/14-kamakura-kaihatsu-gassyuku/images/sky.jpg" alt="sky" /&gt;&lt;/p&gt;

&lt;p&gt;帰りがけ、鶴岡八幡宮に寄っていきました。&lt;br&gt;
&lt;img src="/articles/2017/02/14-kamakura-kaihatsu-gassyuku/images/thumbnail.png" alt="tsurugaoka" /&gt;&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Deviseでフレンドリーフォワーディングを実装する</title>
    <link rel="alternate" href="http://blog.bakunyo.com/2016/12/30/devise-friendly-forwarding/"/>
    <id>http://blog.bakunyo.com/2016/12/30/devise-friendly-forwarding/</id>
    <published>2016-12-30T16:34:00+09:00</published>
    <updated>2017-03-25T12:19:39+09:00</updated>
    <author>
      <name>bakunyo</name>
    </author>
    <media:thumbnail url="http://blog.bakunyo.com/articles/2016/12/30-devise-friendly-forwarding/images/thumbnail.png"/>
    <content type="html">&lt;p&gt;&lt;img src="/articles/2016/12/30-devise-friendly-forwarding/images/thumbnail.png" alt="thumbnail" /&gt;&lt;/p&gt;

&lt;h2&gt;前置き&lt;/h2&gt;

&lt;p&gt;Railsでの認証に &lt;a href="https://github.com/plataformatec/devise"&gt;Devise&lt;/a&gt; を使っている人は多いと思います。&lt;br&gt;
ただ、 Devise はデフォルトでは&lt;strong&gt;フレンドリーフォワーディング&lt;/strong&gt;が効いていません。&lt;/p&gt;

&lt;p&gt;フレンドリーフォワーディングとは、ユーザーが認証前に開こうとしていたページへ、認証後にリダイレクトさせることです。&lt;br&gt;
参考： &lt;a href="http://railstutorial.jp/chapters/updating_and_deleting_users?version=4.2#sec-friendly_forwarding"&gt;Rails チュートリアル&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;最近機会があったので、&lt;a href="https://github.com/plataformatec/devise/wiki/How-To:-Redirect-back-to-current-page-after-sign-in,-sign-out,-sign-up,-update"&gt;DeviseのHow To&lt;/a&gt;を参考に実装しました。&lt;br&gt;
その際にやったことを残しておきます。&lt;/p&gt;

&lt;p&gt;なお、各バージョンは以下の通りです。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ruby 2.3.1&lt;/li&gt;
&lt;li&gt;Rails 4.2.7.1&lt;/li&gt;
&lt;li&gt;Devise 3.5.1&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;手順&lt;/h2&gt;

&lt;h3&gt;アクセスされたURLを保存する&lt;/h3&gt;

&lt;p&gt;認証前にアクセスしようとしたページをセッションに保存します。&lt;br&gt;
&lt;code&gt;current_user&lt;/code&gt; が取得できれば認証できているので、その場合は除外しています。&lt;br&gt;
また、 &lt;code&gt;devise_controller&lt;/code&gt; の各アクションの場合も除外しています。&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# app/controllers/application_controller.rb&lt;/span&gt;

&lt;span class="n"&gt;before_action&lt;/span&gt; &lt;span class="ss"&gt;:store_current_location&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;unless: :devise_controller?&lt;/span&gt;

&lt;span class="kp"&gt;private&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;store_current_location&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;current_user&lt;/span&gt;
  &lt;span class="n"&gt;store_location_for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;store_location_for&lt;/code&gt; を呼ぶと、&lt;code&gt;session[:user_return_to]&lt;/code&gt; にURLを保存してくれます。&lt;br&gt;
&lt;code&gt;:user&lt;/code&gt; の部分は認証のscopeです。大抵の場合は &lt;code&gt;:user&lt;/code&gt; でOKかと思います。&lt;/p&gt;

&lt;p&gt;実は、フレンドリーフォワーディングの実装としてはこれだけで完了です。&lt;br&gt;
&lt;code&gt;session[:user_return_to]&lt;/code&gt; にURLが入っていると、認証後にリダイレクトしてくれるようです。&lt;/p&gt;

&lt;p&gt;ただ、セキュリティ対策として以下の場合は追加の対応が必要です。&lt;/p&gt;

&lt;h3&gt;認証後にセッションをリセットする場合&lt;/h3&gt;

&lt;p&gt;&lt;a href="http://railsguides.jp/"&gt;Rails ガイド&lt;/a&gt; のセキュリティのページで、&lt;a href="http://railsguides.jp/security.html#%E3%82%BB%E3%83%83%E3%82%B7%E3%83%A7%E3%83%B3%E5%9B%BA%E5%AE%9A%E6%94%BB%E6%92%83-%E5%AF%BE%E5%BF%9C%E7%AD%96"&gt;セッション固定攻撃の対応策&lt;/a&gt; について紹介されています。&lt;br&gt;
ログイン認証の際に、 &lt;code&gt;reset_session&lt;/code&gt; を行なうというものです。&lt;br&gt;
これを行なうと、当然上で保存したURLも消えてしまうので、その値だけ別途引き継ぐ対応を行ないます。&lt;/p&gt;

&lt;h3&gt;&lt;code&gt;user_return_to&lt;/code&gt; を引き継ぐ&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Devise::SessionsController&lt;/code&gt; を継承したControllerで以下の対応をします。&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# app/controllers/sessions_controller.rb&lt;/span&gt;

&lt;span class="n"&gt;before_action&lt;/span&gt; &lt;span class="ss"&gt;:reset_session_before_login&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;only: :create&lt;/span&gt;

&lt;span class="kp"&gt;private&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;reset_session_before_login&lt;/span&gt;
  &lt;span class="n"&gt;user_return_to&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:user_return_to&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="n"&gt;reset_session&lt;/span&gt;

  &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:user_return_to&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user_return_to&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;user_return_to&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;これで、認証時の &lt;code&gt;reset_session&lt;/code&gt; をしつつフレンドリーフォワーディングをすることが可能になりました。&lt;/p&gt;
</content>
  </entry>
</feed>
