読者です 読者をやめる 読者になる 読者になる

Goldstine研究所

mosuke5's tech blog

ブログ移転しました。5秒後にリダイレクトします。

社内システム開発からパブリッククラウドの会社へジョインします

本日、2016年7月29日をもって、新卒から3年4ヶ月働いてきた部署が最後となり、8月1日から異動(出向)する。
社内転職制度を使って、自らの希望でパブリッククラウド事業の会社へジョインすることになった。
(新規事業を行う部署へ異動となり、そこから別会社へ出向という扱い)
グループ内の異動ではあるが、違う会社・事業で、職種も変わるので、今の部署でやってきたことをまとめて残しておこうと思う。

私は通信会社のネットワーク運用部隊に所属している(いた)。
ネットワーク運用部隊なのだが、私の部署はネットワーク運用を自動化したり運用を楽にするためのシステム開発を担うところで、下記のような仕事をしてきた。

1. ベンダーコントロールという仕事

システム開発にはうちでは外注物も内製物(後述)もある。
業務の都合上、システムの種類によってはSIベンダーへ発注をして作ることがあった。
ベンダーコントロールなんて言ったりするが、発注でのシステム開発の業務では下記のようなことをしてきた。

  • 要求仕様の検討
  • 見積もり依頼と価格交渉
  • 発注、スケジュール調整
  • 社内での業務調整
  • 受入試験、検収
  • 運用

仕事のほとんどは、社内外の人との調整(コミュニケーション)だ。
エンジニアとしては一見つまらなそうな仕事にみえるかもしれない。
しかし、この仕事から様々なコミュニケーションを学び、それはいろんな場面で役に立っている。
例えばだが、以下の様なコミュニケーションがあったりした。

  • 要求を他者にしっかり、わかりやすく伝える
  • 仕様や価格についての折衝をする
  • システムの利用部門との業務調整をする
  • 作業の手順について精査し指摘する
  • ミスなど良くないことが起きた際には、今後の対策はどうするか相手側に考えさせるよう導く
  • 場合によっては厳しく叱ることもする(感情的に怒るわけではない)

特に価格の折衝などは、SIerや購買部と激しく激突することもあり今でもとても印象に残っている。
こういった業務はビジネスマンとしてとても大事なことを学んだと思うし、内製での開発業務でもとても活きてきている。

外注はいいけど・・・

社内リソースが少なくても同時並行でいろんなシステムの開発ができるし外注はいい。
一方で外注開発について、もどかしさや非効率さなどもたくさん経験してきた。

まず、なにをやるにもお金と時間がかかることだ。
一度納品されてしまったものについて、なんらかの改修をしたい場合、
その改修規模を問わず、見積もり→発注→開発・改修→納品のプロセスを通さなければならない。
if文を1行追加するだけだろ…って思うようなものでも数百万で数週間かかることだってあった。

そして、プロセスの効率化が難しいことだ。
ベンダーが開発したシステムをリリースするには、発注側の会社に度々きてリリース作業を行う。
勝手に発注側のシステムをアップデートすることはありえないので、必ずリリース作業には社員が立ち会わなければいけない。
そのとき、リリース作業が自動化されていないことも多く(発注時の要求によってもちろん異なる)、
何時間もかけて数十台のサーバにデプロイしたりしなければいけなかったりするので大変だ。

これは当たり前だがとても効率が悪いし時間の無駄だ。
だがこれを改善しようと思うとまたお金がかかるわけである。
扱っているシステムが、業務システムなのでアップデートの頻度がおおくないこともあるので、
はじめからデプロイの自動化などを要件にいれることは少ないのである。

これらはSIの開発をディスっているわけではない。(要求も悪いのはわかる。)
これは仕方ないこととして、そのメリット・デメリットをきちんと理解した上で選択、要求をしなれけばいけないということだ。

2. 内製開発の仕事

外注開発とは別にシステムの内製での開発業務も多くおこなってきた。
社内的には外注開発から内製開発に徐々に切り替えの最中であった。
ちなみに開発言語はRubyRailsやPadrino)やPHPFuelPHP)なんか使っていた。

