TDD Boot Camp in 香川 #1に参加してきました!

こんにちは!株式会社Re:Buildの中西です。今回は7/22(土)に香川県の情報通信交流館 e-とぴあにて行われたTDD Boot Camp in 香川に参加してきましたのでイベントのレポートをお届けします!

agile459.connpass.com

参加の動機

これまでプロジェクトをスクラム開発で取り組んできましたが、どうにも毎週のコードレビューとテストがボトルネックになっている気がしていました。

また独学でテストを勉強し、チームメンバー全員でテストコードを書くようにはしているのですが、うまくテスト駆動開発できていなかったり、テストの書き方の方向性はこれでいいのかなど迷っていました。

そんななか、なんとあの「テスト駆動開発」を翻訳された和田卓人さんが来てくださるテスト駆動開発の勉強会があるということで参加させていただきました!

トークセッション「テスト駆動開発 質を作り込む」

午前中は和田卓人さんによる講演会でした。

まず印象に残っているのが、テスト駆動開発のゴールは「動作するきれいなコード」だという言葉です。ハンマー釘病にかかってしまわないよう、まず最初に目標を設定することはとても大切なことですよね。

参考:IT業界を蝕むハンマー釘病 - Togetter

次に非常に印象に残っているのが、とりあえず動いてる汚いコードをリファクタリングするときにとりまく下記の3つの感情のおはなし。

  • 堕落:「コード動いてるからええやん?」
  • 焦り:「うわああああテスト書く時間ないでござる」
  • 恐怖:「動かなくなったら嫌だから、リファクタできひん。。。」

どれもビジネスでプログラミングをしたことがある人なら感じたことがあるとおもいます。解決法としては、

  • 恐怖:テストコードを書くことによって克服
  • 堕落:怠けようとする弱い自分を倒すことで克服

焦りに関してが問題で、本当に時間がない場合ってのもあるのでしょうが、日をまたぐと自分のコードでも意味がわからなくなったりすることって頻繁にありますよね!?なので最低でもその日のうちで最低限のテストコードくらいは書こいておこうというのがひとまずの解決策でした。

全体を通してすごく話がわかりやすくスライドもシンプルでみやすく、発表の仕方自体も勉強させていただきました。

テスト駆動開発ハンズオン!

午後はお待ちかねのテスト駆動開発のハンズオンでした!会場の人とペアになってプログラミングをしていく、いわゆるペアプログラミングでのハンズオンでした。

ペアプログラミングとは、2人1組になって1つの画面でプログラミングをしていく手法のことで、ドライバー(キーボードを叩いてプログラミングする人)とナビゲーター(設計したりドライバにアドバイスをしたりする人)の役割に分かれて共同で作業を進めていきます。一見開発効率が2分の1になるかのように思えるのですが実際はそうではなく、誤った実装をしそうになったときにペアに指摘してもらえたり、煮詰まったときにドライバーとナビゲーターを交換することで1人で煮詰まらずに作業が進んでいくという感じで、メリットの方が多い作業方法のように感じられました。

各チームある程度作業が進んだところで会場全体でコードレビューの時間に。最初は自分のコードを大勢の方にみられるということで緊張していたのですが、実際やってみるととてもおもしろく、様々な指摘を貰うことでコードがその場でブラッシュアップされていく感じがエキサイティングでした。

他のペアの方のレビューの際も、自分が指摘する側にまわることで良いコードからは刺激をもらいますし、俺だったらこうするけどなと感じた部分に関してはすぐに質問してみるなど、お互いにとってプラスになることがとてもおおい時間だなと感じました。

懇親会!

TDDBC in 香川に参加していた約20名くらいで、ホテルの屋上で開催されているビアガーデン会場へ!

ものすごいでかい会場にたっくさんの人がおりました!笑

香川県ってこんなにもビアガーデン文化が広まっているんやなぁと、沖縄県民の中西としてはカルチャーショックでした!

まとめ

これまでテストコードや、テスト駆動開発に関する勉強を独学でしかしてこなかった自分にとっては本当にたくさんの学びがある1日になりました!

最後に、和田卓人さん、TDDBC in 香川の運営の方々、重厚で楽しい時間を本当にありがとうございました!

PHPカンファレンス関西2018に行ってきました

こんにちは!株式会社Re:Buildの中西です。今回は7/14(土)にグランフロント大阪で行われたPHPカンファレンス関西2018に参加してきましたのでイベントのレポートをお届けします!公式サイトから「ネコとワタシとPHP in 沖縄」というタイトルでLT枠に応募したところ、発表順1番で採用されましたのでLTもしてきました!

