タイトルのOSSは
ソースコードを公開している=OSSという解釈で付けています
作ったサービス
- 公開しているサービス内容自体は、この記事の本質では無いので、クオリティの参考程度だと思って下さい。
- サービス云々の話はブログで記事にしているので、こちらをどうぞ( http://wheatandcat.hatenablog.com/ )
なので内容が、ただのオタクの掃き溜めなのはスルーして下さい
作ったサービスの内容
- 記事を投稿できる
- 書いた記事を読み上げる機能がある(読み上げはopen-Jtalk)
- SPAである
- サービスとして運営できる最低限の機能は実装済み(のはず)
公開ソースコード
サーバーサイド
・https://github.com/wheatandcat/dotstamp_server
クライアントサイド
・https://github.com/wheatandcat/dotstamp_client
環境構築
・https://github.com/wheatandcat/dotstamp_ansible
デプロイスクリプト
・https://github.com/wheatandcat/dotstamp_deploy_script
デプロイ環境構築
・https://github.com/wheatandcat/dotstamp_deploy_ansible
※実行手順はREADME.mdに記載
この記事を読む前に
このサービスは一人で開発したものです
go言語、react、ansibleは、今回初めて触れました(開発期間は学習も含めて半年くらい)
コードは、その程度の信頼度です
公開していソースも実装内容も、あくまで個人開発規模での内容です(ここ重要)
ってことで、この記事では
各リポジトリの説明と実装方法について記載します
全体構成(ザックリ)
-
サーバーサイド
- 言語
- Go
- フレームワーク
- beego
- テスト
- gocheck
- goconvey
- 言語
-
クライアントサイト
- 言語
- es6
- jsライブラリ
- react
- redux
- テスト
- jest
- css
- post-css
- コンパイラ
- webpack
- 言語
-
環境構築
- ansible
-
web
- nginx
-
db
- MariaDB
-
デプロイ方法
- supervisor + nginxで、ブルーグリーンデプロイ
サーバーサイド
概要
リポジトリ:https://github.com/wheatandcat/dotstamp_server
言語:Go言語
APIサーバ(+トップのhtmlのみview活用)
サーバーサイド構成
フレームワーク
beego
フルスタックフレームフーク
ドキュメント豊富
が、今回の用途はAPIサーバなのでフルスタックなフレームワークを選んだのはミスですね ・・・orz
注意
日本語化されているドキュメントに、beedbの使用例がありますが、
beedbは既に非推奨になっているので注意
beedb: https://github.com/astaxie/beedb
DB
gorm
ORMラッパー
ドキュメント豊富
バリデーション
validator
バリデーション。
以下みたいに書くと、フォームパラメータをコードを汚さずバリデートできてイケてる
// NewRequest 新規リクエスト
type NewRequest struct {
Email string `form:"email" validate:"required,email"`
Password string `form:"password" validate:"min=8,max=100"`
}
func (c *NewController) Post() {
request := NewRequest{}
// ここでフォームの値を取得
if err := c.ParseForm(&request); err != nil {
c.ServerError(err, controllers.ErrCodeCommon, 0)
return
}
// ここでバリデーション
validate := validator.New()
if err := validate.Struct(request); err != nil {
c.ServerError(err, controllers.ErrCodeCommon, 0)
return
}
テスト
実装状況
- モデルとライブラリはユニットテスト
- コントローラはhttpテスト(現状は正常系のみ実装)
- テストDBデータはフィクスチャで挿入
- カバレッジは、40%くらい
- Go Mockとか使えば、カバレッジ100%にできるかも?ここは、まだ手つかず
├── conf
├── controllers
├── db
├── logs
├── models
├── resources
├── routers
├── static
├── tasks
├── tests
│ ├── controllers ← コントローラーのテスト
│ ├── database
│ ├── files
│ └── resources
│ └── fixture ← テスト前に挿入するDBデータ
├── tool
├── utils
├── vendor
└── views
gocheck
フィクスチャをサポートしているのでDBの初期設定に使用
データは、ymlで用意してテスト前にインサート
注意
フィクスチャでデータ挿入を実装すると、並走は使用できなくなるので、
go testのオプションに「-p 1」が必須になる
goconvey
goの自動テスト
ソースコードがでかくなったので、最近はあまり使ってない
その他ツール系
パッケージ名 | 内容 | リンク |
---|---|---|
glide | パッケージ管理 | https://github.com/Masterminds/glide |
goose | Go言語製のマイグレーション | https://bitbucket.org/liamstask/goose/ |
dbweb | Go言語製のdbクライアント | https://github.com/go-xorm/dbweb |
クライアントサイド
概要
リポジトリ:https://github.com/wheatandcat/dotstamp_client
言語:es6
クライアントサイド構成
jsライブラリ
react + redux
表示制御に使用
react-bootstrap
https://github.com/react-bootstrap/react-bootstrap
reactのBootstrapコンポーネント
サイトのクオリティがある程度に保てているのは、これのおかげ
react-router
reactのルーティング制御。react使うなら、ほぼ必須
また、react-bootstrapと合わせて使うなら、
react-router-bootstrapも必須
isomorphic-fetch
httpアクセス
reduxのチュートリアルで、使っていたので採用。
でも、よく読んだだらGraphQLのサンプルだったので、RESTは、他にも選択肢があるかも
css
postCss
cssパーサー。sassよりも手軽
css-loader
webpackの一機能。jsにcssを組み込める
実装例は検索すればHITするので省略
「react-bootstrap + css-loader」の組み合わせで、
デザインによるコード汚染を抑制できる
テスト
jest
テストフレームワーク
起動が遅いけど、基本「--watch」しているので、あまり気にならない
css-loader使用時は、以下の通りに実装
https://facebook.github.io/jest/docs/webpack.html
実装方法はreduxのドキュメントが一番参考になった
http://redux.js.org/docs/recipes/WritingTests.html
環境構築
概要
リポジトリ:https://github.com/wheatandcat/dotstamp_ansible
ローカル環境構築と本番(デプロイ関係以外)の環境構築
ローカル環境は、vagrantで構築
ツール:ansible
構築している内容一覧
基本的には、「galaxy.ansible」から導入。無いものは自作
https://galaxy.ansible.com/
名前 | 使用内容 | 環境 | 備考 |
---|---|---|---|
MariaDB | データベース。アプリのデータ管理 | 両方 | 全文検索にMroongaを使用 |
redis | キーバリューのDB。セッション管理に使用 | 両方 | |
open-jtalk | 日本語読み上げ | 両方 | |
sox | 音声ファイル結合 | 両方 | |
lame | wav→mp3に変換 | 両方 | |
Go | サーバーサイドのビルド | ローカル | 本番はバイナリ実行なので不要 |
nodejs | クライアントサイドのコンパイル | ローカル | 本番はビルド済みのファイルを同期するので不要 |
ntp | vagrantの時間合わせ | ローカル | |
nginx | webサーバ | 本番 | ローカルはbeegoに直接アクセスするので不要 |
supervisor | Goのバイナリ実行をデーモン化 | 本番 | 同上 |
firewall | アクセス制限 | 本番 | |
logrotate | ログのローテション | 本番 | |
mysqldump | DBバックアップ | 本番 |
Mroonga
MySQLのプラグイン
DBの全文検索に使用
デプロイスクリプト
概要
リポジトリ:https://github.com/wheatandcat/dotstamp_deploy_script
デプロイに必要なファイルを同期するバッチを管理
デプロイしているリポジトリはプライベートにしているので、アクセス不可
内容
以下のコマンドを実行で、デプロイリポジトリにファイルを同期
sh ./bin/deploy.sh
- 実行内容
- goをビルドしてバイナリを同期
- goのバイナリと外部で呼んでいる以下のファイルを同期
- viwe
- config(環境設定ファイル)
- static(外部から参照できる静的ファイル:画像等)
- resources(内部から参照するファイル:csvファイル等)
- jsをwebpackでコンパイル
- 本番設定を適用
- jsを難読化
- jsをgzipで圧縮
- コンパイルしたjsファイルを同期
ここで同期したファイルをコミットして、本番環境に反映しています
デプロイ環境構築
概要
リポジトリ:https://github.com/wheatandcat/dotstamp_deploy_ansible
デプロイするために必要な構築系を管理
デプロイはブルーグリーンデプロイを採用
対象は本番サーバー
ツール:ansible
構築内容
- 本番環境にブルーとグリーンの環境構築(デプロイリポジトリから2つのフォルダ作成)
- supervisorにブルーとグリーンのデーモンを設定
- ブルー or グリーンは、環境変数で切り替えている
- 構築時はブルーは起動。グリーンは停止状態
- ブルーとグリーン切り替え用のnginxの設定を追加
- 上記のnginxの設定を切り替えるバッチを作成
デプロイ実行
以下のコマンドを実行で、デプロイする
※以下は、サーバー1台構成用の内容です。ロードバランサの使用は考慮していないので、ご了承下さい
sh ./deploy.sh
- 実行内容
-
グリーンの環境を起動
- supervisorctl start green
-
nginxの設定をグリーンの環境書き換えてreload
- cp -r /xxx/nginx_green.conf /etc/nginx/conf.d/xxx.conf
- nginx -s reload
-
ブルーの環境を停止
- supervisorctl stop blue
- ブルーの環境に最新のバイナリ + 静的ファイルを同期
-
ブルーの環境を起動
- supervisorctl start blue
-
nginxの設定をブルーの環境書き換えてreload
- cp -r /xxx/nginx_blue.conf /etc/nginx/conf.d/xxx.conf
- nginx -s reload
-
グリーンの環境を停止
- supervisorctl stop green
- グリーンの環境に最新のバイナリ + 静的ファイルを同期
-
グリーンの環境を起動
ただし
上記だけだと、利用中のユーザーのjsが最新にならないので、
真面目にやるなら、jsのバージョン管理 + サーバーから最新のjsバージョンを返却
ローカルのjsのバージョンと差異があったらリロードするを実装する必要があります
(リポジトリは、そこまでは実装していない)
まとめ
以上、ここまで実装する + 本番vpsの設定 + gitのREADMEの整理で、
OSSで個人開発規模サービス運営が開始できます!!(たぶん)
また、今回の開発では時間の制約で省きましたが、本来ならば以下も考慮したいところですね
- 負荷検証
- サーバー監視
- MySqlチューニングツール
- クライアントのレンダリング測定ツール
時間は無限にある訳では無いので、個人開発では難しいところではありますが・・・