業務システムの他にもメールサーバやリバースプロキシサーバなど基盤システムも構築してきた。
2015年の振り返りブログに雑だが少し書いていた。

mosuke5.hateblo.jp

開発組織の改善活動

また、開発組織を改善するための活動をおおく行ってきた。
どこの組織でもある問題だと思うが、うちもまた「属人化」「秘伝のタレ」などといった類の悩みをたくさん抱えていた。

うちはソフトウェア企業ではないし、システムを外注で作る部署も多い。
そのため、新卒や異動してくる人などがソフトウェアエンジニア思考の人ばかりではない。というかむしろ少数派。
だからこそ、よりいっそう「属人化」「秘伝のタレ」が弊害となる。
わかりやすいところでいうと下記のようなことをやったりして開発組織の改善をしてきた。

  • gitlabを使ったgithub-flowの導入。レビュー必須化
  • Ansibleを使ったインフラ環境のコード化、構築自動化
  • またそういったツールの導入だけでなく講師としてワークショップの実施やサポート活動
  • 部署内の開発ルールの策定
  • 最低限身につけてほしいスキルや知識を習得できる環境や研修の準備

ツールの導入や普及、組織改善活動について次の2つがとても重要だったと思う。

  1. キーパーソンを見方につける。
  2. ハンズオンを行う。サポートを手厚くする。

どんなにいい試みをやっても、独断で行ってしまうと「勝手にやったことだよね?」ってやっぱり思われてしまう。
また、その試みを広めるのに苦労する。
試みに対して理解してくれる上の人、キーパーソンを見方につけて働くことがとても有効的だった。

そして、ツール類はとくにそうだが、紹介したりするだけじゃなくて、
ハンズオン会をやったりサポートをし「軌道にのせる」ところまでやったのがとてもよかった。
サポートがないと、気が付くと昔のやりかたにもどってしまっていた、なんてこともあった。

3. データセンター、ネットワークの仕事

データセンター系

サーバ環境はオンプレだった。
また、専任のサーバ・インフラ管理者がいるわけではなかったので、
データセンターへのサーバラックの立架工事やサーバラッキング、配線などそういったことも業務の1つだった。
データセンタ系業務とそれで身につけたことなどは下記。

  • データセンターへのサーバラックの立架工事やサーバラッキング、配線をやった
    • ラックの立架工事や電源工事は当たり前だが外注
    • 工事の監督はさんざんやった
    • サーバのラッキングやLANケーブルの敷設は自前でもたくさんやった
    • LANケーブル作るのはだいぶこなれた
    • でもやっぱりプロの配線は神
  • 安全に工事するための知恵をたくさん身につけた
  • 電源工事などに備え、電気的な知識を身につけた
  • openstack(プライベートクラウド)の検証などもした
ネットワーク系

バックボーンのネットワークは範囲外ではあるが、
システム内のネットワーク設計・構築・運用は自分たちの仕事だった。

そういう組織体系が業務的によかったかどうかはわからないけど、
現代では特に触れる機会が少ないネットワークについて理解を深められたのはとてもプラスになっている。
下記あたりは自前でやってきた。

  • システム内のネットワークの設計
  • L2スイッチ、L3スイッチの設定
    • VLANとかNAT、ACLとか
  • NW機器が故障した際の交換とか設定投入

ネットワークは専門ではないけれど、オンプレでやっているとネットワーク系の仕事をやることや、
他部署とネットワークの話をしなければいけないことが多い。
ネットワークの知識は仮想サーバを構築するときなどにも役に立つし、ソフトウェア開発でも何かと役に立っている。
ちょうど最近、システムが調子悪い原因が光ファイバーの不良ということを発見できてとてもスッキリした。

4. その他

その他にあったことを雑にまとめる

  • たくさん出張にいった
    • 大阪、北陸、名古屋、広島、四国など
  • 社内での業務改善コンテストで賞をとった
  • 新卒の面倒をみたりした
  • インターン生も毎年きて面倒をみた
  • 採用リクルータをやって就活生とたくさん出会った
  • マリオカート大会企画した
  • 勤務地が変更になったりした