2018.kphpug.jp

各セッションの感想

会場が3会場に分かれており、自分の好きなトークセッションを聴くスタイルでした。以下は中西が拝聴させていただいたセッションの感想です。

脱!なんちゃってフロントエンド

スピーカーの榊原さんの「フロントエンドをPHPでかくのがアンチパターンになるのはすぐそこだ!」という発言が非常に印象的で、実際僕もそうなるのでは?と思わされました。その理由として、

  • しっかりフロントエンド組めば、Webベースでもネイティブ アプリに見た目や機能が劣らない時代になってきた
  • 実際PHPでViewをレンダリングするのは非常にコストの高い処理である
  • APIを利用してフロントエンドとバックエンドを疎結合に保ち、描画する際のエラーをしっかりハンドリングしておけば、PHPのFatal Errorなどで画面がユーザー表示されないこともなくなる

という理由を上げていました。

やはり既存の技術を惰性で使い続けるのではなく、どうすればUXが向上するかを常に考え続けることが非常に重要だとあらためて認識させられました。

将来的にはフロントエンドエンジニアとか、バックエンドエンジニアとか垣根がなくなっていくのではとも思いました。

チャットディーラーの高速開発を支えるLaravel

株式会社ラクスの主力サービス、「チャットディーラー」をLaravelで開発した際に得られた知見をまとめた感じの発表でした。Laravelのいいところ、気をつけるべきところのまとめが非常にわかりやすかったので、Laravel初学者の方は以下のスライドが参考になると思います。是非ごらんください!

CircleCI 2.0 を使い倒そう

CircleCI2.0って実際どうなの?という話から、CircleCI 2.0を利用する具体的な方法。また、CIを構築する際に技術的な障壁となってくるDockerを使いこなすためのテクニックまで盛りだくさんな内容でした!

僕も知らなかったのですが、CircleCI2.0は無料枠があるらしいので個人的なプロダクトで今度触ってみようと思います。

DockerHubのイメージのソースをダウンロード、改造して自分のDocker Imageを作成するのが超勉強になるみたいなので近々取り組んでみようと思いました。

LTしましたよ!「ネコとワタシとPHP in 沖縄」

沖縄を代表してLTの発表頑張りました!カンファレンスの参加者が1つの部屋に集結するイベントの運びとなっており、非常に沢山の人の前でLTさせていただきました!緊張したけど会場の反応もあったかく楽しく発表させていただきました!

f:id:kaoru6strings:20180716155435j:plain

懇親会!

技術の話からお仕事の話まで、非常にたくさんの方々と交流できました。お話してくださった方々、本当にありがとうございましたー!

f:id:kaoru6strings:20180716155423j:plain

まとめ

はじめて県外遠征での勉強会参加となりましたが、非常に濃い内容の勉強会となりました!1人で参加したので最初はアウェイな感じがありましたが、近くの方と技術の話を通してすぐ仲良くなれたのでそれからは居心地のいい雰囲気で参加させていただきました。やっぱりエンジニアっておもしろい!

最後に、PHPカンファレンスの運営の方々、スピーカーの方々をはじめ、関わってくださったすべての人に感謝!楽しい時間をありがとうございました!

株式会社リビルドではWebエンジニアを募集しています

弊社ではWebエンジニアを募集しています。ご連絡は下記のコーポレートサイトから!

株式会社ReBuild | ReBuild

また、沖縄でネコ駆動リモート開発したいエンジニアの相談も中西が受け付けていますのでお気軽にご相談ください。

大阪のコワーキングスペースいってみた!

こんにちは!Webエンジニャーの中西です。

本日はPHPカンファレンス関西2018に参加するため大阪に前入りして、現地のコワーキングスペースで仕事してみました。

1. Blue+(ブルータス)

bluetas.com

梅田のヨドバシカメラの裏手くらいにありました。

今回は2時間30分くらい利用させていただきました!

床に緑の芝生が引いてあり落ち着いた空間に仕上がっておりました。料金を支払えば個室空間を借りれたり、専用のロッカーを借りれたりするみたいなので気に入った方はがっつり契約してみるのもいいかもしれません。

2. オオサカン

www.osakan-space.com

