こんにちは、ピクスタ開発部の星直史( id:watasihasitujidesu )です。 idがwatasihasitujidesuですけど、執事ではありません。エンジニアです。
先日、ピクスタのローカル開発環境構築の自動化方法をコンペで決定しました。 今回は、そのときに各エンジニアが発表した"オレが考える最強の構築方法"と、結果について書きます。
目次
- 背景
- エントリー
- Docker Compose
- Chef Zero
- Ansible
- 結果
- まとめ
背景
ピクスタの開発環境は、主にAWSのEC2を利用していました。 ローカルでも開発環境を構築できますが、多くのエンジニアは利用していませんでした。
しかし、最近はIDE(RubyMine)を使用するエンジニアも増え、ローカルで開発環境を構築することが増えてきました。 Macでの開発環境構築は、手順者こそあるものの、更新頻度や粒度がマチマチであったため、新しく入社する方も一通り動かすのに丸一日(!)かけて構築していました。
その結果、下記の問題が散見されるようになってしまいました。
- ◯◯さんのPCでは動くけど△△さんの環境では動かない
- hogehoge コマンドの実行漏れによるエラー
- MacOSをアップデートしたら動かなくなった
そこで、開発部のメンバーが増えたことや、今後の運用の手間の軽減を考慮して、今回のコンペを実施する運びとなりました。
エントリー
コンペ実施にあたり、イカれたメンバーを紹介するぜ!
Docker Compose
選んだ理由
PIXTAのサービスは複数のマイクローサービスで構成されており、各マイクロサービスごとにDocker Image を作成して動かせないかなと考えていました。
また以下の点を踏まえて、以前から調べてみたいなと思っていた Docker を選択しました。 - 壊れたときに再構築が容易であること - EC2インスタンス、ローカル環境(個人PC)等で差がなく開発できること - なるべくホスト環境は汚さなくしたい
ただ、マイクロサービスごとに Docker Image を作成する場合、個々で連携させる必要があります。 そこで Docker Compose をつかって、Docker Image を連携させようとしました。
良かったところ
Docker Compose の連携の部分
Docker Compose の設定内容は docker-compose.yml
に記載していきます。
PIXTA本体に対して各マイクロサービスをリンクさせていく方法をとりました。
version: "2" services: web: . . depends_on: - "db" - "pixta-search" - "pixta-lightbox" pixta-search: . . pixta-lightbox: . .
コマンドを実行して、連携させるのではなく、こういった設定ファイルに対して記述していけるということで 個々の連携であったり、修正だったりが容易になるのかなと思いました。
ポートフォワーディングやボリュームマウント等、できることは数多くあるようなので、 以下のドキュメントを見ながら、目的のものがないか探していました。
https://docs.docker.com/compose/compose-file/
悪かったところ
Dockerfile の管理・運用
スクリプトファイルと同じで、上から下へと実行するコマンドをずらずらと並べていくスタイルになります。
PIXTAのサービスとして必要なパッケージ類は予めまとめておき、 個々のマイクロサービスでは追加のパッケージを入れるというスタイル等、うまくやっていかないと修正等が苦になりそうで不安です。
変更されるファイルの管理
ソースコード等、変更されるファイルをどこに保管しようかということに長い時間悩みました。 今回は、Docker Image 上でソースコードのダウンロード・修正等を行うことにしました。
ただ、Docker Image を作り直すと環境設定(エディタ等)が削除されてしまうので、将来的には、変更があるファイルについては保管できる、もしくはホスト側のファイルをマウントする形をとりたいなとは思っています。
Chef Zero
選んだ理由
私、kaibaは前から興味のあったChefにチャレンジしました。 僕はこの手のツールに疎く、今回がはじめてだったのもあり、以下の理由でChefに挑戦しました。
- PIXTAでも使われており、覚えておくと役立ちそう
- 多くの環境構築ツールが影響を受けている(と初心者ながら感じた)
自分のMacにはすでに開発環境が整っており、壊すのが嫌だったのと、MacOSのアップデートに悩まされるのが嫌だったので、今回はVagrantのCentOS7に構築することにしました。 僕はRubyMineユーザなのでローカルに環境があるのはありがたいのですが、rsyncやNFSを使ってVM上で開発できないかと目論んでいました。
良かったところ
僕は料理が好きなのもあり、料理人(Chef)が料理本(Cookbook)のレシピ(Recipe)を調理器具(Knife)を使って作っていく、というのはどこに何があるか分かりやすかったです。 シェルスクリプトよりずっと見通しが良くなります。
悪かったところ
僕は既存の環境構築手順を忘れ、Chef Zeroで作り直す、という方法を採りました。 自分で全てのCookbookを書くのは面倒なので、Berkshelf(他の人が書いたCookbook)を使おうとしました。 しかし、既存の環境構築手順を実現するためには、何をするにもカスタムCookbookの使い方を調べなければならず、思うように進まず、多くの時間を費やした上、目的を達成できませんでした。 このアプローチではなく、既存の手順書をChefに変換していくようなアプローチが正解だったと思います。 その他の良くなかったことと感じたところは以下です。 - Berkshelfには十分にメンテされていないものも多い(issue山積みなど) - Chef Soloなど古い情報が錯綜している感があり、混乱を招いた
Ansible
選んだ理由
Mac用モジュール(homebrew_cask
)やRailsを動かすためのモジュール(gem
)などが揃っており、Macでの開発環境構築においては必要十分だと思い、Ansibleを選びました。
また、保守運用や中途入社の方を意識して、学習コストがなるべく低いものにしたかったのもAnsibleを選んだ理由の一つです。
良かったところ
必要な知識はymlの構文と、実行コマンド数種類だけなので、 慣れるとgoogleで「ansible やりたいコマンド名」で検索して、1個目の記事見れば、サクサク進めることができたのは、学習コスト低さの裏付けになりました。
またbrew install
でpython
とansible
さえ入れれば、Playbook
をgit clone
して実行できる導入しやすさも良かった点として挙げられます。
悪かったところ
デバッグのやりにくさと、Macのバージョンアップに弱いのではないか?という懸念が挙げられます。
Ansibleはdry run(-C オプション)があるのですが、Passenger インストール後のロードモジュールをconfに書いたtasksの後のhandlersでのapache起動などは、ロードモジュールの実態がないのでdry runでは失敗してしまい、デバッグのやりにくさを感じました。
また、中途入社の方には新しいMacが貸与されているのですが、そのPCには最新のOSバージョンが入っているわけで、OSのバージョン差異が吸収できない問題が発生しそうだという懸念があります。 動作確認が済んでいるOSのバージョンにおいては、威力を発揮するが、仮にコケてしまった場合のフォローは不可避かと思います。
とはいえ、Ansible自体の学習コストは低いので、すぐに乗り越えられる壁だとは思うので*1、ローカル環境構築においてはAnsibleで必要十分かと思います。
また、調べていくなかで、Ansible ベストプラクティスなるものがあり、それについてまとめた記事を作成しました。
結果
"Macのローカル環境を構築する"という目的はどれも概ね達成できていました。 その上で、どれを採用するか議論した結果、Dockerが採用されました。
議論を進めていく中で、開発環境だけではなく、プロダクション環境に対しても視野を広げました。 現状のプロダクション環境では、サーバーリソースの有効活用や、Passengerからnginxへの移行を計画しています。 また、それらを解決できる技術としてDockerが有力であるため、ローカル開発環境でも並行して調査、運用してみて、いずれプロダクション環境にも適用していくことになりました。
↓コンペの様子です!
まとめ
導入する技術選択をコンペ形式にしたのは、初の試みでした。 個人としては、自分で選択した技術の習得ができるので、単純にスキル幅が広がったと思います。 また、開発部としては、各メンバーが、選択した技術の概要、選択した理由、メリットデメリットが共有されることや、エントリーされた技術の中から、現状の課題や今後の運用を踏まえて、メンバーで議論できるので、最良の技術選択ができる良い機会になると振り返っています。
ピクスタでは新しい技術を学んでいきたいエンジニアを募集しています! recruit.pixta.co.jp
↓優勝者のI氏
*1:私は