最後に

ほんとうに多岐にわたる仕事をさせてもらい、視野が広がった3年間だった。
アプリケーション開発しか知らなかった学生時代を振り返ると驚くほどの成長をしたと思う。

部署や上司、メンバーへ、本当に感謝です(^人^)

次は、パブリッククラウドの会社に行く。
パブリッククラウドを構築し運用するところなので、AWSGCPが敵…)

会社ではオンプレを使っていたし、またプライベートクラウドの構築の検証にも携わった。
規模感や組織構造によるのはわかっているが、どうもシステムを維持することにばかり時間を費やし、本来やるべきシステム開発による問題解決になかなかいたらなかった感じはあった。
一方、趣味開発ではAWSやHerokuなどのクラウドを使っていたので、本来やるべき問題解決に集中できることの価値を感じていた。
そういった経験から、パブリッククラウドをもっと多くの人が活用してシステム開発の本質により注力できるように、と思うようになった。

最後に…
この3年間で社内の仕事の質がかわった瞬間を目の当たりにした。
外注も内製もやってきたと書いたが、はじめは外注が多かったが徐々に内製開発の比率が増えてきた。
それに伴って、社員が行う仕事の質や求められるスキルが変化していったのを感じた。
きっと、次の3年間もなんらかで変化が起こるはずで、振り落とされないよう頑張りたい。

※次のところ英語話さなきゃいけなくてほんとにヤバイ・・・

とてもながめのいいオフィスでした。

【めも】httpヘッダー、x-forwarded-forとか任意のヘッダーとか

ただのめも。

もともとApache+PHPで動作していたシステムに、リバースプロキシ(Nginx)を前段に挟むことになった。(理由はここではどうでもいいので書かない)
つまり、Nginx->Apache->PHPという構成になった。
よくあることだが、Apacheからみるとすべてリバースプロキシから通信がきているので、 接続元のIPアドレスがすべてリバースプロキシのものになる。

HTTPヘッダーに接続元のIPアドレスを追加しアプリ側(PHP)で受け取ろうとしたときのめも。

リバースプロキシ側でHTTPヘッダー追加

まず、そもそもデフォルトのNginxの設定では接続元のIPアドレスをHTTPヘッダーに含まれない。
ググればすぐに設定方法自体はでてくる。
X-Forwarded-Forというヘッダー名にNginxでもっている変数$proxy_add_x_forwarded_forをつっこむ。

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

設定は簡単なんだけど、そもそもX-Forwarded-Forなんていうヘッダーあったっけ。。。?
Wikipediaでみる。

X-Forwarded-For (XFF) とは、HTTPヘッダフィールドの一つ。HTTPプロキシサーバまたは負荷分散装置(ロードバランサ)を経由してウェブサーバに接続するクライアントの送信元IPアドレスを特定する際のデファクトスタンダードである。 (略)RFCの標準的なヘッダフィールドではないが、IETFのネットワーク作業部会 (Network Working Group) は2011年10月より同種のHTTPヘッダForwardedの標準化作業を開始した[1]。

なるほど、RFCの標準ではないけど、一般的なものなんですね。

phpでX-Forwarded-Forを受け取る

というわけで、おりゃ!

echo $_SERVER['X-Forwarded-For'];

エラー...
※普段PHP使ってないのがバレますね。

サーバ変数とりあえず、全部はきだす。

<?php
var_dump($_SERVER);

# array(x) { ["HTTP_X_FORWARDED_FOR"] => string(12) "192.168.33.1" ...... }

HTTP先頭についてて、大文字になってて、ハイフンがアンスコに変わっている。
あたりまえだけどこれはPHPの仕様でいいんだよな...?

<?php
var_dump(getallheaders());

# array(x) { ["X-Forwarded-For"] => string(12) "192.168.33.1" ...... }

サーバ変数にいれるときに、変わるんだわ。

念のためtcpdumpで軽く確認してみる