ほとんどの利用者が月額会員ということで根強いファンが多い印象でした。お互いが気持ちよく作業するためにルールの整備もしっかりされており、通いやすい環境にあれば是非契約してみたいなーと思いました。また、お昼時間にはみんなでご飯を食べる文化があったりと、他のコワーキングスペースにはないいい雰囲気が!この雰囲気がすきな人はすぐ月額会員になっちゃうんだろうな〜。

最後に、作業風景をパシャリ。

f:id:kaoru6strings:20180714142634j:plain

まとめ

今回は2件のコワーキングスペースにお邪魔させていただきました!

どちらのコワーキングスペースも個性が出ていてビジターとして利用させていただくだけでも非常に勉強になりました!

フリーランスやリモートワークの方は、自分のお気に入りのコワーキングスペースを探す旅とかしても面白そうです。

みなさんおすすめのコワーキングスペースがあったらコメントで教えてください!それでは!

写真撮影会をしました!

こんにちは!株式会社Re:Buidの中西です。

今回は先日行われた写真撮影会のオフショットをお届けします!

f:id:kaoru6strings:20180714134949j:plain f:id:kaoru6strings:20180714134956j:plain f:id:kaoru6strings:20180714135008j:plain

カメラマンはフリーでデザイナーのお仕事をなさっている町田さんに特別に撮影していただきましたー!

町田さん、素敵な写真本当にありがとうございました!

撮影していただいた写真は弊社のコーポレートサイトや求人ページで見ることができます。お楽しみに!

それでは!

「PHPカンファレンス福岡2018」にLT枠で登壇しました

株式会社リビルドの嘉数です!

先日PHPカンファレンス福岡2018に弊社のインターン生と一緒にLT枠で登壇してきたので、そのことについて徒然と書いていきたいと思います!

PHPカンファレンス福岡とは

もともとはPHPカンファレンス福岡の運営者である市川さん(@cakephper)がTwitterでふとした発言をしたことにより実現したカンファレンスらしいです。ちゃんとその時のTweetがtogetterにまとめられていました!

PHPカンファレンス福岡が開催!? #fukuokaphp - Togetter

なるほど、東京で行われていたPHPカンファレンスに参加できずボソッと呟いたことがきっかけだったようですね。影響力でかい。

PHPカンファレンス福岡は2015年から始まり、毎年続いて2018年今回は第四回目の開催。毎年大体300人近くの参加者が集まるそうです。スポンサーの数も多い感じがしました。

ちなみに今回は前回よりもTシャツのデザインにこだわったそうです。参加者は先着でイベントTシャツが貰えるのですが、嘉数は登壇者枠ということで色違いのTシャツを頂きました。ロゴと色合いが可愛くて良い!

f:id:kkznch:20180620090135j:plain

各セッションの感想

会場にはFusicホールとロリポップ!マネージドクラウドホールの二箇所あり、嘉数は基本的にFusicホールのセッションに参加していました。なので、Fusicホールのセッションについてざっと感想を述べようと思います。

なお写真については基本的にNGだったので、嘉数と伊藝君の分のみこちらで掲載します。

「何故PHPなんですか?」

PHPに慣れ親しんできた私達にとってPHPの良さというものが当たり前となっているが、Golangという別の言語に触ってみて改めてPHPの良さを再認識したというお話でした。ちなみにGolangをディスっていたわけではなく、あくまでも良い部分と悪い部分がそれぞれあるよね、といった具合です。

嘉数は単純にLaravelフレームワークが使いやすいからという理由でPHPを使ってます。言語仕様うんぬんもそうですが、案件やその時の状況など様々な要因が絡んでその言語を使う理由も変わると思うので、効率よく目的が達成できるのであればPHPに限らず触ってみたいですね。

「ログの設計してますか?PSR3とログ設計の話」

PHPのロギングライブラリの共通インターフェースであるPSR-3に準拠してログ設計をし、その出力を活用することでより幸せになれるかもしれないとお話でした。

var_dumpでのprintデバッグが許されるのは小学生までだよね〜、とか言いつつ嘉数は今でも無意識に使ってしまいます。ログ出力する必要はないけど値を確認したい箇所とか、ついつい書いてしまいます。そこはデバッガ使うべきですね、わかります(嘘)。

「Fusic n本の矢 〜生きた集合知の作り方〜」

個人の知識、個人の知識を蓄えた皆の知識、皆の知識が関連しあって出来る集合知、生きた集合知、生き生きとした集合知。知識の段階とそこまでに至った過程について非常に興味深い内容でした。

弊社の現状は個人の知識がそれぞれ散らばっている状態なので、知識を共有できる場所を作ってそれを活用していきたいですね。

「未経験からの挑戦!超速ネイティブアプリ開発

FlutterというGoogleクロスプラットフォームを用いてiPhoneAndroidのアプリを高速で開発できるらしいです。

個人的にはプラットフォームに合わせたネイティブな言語を使って開発をする方が好きなのですが、時間や資源が制限されるのであれば開発時に使ってもいいかなと思いました。

「SOLIDの原則ってどんなふうに使うの?オープン・クローズドの原則編 拡大版」

「クラスは拡張に対して開いていて、修正に対して閉じていなければならない」というオープン・クローズドの原則に則って書くコードに感動しました。バリエーションの追加があったとしても既存のコードには手を付けず、新しくコードを追加するだけで対応できるという美しさ、これは確実に抑えておくべきですね。

ロリポップ!マネージドクラウドを支えるコンテナ技術のすべて」

普段意識せず使っているコンテナの技術に関するお話でした。ローカルだとDockerコンテナを起動し続けて無駄にリソース消費していますが、マネージドクラウドを提供してる側はリソースが無駄にならないように様々な努力をしているのだなと感じました。コンテナは今では開発には欠かせない技術なので、コンテナの仕組みについて勉強もしてみたいですね。

「0から始めるLaravel相談会」

Laravelを使えば初級者でも簡単に開発ができるのか?ということについて考えるお話でした。定義されていた初級者のスペックが何気に高い気がしましたが、基本的にLaravel公式のガイドにさえ従えばある程度のレベルのコードが書けるらしいです。

嘉数も最初の頃はLaravel公式ガイドにお世話になりましたが、いつしか途中から読まなくなった記憶があります。一度は全体に目を通す方が良さそうです。

「Laravel Queue でスケーラブルなバッチシステムの構築」

LaravelのQueueとJobを使ったバッチシステムについてのお話でした。話を聞くまではcronを使えばどうにでもなるだろうと思っていたのですが、QueueとJobの使い方や使い所について説明を聞いてかなり勉強になりました。おそらく今後いつか使う機会が出てくると思うので、その時に活かしたいです。