$ sudo yum install tcpdump
$ tcpdump dst port 80 -X

# ながいんで適当に端折りました
11:04:01.883209 IP 10.0.2.15.43038 > 192.168.0.10.54655: Flags [.], seq 802:1603, ack 1, win 14600, length 1460
     (略)
     0x0000:  4500 0355 c705 0000 3706 24ca adc2 265f  1.0..X-Forwarded
     0x0010:  c0a8 000a 0050 d57f 51ad 1e62 e596 78a4  -For:.192.168.33
     0x0020:  8018 0137 8dbe 0000 0101 080a d1dc c19e  .1..Host:.xxxxxx

いたいた。
Nginxからプロキシされるときはちゃんとヘッダー名は"X-Forwarded-For "になっていること確認。

任意の適当なHTTPヘッダーつけてみた

proxy_set_header my-header 'hogefugafoobar';
var_dump($_SERVER);

# array(35) { ["HTTP_MY_HEADER"] => string(14) "hogefugafoobar" ...... }

ふーん、なるほどな...

Vim::Factory、LTではなす

7月6日の会社のエンジニアイベントでLTするやつ、先にあげておく。
自分の中でのネタとしては古いけど、話すのはなんだかんだ初。

詳しくはこっち見ること

mosuke5.hateblo.jp

IkaLog環境整えた。画面が突然映らなくなる事象とかについて

昔まで、人の家でスプラトゥーンをやったりたまに借りたりして楽しんでいたが、
ついにというか今更というか自宅用に買ってしまった。
ついでにという感じで、お金を注ぎ込んで、IkaLogを楽しめる環境も作った。

IkaLogあるととても楽しい。

IkaLog環境はほぼ下記ブログを参考にしたので、詳しいことはかかないが、
全体図やハマったポイントなどを中心にまとめておく。

uriku.hatenablog.com

完成後写真

f:id:mosuke5:20160625112118p:plain

図にしてわかりやすくすると

f:id:mosuke5:20160625112128p:plain

突然画面が映らなくなることが起きた!!

ゲームを楽しんでいた時突然、ディスプレーに画面が映らなくなることが度々あった。
ケーブルを抜き差ししても直らない。
ただ時間が経つと映るようになる・・・

原因が最初わからなかったのだが、
どうやらHDMIスプリッターの電源供給が追いつかなくなった時になっていた。
HDMIスプリッターはHDMIからある程度給電することができるので、はじめはそのまま利用していた。
だが、IkaLogを回し始めるとどうやら給電が追いつかなくなるようであった。

説明書にも下記のように書いてあって、「あっ」って感じだった

入力機器側の電力不足により正常に表示できない場合に使用します。

USB経由で別途電源供給をするようになってから事象が発生しなくなった!

※画面が映らなくなってガチマッチ何度負けたことか・・・

Nginxの仕組みについて入門

普段Nginxを使ってはいるものの、その仕組やなぜNignxを使うべきなのかというところがあまりわかっていなかったので、 改めてNginxを入門しその仕組などについて調べてみた。
勉強不足もあって、間違ってることもあるかもしれないがその際は教えて下さい。

1. C10K問題

まず、Nginxを理解する上でC10K問題について知る必要がある。
C10K問題とは下記の問題のことだ。

ハードウェアの性能上は問題がなくても、クライアント数があまりにも多くなるとサーバがパンクする問題のこと。 C は「Client(クライアント)」の頭文字、10K は「1 万台」を意味する。「クライアント 1 万台問題」ともいわれる。
C10K 問題とは - はてなキーワード より引用)

2. 従来のWebサーバのアーキテクチャ

prefork

Apacheのデフォルトのアーキテクチャなどで採用されている。
特徴としては、1リクエストに対して1プロセスが処理する。
すなわち同時接続が 1000であれば 1000個のプロセスが必要となる。

f:id:mosuke5:20160604171531p:plain

worker

リクエストはスレッドが処理する。
スレッドは1プロセスのなかで複数立ち上げることができる。
プロセス数は少なくて済むが、同時接続が1000であれば1000個のスレッドが必要となる。
Apacheで指定可能なアーキテクチャの1つ。

f:id:mosuke5:20160604171542p:plain

いずれにしても、1000の同時接続があれば、1000のプロセスやスレッドが必要ということだ。
プロセス/スレッド数が多くなってくると「コンテキストスイッチ」が多く発生し、処理が遅くなってしまう。

コンテキストスイッチとは

コンテキストスイッチとは、コンピュータの処理装置(CPU)が現在実行している処理の流れ(プロセス、スレッド)を一時停止し、別のものに切り替えて実行を再開すること。
コンテキストスイッチとは|コンテキストスイッチング|context switch - 意味/定義 : IT用語辞典 より引用)

3. Nginxのアーキテクチャ

NginxがC10K 問題を解決するために開発されたともいわれている。
上記のような課題を解決するようなアーキテクチャを採用している。

f:id:mosuke5:20160604171559p:plain

ワーカプロセスがリクエストを処理する。
前述のpreforkやworkerと決定的に違うところは、1つのワーカプロセスが複数のリクエストを処理するということだ。

また、マスタープロセスはワーカプロセスの立ち上げや、制御、管理などが主な仕事。
Nginxを終了あるいは再起動、設定ファイルを再読み込みして変更を反映するなど。

下記のような仕組みがNginxの高速化(C10K問題対応)を可能としている。

シングルスレッド

接続ごとにプロセスやスレッドを立ち上げていては、C10K問題に対応できない。
そこで、Nginxは1つのスレッドで処理を行うようにしている。
それにより、コンテキストスイッチと呼ばれるCPUの切り替え処理が発生しない。
正確に言うと、完全に1スレッドで処理するわけではなく図にあるようにワーカプロセス自体はマルチプロセス化できる。

イベント駆動

通常のプログラムは上から書かれた順に実行されますよね。
イベ ント駆動で動作するプログラムは何かしらのイベントが発生するまで待機し、発生したイベントの種類に応じて実行される。
ブラウザ上のJavaScriptの動きをイメージするとわかりやすいと思う。

非同期処理

一般的なwebサーバでは同期処理を行う。 つまり、複数のリクエストがあったときに順番に処理していく。
そのため、1つのリクエストが遅いとそれに引きづられてあとのリクエストも遅くなる。
非同期処理では、リクエストがきたら他のリクエストの状況に関わらず処理を行う。

同期処理

f:id:mosuke5:20160604173212p:plain

非同期処理

f:id:mosuke5:20160604173226p:plain

向いていること / 向いていないこと

Nginxではイベント駆動で非同期的なIO処理によって、リクエストを完全に処理することを待たずに次から次へと処理を受け付けていきます。
そのため、1処理に時間のかかるものをNginx自身で行おうとするとキューがどんどん溜まってしまいます。
そのため、一般にアプリケーションの実行やデータベース処理などは向いていません。
一方で、軽量な静的データの配信やリバースプロキシなどに向いています。

Nginxは、静的データの配信や、プロキシなどに特化させ、アプリケーションの実行などは別途アプリケーションサーバ等で行わせることで有効活用できます。

向いていること

  • 軽量データの大量配信
  • ディスクI/Oの発生しないキャッシュ
  • リバースプロキシ
  • ロードバランサ

向いていないこと

  • アプリケーション実行
  • データベース処理
  • 動画などの重たいデータの配信

4. 最後に

NginxやWebサーバについてより理解を深めるためには、
UNIXのプロセスやネットワークAPIについての知識が足りないと感じた。。。

というわけでこれを買ってみたが、978ページもあってとりあえず挫折\(^o^)/

UNIXネットワークプログラミング〈Vol.1〉ネットワークAPI:ソケットとXTI

UNIXネットワークプログラミング〈Vol.1〉ネットワークAPI:ソケットとXTI

  • 作者: W.リチャードスティーヴンス,W.Richard Stevens,篠田陽一
  • 出版社/メーカー: ピアソンエデュケーション
  • 発売日: 1999/07
  • メディア: 単行本
  • 購入: 8人 クリック: 151回
  • この商品を含むブログ (37件) を見る