「Testing Live!!!」

  • スピーカー:フクダリナ(@rina
  • スライド:Testing Live!!!

単体テスト結合テストの話かと思いきや、テスターがテスト対象のサイトをブラウザで開いて目視で行うテストのお話でした。しかもライブ・コーディングならぬライブ・テスティング。実際に存在するサイトをプレゼン中にテストするという稀に見る内容でした。

「ランサーズバージョンアップ報告」

ランサーズで使われているシステムのPHPとCakeのバージョンをリアルタイムにバージョンアップ完了させた報告と思いきや、現在奮闘しているというお話でした。システムが稼働している環境のPHPのバージョンを5系から7系に上げるとどのような影響があるのだろうか検討がつきませんね。話の後半に出てきたMailDevコンテナは開発の時に使えそうですね。

LTセッション

嘉数とリビルドインターン生を含めて合計9人がLTを行いました。プロファイラを使って不要なコードを削減したら99%のコードが消え去った話、エンジニアにとっての選択肢の良し悪しについて真面目な話、歌って踊れるアイドルエンジニアによるDappsの話、社内SEがVBAを捨ててPHPで幸せになると思いきやVBAではなく職を捨てていた話など、話者とその内容が濃すぎるものばかりでした。色んな意味でレベルが高かったです。

弊社のLT!!

緊張しすぎて自分の番が回ってくるまで吐きそうでした。多分変な顔をしていた気がします、写真に撮っておけばよかった。というわけで以下は嘉数と伊藝君のプレゼン内容になります。

嘉数「PHP歴3か月だけど沖縄でフルリモート開発してる話」

嘉数は、PHPの経験が浅いけど沖縄でフルリモート開発をしていることについて話をしました。といってもLT枠で時間がないので、雰囲気だけ伝わればいいかなぐらいの内容です。LT後の懇親会では「ビーチ駆動開発やってみたい」という声があったので発表した甲斐がありました。

こちら発表風景になります。会場に100人以上はいたかな、かなり緊張しました。

f:id:kkznch:20180620090210j:plain f:id:kkznch:20180620090158j:plain

伊藝(インターン生)「いつか技術を身につけたらLTする!じゃなくて今やる。」

  • スピーカー:伊藝 秀(@si_date)
  • スライド:(まだアップロードされてないっぽい〜)

弊社インターン生の伊藝君はLT駆動開発についての話をしました。確かに、よく分からないけどLT発表に申し込んで、LT発表のために技術の勉強をする方が効率が良いしモチベーション維持にも繋がる気はします。発表もハキハキとしていたし結構ウケていたので良かったです。おつかれさま!

f:id:kkznch:20180620085809j:plain

おわりに

今回PHPカンファレンス福岡2018に参加してみて、様々な知見を吸収することができた気がします。また嘉数自身、これほどの規模の舞台でLTをすることが初めてだったため、かなり良い経験が積めました。楽しかったなと、この一言に尽きます。

PHPカンファレンス福岡2018の運営の皆様、こんなに素敵なイベントを企画・運営していただき本当にありがとうございました!

f:id:kkznch:20180620090145j:plain

Laravel5.5で中間テーブルを経由した先のテーブルのデータをとりたい

下記のリンクを参考にEloquentのリレーションにhasManyThroughを設定しましょう

Laravelのリレーション hasManyThrough の使い方を毎回間違うのでメモ

// ユーザーモデル
class User extends Model
{
    public function Games() {
        return $this->hasManyThrough(①, ②, ③, ④, ⑤, ⑥); // ← 毎回忘れる
    }
}
番号 user_id
リレーションを経由したあとに取得したいモデル (Model\Game)
リレーション用のモデル (Model\UserGame)
②のモデルを呼び出し元のモデル (Model\User) と結びつけるために使うキー (user_id)
①のマスタID (game_master_id)
不明
②のモデルを①のモデルと結びつけるために使うキー (game_id)

Gitlab CI/CDでLaravelプロジェクトのテスト及びデプロイをする

※本記事は嘉数の個人ブログ(Gitlab CI/CDでLaravelプロジェクトのテスト及びデプロイをする - けけずんセルフハッキング)からの転載になります

概要

LaravelプロジェクトをGitlabにPushした際、Pushしたブランチに応じて自動でテストやデプロイを行うようにする。ついでに、テストが通らなかったブランチはメインのブランチに対するマージリクエストを行えないようにする。

ブランチ毎に行う処理

  • master:テスト、本番環境へのデプロイ
  • deploy:テスト、ステージング環境へのデプロイ
  • 上記以外のブランチ:テスト

処理の流れ

以下はPushからデプロイまでの処理の流れ図。

f:id:kkznch:20180620092408p:plain

  1. LocalからGitlabにPushする
  2. GitlabCIが実行される
  3. Unitテスト用のDockerコンテナが起動される
  4. Unitテストが実行される
  5. デプロイ用のDockerコンテナが起動される
  6. Envoyコマンドが実行される
  7. デプロイ先(本番環境orステージング環境)でPullされる

実装手順

結構やること多い。やることを列挙しとく。

  • ローカルでやること
    • Gitlabからデプロイ先に接続するための鍵組の作成
    • Dockerの準備
      • Dockerfileの作成
      • Dockerfileをビルドしてイメージを作成
      • DockerイメージをGitlab Container Registryに登録
    • Gitlab-CI設定ファイルの作成
    • デプロイ用タスクランナー設定ファイルの作成
  • デプロイ先(本番環境orステージング環境)でやること
    • デプロイ用ユーザの作成と設定
    • GitlabからClone・Pullするための鍵組の作成
    • リポジトリのCloneと設定
    • Gitlabからデプロイ先に接続するための鍵の設置
  • Gitlabでやること
    • GitlabからClone・Pullするための鍵を登録
    • Gitlabからデプロイ先に接続するための鍵の登録
    • ブランチをProtected branch化

こんな感じでやっていく。

ローカルでやること

Gitlabからデプロイ先に接続するための鍵組の作成

ローカルの任意の場所(以下/path/to/mykeysとする)で以下のコマンドを実行し、Gitlabからデプロイ先へ接続を行うための鍵組を作成する。

$ cd /path/to/mykeys
$ ssh-keygen -t ecdsa -b 521 -f gitlab-deploy-key -C "deploy-key@gitlab.com"
(色々聞かれるので全てEnter)

暗号スイートはECDSAを指定、鍵長は521bitを指定、コメントは任意のコメントを入力する。以下のコマンドで鍵組(秘密鍵、公開鍵)が作成されたことを確認する。

$ ls -l /path/to/mykeys
gitlab-deploy-key
gitlab-deploy-key.pub

これ失くしたらヤバイので、紛失しないようにちゃんと管理すること。

Dockerの準備

Gitlab-CI実行時に起動されるDocekrの準備をする。Dockerイメージの登録先として、Gitlabにmydockerというリポジトリを作成しておくこと。

Dockerfileの作成

ローカルの任意の場所(以下/path/to/mydockerとする)で以下のコマンドを実行し、Dockerfileファイルを作成する。

$ touch /path/to/mydocker/Dockerfile

上記で作成したファイルに以下の内容を記述する。

FROM centos:7
MAINTAINER myname <myname@my_email_address>

RUN echo "include_only=.jp" >>/etc/yum/pluginconf.d/fastestmirror.conf && \
    rpm --import http://ftp.riken.jp/Linux/centos/RPM-GPG-KEY-CentOS-7 && \
    rpm --import http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-7 && \
    rpm --import http://rpms.famillecollet.com/RPM-GPG-KEY-remi

RUN yum -y install epel-release && \
    yum -y install http://rpms.remirepo.net/enterprise/remi-release-7.rpm && \
    yum-config-manager --enable remi-php72 && \
    yum -y update

RUN yum -y install wget git unzip

RUN yum -y install php php-mbstring php-pdo php-mysqlnd php-dom php-posix

RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

RUN composer global require "laravel/envoy=~1.0"

今回のDockerfileはLaravelプロジェクトとEnvoyコマンドが動く最低限の環境を構築するための内容になっている。他に必要なものがあれば上記のファイルに適宜追加してね。

Dockerfileをビルドしてイメージを作成

作成したDockerfileから以下のコマンドでDockerイメージを作成する。

$ cd /path/to/mydocker
$ docker build -t registry.gitlab.com/[Gitlabアカウント名]/mydocker .

-tオプションには作成するイメージ名を指定してる。ビルドに少し時間かかるかも(3〜5分くらい)。

DockerイメージをGitlab Container Registryに登録

GitlabにDockerイメージを登録するために以下のコマンドでGitlabにログインする。

$ docker login registry.gitlab.com
(Gitlabアカウント名、パスワードの入力を要求される)

ログイン後、以下のコマンドでDockerイメージを登録する。

$ docker push registry.gitlab.com/[Gitlabアカウント名]/mydocker

ここでも少し時間がかかる(3〜5分くらい)。特にエラーがなければ正常に登録されているはず。

なお、Gitlab公式ページではLaravelプロジェクト直下にDockerfileを作成してビルドしたDockerイメージをLaravelプロジェクトのGitlabリモートリポジトリに登録しているが、今回はDocker用にGitlabリモートリポジトリに作成してそこに登録している。こうすることで、他のプロジェクトでもDockerを利用することが出来る(こういう使い方していいのか分からんけど)。

Gitlab-CI設定ファイルの作成

Gitlab-CIではGitlab-CI設定ファイル.gitlab-ci.ymlに記述された内容に沿ってCIが実行される。以下のコマンドでLaravelプロジェクト直下(以下/path/to/myappとする)に.gitlab-ci.ymlファイルを作成する。

$ touch /path/to/myapp/.gitlab-ci.yml

上記で作成したファイルに以下の内容を記述する。

image: registry.gitlab.com/[Gitlabアカウント名]/mydocker

stages:
  - test
  - deploy

test_pupunit:
  stage: test
  services:
    - mysql:latest
  variables:
    DB_HOST: mysql
    DB_USERNAME: root
    MYSQL_DATABASE: homestead
    MYSQL_ROOT_PASSWORD: secret
  script:
    - cp .env.example .env
    - composer install
    - php artisan key:generate
    - php artisan migrate
    - vendor/bin/phpunit

.shared_hidden_key: &before_deploy
  before_script:
    - 'type ssh-agent || yum -y install openssh-clients'
    - eval $(ssh-agent -s)
    - ssh-add <(echo "$SSH_PRIVATE_KEY")
    - mkdir -p ~/.ssh
    - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" >~/.ssh/config'

deploy_stg:
  stage: deploy
  <<: *before_deploy
  script:
    - ~/.composer/vendor/bin/envoy run deploy_stg
  environment:
    name: staging
    url: [ステージング環境で公開してるURL]
  when: on_success
  only:
    - develop

deploy_prd:
  stage: deploy
  <<: *before_deploy
  script:
    - ~/.composer/vendor/bin/envoy run deploy_prd
  environment:
    name: production
    url: [本番環境で公開してるURL]
  when: manual
  only:
    - master

image項目では先ほどGitlabに登録したDockerイメージを参照してあげる。あとはテストの項目、デプロイの項目が順に記述されている感じ。あとデプロイ先毎に同じ内容の処理を記述するのがダサい感じがしたので、.shared_hidden_key: &before_deployの項目に処理をまとめて記述しておいて、各デプロイ先の処理部(deploy_stg, deploy_prd)に <<: *before_deployを記述しておく。これでなんとなくスマートな感じがする。

.gitlab-ci.ymlがローカルリポジトリに存在する状態でGitlabにPushするとGitlab-CIが実行されるようになる。しかし今の段階ではちゃんと動かないので、本ブログの手順を全て終えてから最後にPushしてね。

デプロイ用タスクランナー設定ファイルの作成

Gitlab-CIから呼び出されるデプロイ用タスクランナー設定ファイルEnvoy.blade.php/path/to/myapp直下に作成する。

$ touch /path/to/myapp/Envoy.blade.php

上記で作成したファイルに以下の内容を記述する。

@servers(['stg-host' => 'deployer@[ステージング環境のIPアドレス]', 'prd-host' => 'deployer@[本番環境のIPアドレス]'])

@setup
  $app_dir = '/var/www/myapp'
@endsetup

@story('deploy_stg', ['on' => 'stg-host'])
  pull_repository
  run_composer
  run_artisan
  run_npm
@endstory

@story('deploy_prd', ['on' => 'prd-host'])
  pull_repository
  run_composer
  run_artisan
  run_npm
@endstory

@task('pull_repository')
  echo 'Pull repository'
  cd {{ $app_dir }}
  git pull
@endtask

@task('run_composer')
  cd {{ $app_dir }}
  composer update
  composer install --no-dev --optimize-autoloader
@endtask

@task('run_artisan')
  cd {{ $app_dir }}
  php artisan down
  php artisan migrate
  php artisan cache:clear
  php artisan config:cache
  php artisan view:clear
  php artisan up
@endtask

@task('run_npm')
  cd {{ $app_dir }}
  npm run production
@endtask

デプロイ先(本番環境orステージング環境)でやること

デプロイ先(本番環境、ステージング環境)それぞれにログインして以下の作業を行う。

デプロイ用ユーザの作成と設定

rootユーザで以下のコマンドを実行し、デプロイ用のユーザを作成する。

root$ adduser deployer

どうせ公開認証方式でしかログインしないだろうからパスワードの設定しなくてもいいんだけど、念のため設定しておく。

root$ passwd deployer
(任意のパスワードを入力)

deployerユーザが/var/www下でリポジトリをClone・Pull出来るよう、以下のコマンドで権限を与える。/var/wwwがない場合は作成すること。

root$ setfacl -R -m u:deployer:rwx /var/www
GitlabからClone・Pullするための鍵組の作成

deployerユーザで以下のコマンドを実行し、GitlabからClone・Pullを行うための鍵組を作成する。

deployer$ mkdir -p ~/.ssh
deployer$ chmod 700 ~/.ssh
deployer$ ssh-keygen -t ecdsa -b 521
(色々聞かれるので全てEnter)

以下のコマンドで鍵組(それぞれ秘密鍵、公開鍵)が作成されたことを確認する。

deployer$ ls -l ~/.ssh
id_ecdsa
id_ecdsa.pub
リポジトリのCloneと設定

deployerユーザで以下のコマンドを実行し、GitlabからLaravelプロジェクトをCloneする。

deployer$ cd /var/www
deployer$ git clone git@gitlab.com:[Gitlabアカウント名]/myapp.git

CloneしてきたLaravelプロジェクト下にあるstorageにのみ書き込み権限を与える。

deployer$ chmod -R 777 /var/www/myapp/storage

chmodコマンドで-Rオプションつけて777って場所間違えたら大変なことになるので注意。

Gitlabからデプロイ先に接続するための鍵の設置

ここが少しややこしい。手順「ローカルでやること/Gitlabからデプロイ先に接続するための鍵の作成」で作成した鍵のうち公開鍵gitlab-deploy-key.pubをデプロイ先に設置する。以下のコマンドをローカルで実行し、公開鍵を転送する。

$ scp /path/to/mykeys/gitlab-deploy-key.pub deployer@[デプロイ先のIPアドレス]:~/

公開鍵認証使ってる人は上記のコマンドを実行すると特に何も聞かれずに実行完了するけど、使ってない人はパスワード求められるのでパスワードを入力する。さっき設定したパスワードがここで活きるというね、設定しててよかった(小並感)。

次に以下のコマンドをデプロイ先で実行し、転送されてきた公開鍵をauthorized_keysに記述する。あとは適切なアクセス権を付与することで、Gitlabからデプロイ先へ接続可能な状態になる。最後に、転送されてきた公開鍵を削除するのを忘れずに。

deployer$ cat ~/gitlab-deploy-key.pub >> ~/.ssh/authorized_keys
deployer$ chmod 600 ~/.ssh/authorized_keys
deployer$ rm ~/gitlab-deploy-key.pub

コマンドの実行場所(ローカルとデプロイ先)を間違えないように注意しよう。

Gitlabでやること

ここからはブラウザでGitlabのページを開いて作業を行う。ローカルにあるLaravelプロジェクト/path/to/myappのリモートリポジトリはGitlabに作成済みであるとする。

GitlabからClone・Pullするための鍵を登録

ここもややこしい。手順「デプロイ先でやること/GitlabからClone・Pullするための鍵の作成」で作成した鍵のうち公開鍵id_ecdsa.pubをGitlabに登録する。以下のコマンドをデプロイ先で実行し、出力された値をコピーする。

deployer$ cat ~/.ssh/id_ecdsa.pub
(なんか出力されるので範囲選択してコピーする)

LaravelプロジェクトのGitlabリモートリポジトリページからProject > Settings > Repositoryと辿っていき、Deploy Keysの項目で登録する鍵のタイトルを任意で入力、それと先ほどコピーした公開鍵の内容をペーストする。以下のような感じ。入力後はAdd keyボタンを押して登録する。

f:id:kkznch:20180620092240p:plain

Gitlabからデプロイ先に接続するための鍵の登録

またもやここもややこしい。手順「ローカルでやること/Gitlabからデプロイ先に接続するための鍵の作成」で作成した鍵のうち秘密鍵gitlab-deploy-keyをGitlabに登録する。以下のコマンドをローカルで実行し、出力された値をコピーする。

$ cat /path/to/mykeys/gitlab-deploy-key
(なんか出力されるので範囲選択してコピーする)

LaravelプロジェクトのGitlabリモートリポジトリページからProject > Settings > CI/CDと辿っていき、Secret variablesの項目で登録する鍵のタイトルに「SSH_PRIVATE_KEY」と入力し(重要!!)、先ほどコピーした秘密鍵の内容をペーストする。「Protected」のトグルはよく分からんけどオンにしておく。以下のような感じ。入力後はSave variablesボタンを押して登録する。

f:id:kkznch:20180620092412p:plain

鍵のタイトルに「SSH_PRIVATE_KEY」を入力したのは、手順「ローカルでやること/Gitlab-CI設定ファイルの作成」で作成したGitlab-CI設定ファイル内で環境変数として使用するため。鍵のタイトルとGitlab-CI設定ファイルに記述した環境変数名は統一すれば何でも良いのだけど、分かりやすいように今回はこのタイトルにした。

特定のブランチをProtected branch化

うおーーーーーそしてこれが最後の手順!Gitlab-CIでテストを実行した後、テストが通ったブランチをメインのブランチにマージしないよう設定する(正確にはマージリクエストが出来ないようにする、かな?)。

LaravelプロジェクトのGitlabリモートリポジトリページから、Project > Settings > Repositoryと辿っていき、Protected Branchesの項目でProtected branch化したいブランチを選択する。おそらく本番環境で使用するmasterブランチはデフォルトでProtected branchになってるので、今回はステージング環境で使用するdevelopブランチ辺りをProtected branch化する。以下のような感じ。

f:id:kkznch:20180620092236p:plain

Gitlab-CI実行

ここまで長い工程をお疲れ様でした。最後に、ローカルからLaravelプロジェクト/path/to/myappをPushし、Gitlab-CIが実行されるか確認しよう。このとき、本番環境にデプロイするならmasterブランチ、ステージング環境にデプロイするならdevelopブランチでPushする。最初に説明したが、developブランチはPushすると自動でデプロイされるが、masterブランチはPushしても自動でデプロイはされない。masterブランチをデプロイする際はLaravelプロジェクトのGitlabリモートリポジトリページからテストが通っていることを確認し、手動でデプロイすること。

$ cd /path/to/myapp
$ git push -u origin master

感想

主にGitlab公式ページを参考に作業を行ったが、実際に手を動かして理解できた。作業自体も時間がかかったが、この記事を書くのにも時間かかった...。自分のための記録として、また他の人の参考として、本記事が役に立つと嬉しい。間違い等があれば指摘おなしゃす、

参考