まずはこれからはじめようと思う。。。

tatsu-zine.com

参考文献

今度こそ入門するtmux

tmuxの入門は何度目だろうか…
SoftwareDesignの2015年7月号を見ながら、何度目かの入門をしたのでメモする。
ブログに書いたので、これで運用にのりそうだ。

tmuxってなに?

公式ページ(http://tmux.github.io/)から引用すると。

tmux is a terminal multiplexer. What is a terminal multiplexer? It lets you switch easily between several programs in one terminal, detach them (they keep running in the background) and reattach them to a different terminal. And do a lot more.
(訳)tmuxはターミナルマルチプレクサです。ターミナルマルチプレクサは複数のプログラムを容易に1つのターミナル上で切り替えられるようにします。またそれらのプログラムをバックグラウンドで動かしながらデタッチしたり、別のターミナルにアタッチすることができます。さらにいろいろなことができます。

tmuxを使ってみる

インストール

今回Macの環境で行っています。
今日時点ではバージョン2.2まででていますが、brewでは2.1がインストールされました。

$ brew install tmux
$ tmux -V
tmux 2.1

起動

$ tmuxと入力すると、tmuxが起動し$ exitで抜けることができます。
これから説明していきますが、tmuxの機能を利用するときプレフィックスキーを入力する必要があります。
デフォルトではプレフィックスキーはCtrl-bになっています。

ウィンドウの作成、切り替え

1つのtmuxの中にウィンドウ(タブ機能と考えてください)を作って切り替えたりします。
Ctrl-b+cでウィンドウを作成できます。
ウィンドウを作成するとターミナルの下部分(ステータスバー)に表示されます。
*印があるのがいまいるウィンドウです。

f:id:mosuke5:20160414233836p:plain

ウィンドウ分割

ウィンドウの分割もできます。開発するときに便利ですよね!
分割された画面をペインと言います。
Ctrl-b+%で縦に分割、Ctrl-b+"で横に分割できます。
ペイン間の移動はCtrl-b+o

f:id:mosuke5:20160414230041p:plain

なにが嬉しいの?

まてまて、タブ機能もウィンドウ分割もiTerm2で全然できるよ?
ほら!? f:id:mosuke5:20160414230301p:plain

tmuxのいいところはデタッチとアタッチ機能やカスタマイズ性の高さだと思う。
カスタマイズ性についてはまだそんなにわかってませんが。。。

デタッチとアタッチ

tmuxはターミナルを仮想化します。その威力を発揮するのがデタッチとアタッチ機能です。
tmuxを起動した状態でCtrl-b+dを押してみよう。
そうすると下のステータスバーも消え、元のターミナルに戻ってきたと思う。
これをデタッチといい、tmuxが終了したわけではない。

プロセスを確認すると、tmuxがまだ存在してることがわかる。

$ ps -ef | grep tmux
  501 16038     1   0  9:26PM ??         0:02.26 tmux
  501 17800 13345   0 11:53PM ttys005    0:00.00 grep tmux

tmux lsで現在のtmuxのセッションの一覧がみれます。

$ tmux ls
0: 1 windows (created Thu Apr 14 21:26:19 2016) [129x32]

ではアタッチしてみよう。下記で元のtmuxに戻ってくるはずです。

$ tmux attach

デタッチしている間もバックグラウンドでプログラムは動き続けています。
試しに、tmux上でvmstatなどを打ってデタッチしてアタッチすると動き続けていることがわかると思います。

pstree見るといい

tmuxの概念を理解するにはpstreeをみるといい。
tmuxを使わずにpstreeコマンドを打つと、SSHのプロセスの下でpstreeが動いているのがわかる。

$ pstree -p
systemd(1)
    ├─sshd(13589)─┬─sshd(15066)───sshd(15068)───bash(15069)───pstree(15115)

一方、tmuxを起動し、tmux上でpstreeを実行すると、sshdのプロセスの下にはtmuxが動いており、
pstreeコマンドはtmuxプロセスの下で動いている。

$ pstree -p
systemd(1)
    ├─sshd(13589)─┬─sshd(15066)───sshd(15068)───bash(15069)───tmux(15146)
    └─tmux(15148)───bash(15149)───pstree(15168)

なにがいいたいかというと、tmuxの上で動かすプロセスはsshdとは別プロセスで動いているということ。
sshが切れても動作し続けるとはまあそういうことです。

カスタマイズ

tmuxはカスタマイズ性に優れます(ようです)。.tmux.confを修正することでカスタマイズ可能です。
今回は入門ということで、よく使いそうな基本設定だけしたが、これだけでも相当便利でした。

  • プレフィックスキーをCtrl-tとする
  • ペインのサイズをvimキーバインドで調整できるようにする
  • ウィンドウの分割を|-でできるようにする
# プレフィックスキー
unbind C-b
set-option -g prefix C-t

# paneのサイズ変更(Vimerにはかかせない)
bind -r H resize-pane -L 5
bind -r J resize-pane -D 5
bind -r K resize-pane -U 5
bind -r L resize-pane -R 5

# window分割(わかりやすくていいね!)
bind | split-window -h
bind - split-window -v

Vimキーバインドでペインのサイズ自由自在! f:id:mosuke5:20160415000811g:plain

HerokuをRailsアプリのステージング環境として使う

趣味で作っているアプリ(Rails)があるのだが、はじめHerokuで運用しようと検討していたが、
データ量が多いためすぐにHobbyプランでは対応できなくなってしまった。
仕方ないので、別のアプリで持っているVPSをProduction環境とすることにしたのだが、
せっかくなのでherokuもうまく使いたいなーと思ってステージング環境として使うことにした。

そのときにやったことをメモする。

Staging環境の設定を作る

Railsではデフォルトではdevelopment, test, productionの環境を持っている。
そこに今回、stagingという環境を追加した。
そして、herokuではデフォルトではproductionを利用するようになっているのでstagingに切り替えるだけ。

Rails側はstaging環境追加。

$ vim config/database.yml
# 下記を追加した
staging:
  <<: *default
  adapter: postgresql
  encoding: unicode
  database:
  pool: 5
  username:
  password:

$ vim config/enviroments/staging.rb
# 基本的にはproduction.rbをコピーし、必要に応じて設定を変更

$ vim config/secrets.yml
# 必要に応じてstagingを追加

heroku側はステージングへの切り替え。

$ heroku config --app app-name    # デフォではproductionになってる
RAILS_ENV:                production
$ heroku config:set RAILS_ENV=staging --app app-name
$ heroku config --app app-name
RAILS_ENV:                staging

Basic認証

ステージング環境なので、外部から簡単にアクセス出来ないようにBasic認証をかけた。
いくつかやり方があると思うが、app/controllers/application_controller.rbに設定を追加した。
ユーザ名とパスワードをベタ書きだとGithubに上げてる場合は丸見えになってしまうので環境変数でやりましょう。

http_basic_authenticate_with :name => ENV['BASIC_AUTH_USERNAME'], :password => ENV['BASIC_AUTH_PASSWORD'] if Rails.env == "staging"

heroku側では環境変数を設定してあげる。

$ heroku config:set BASIC_AUTH_USERNAME="xxxxx" BASIC_AUTH_PASSWORD="xxxxx" --app app-name
$ heroku config --app app-name
BASIC_AUTH_PASSWORD:      xxxxx
BASIC_AUTH_USERNAME:      xxxxx

Github連携で自動デプロイ

今更ながらGithubと連携した自動デプロイ機能があることを知った…
Githubgit push origin masterすればheroku側にも反映される機能だ。
昔使った時にはgit push origin mastergit push heroku masterと2回コマンド打ってたのでめんどいなーと思ってた。
デプロイが楽なのでステージング環境としてはほんとに優秀だと思う。

[heroku]githubから自動でherokuにデプロイ - KayaMemo