Explore the Snark

UI Design, Game graphics, Programmingとか. Photoshopとか.

Flaskでブログエンジンを作ってデプロイするまでのまとめ

Category: Python Tags: Flask Tags: Create

本業は別なので、強制的に色んなことの勉強をするためにLogpotというシンプルなブログエンジンを作った。このブログがそう。ちまちま進めてきて、かなり前に大体出来てデプロイも済んでたけど、忙しくて細かいところ直すのに今になってしまった。

Logpot

とりあえず完成ソース: moremorefor/Logpot

とその付属物

機能としては、カテゴリとタグ(…ページはまだ無い)、複数画像アップロード、Markdown、コードハイライト、RSS、OGPなど。ブログ記事のURL(Wordpressでいうslug)と画像アップロード先のディレクトリ名を一緒にしたくて、そういう感じにしてあるけど、現状ちゃんとそういう仕組みに出来てなくて、記事を上げてからしか画像がアップできないというダメな感じになってしまっている。いずれ直す。


以下、勉強したこと

  • FlaskとそのExtension周り
  • タスクランナーにGulpを使う
  • Sassの設計
  • サーバーセットアップ
  • Ansibleでその自動化(+Vagrant)
  • アプリケーションサーバー

一通りやりたかったことは出来て色んな知識がついたと思う。

FlaskとそのExtension周り

Django使えばブログっぽいものはすぐ出来るだろうけどそれじゃ勉強の意味が無い。なのでFlaskで作る。

今までもトークン発行用に使ったり、Twitterクローン的なものをちょっと作ったりしてたけど、そこまで構造化とか考えて使ったこと無かったので、いろんなモジュール入れてちゃんと使ってみたかった。

Flaskのことについてはこの辺の本とか記事、コードを参考にさせてもらった。特にBlueprintで分割したり、循環importにならないようにアプリ全体をどういう構造にすればいいのかは大変参考にさせていただいた。日本語の情報は貴重でありがたい…。

記事

Github


次に、使ったExtensionはこの辺

Extension

管理画面作るのにはFlask-Adminを使ってみた。Flask-Adminは結構更新されてて、時間が空くと互換性無くなってる時とかあって泣けた。 ドキュメントも微妙に古かったり詳しく書いてなかったりして、わからない時はソース読んだりすることにもなった(ある意味勉強的には良かった)。

Flask-Admin

html側は結構Flask-Admin内のテンプレートを流用して改変する感じにしたら融通効かない感じになってまだデフォルトっぽいところから抜け出せず少し使いにくい管理画面になってる。逆に、慣れるとテンプレート的な画面ならすぐに作れるのはめちゃくちゃ楽。

あとはMarkdownのレンダーにはmisakaを使い、RSSにはfeedgenを使ってみた。

タスクランナーにGulpを使う

Gruntを使っていたけどこの機会にそれをGulpに乗り換えた。一番やりたかったのは、再利用&わかりやすいようにタスクごとのファイルに分けるのと、設定を1ファイルにまとめることだった。

勉強にはこの記事群を最初から読んでいくのが一番分かりやすかった。

特にこの記事に知りたかったことが書いてあったので、この記事を応用した形で利用させていただいた。

で、雛形として完成したのが付属物その1: moremorefor/gulp-bourbon-skeleton

その後色んなプロジェクトで調整しながら使っている。便利。

今回のブログでは、static内だけをgulpで処理するように雛形をちょっとだけカスタマイズした。gulpコマンドはProcfileに書いておいて、ForemanのPythonクローン honcho を叩いてFlaskアプリと一緒に起動するようにしている。

Sassの設計

Sassのライブラリには前から Bourbon を使っていて、Sassはそのサンプルで紹介されていた構成にして使っていたけど、そろそろ真面目にCSS設計を勉強しないとなと思って今回考えた。

とりあえずこの本を読んで改めて基本を理解した。前後のページを行き来して見たい場面が多くてKindleで買ったのは失敗だった…。

で、結果的に FLOCSS がいいかなと思い、ちょうど別のプロジェクトもあったのでそっちで先に試してみた。

が、だが書いてみるとめんどくさい。規模が大きくないプロジェクトにはこんなに細かい必要はないと思い直して、結果、このブログではディレクトリを4つのレイヤーに区切るだけにした。Class名についても自分なりのやり方をまだ検討中…。

とりあえず今回は手を付けたということでOKとして、あとはMarkdownのサンプル一覧を用意して、それぞれの要素用のcssを 作成した

Markdown

サーバーセットアップ

かなりわかっていることが少ないところから始まった。少しはやったことあったけどどっから手を付けたらいいのかわからない。ので、とりあえず手を動かさないと無理だなと思い、この2つの記事をベースに一通り手を動かしてみた。動かした内容はすべてメモしておいた。

その後、そのメモの中から今回に必要な処理を書き出して & 追加で調べていって(特にセキュリティ周りなど)、それをまとめた。

  • epel.repoの追加
  • ユーザーの作成
  • etckeeperの導入
  • authorized_keyの追加
  • sshの設定
  • rootログイン・パスワードログインの禁止
  • iptablesの設定
  • Nginxのインストール・設定
  • などなど…

だが初心者の自分がこれをこのままVPSとかに構築していってもいずれ絶対に失敗することが目に見えている。ので次の段階に進む。

Ansibleでその自動化 (+Vagrant)

失敗しても環境をいくらでも作り直し、ほぼ自動的に失敗した地点まで戻せるように、VagrantでCentOSの環境を作り、Ansibleのplaybookに処理を逐一書いていって、それを適用して試すという方策をとった。

ということでまずはAnsibleの基本を勉強する。

基本を抑えたところでどんどんplaybookに書いて適用して試していく。最初はmain.yml一個を用意してそこに全部書いていって、あとでベストプラクティスのRoleに分割していった。

最終的にインストールしたのはこの辺

  • Nginx
  • nodebrew & Node 0.12.7
  • Python 3.4 & virtualenv
  • rbenv & Ruby 2.2.2
  • PostgreSQL 9.4

このやり方、初心者的にはいつでも試していた時点に戻せる環境があるという心強さが一番ありがたかった。

で完成したのが付属物その2: moremorefor/ansible-playbooks

問題

だがしかしハマりどころも多かった。

  1. まずVagrantと一緒にAnsibleを勉強しだしたので、上手くplaybookが適用されない時に、ssh周りの設定で詰まることが多かった。

  2. 次に、未だにわかってないのが、本当に最初からVagrant上にplaybookを適用すると、sshの設定をした後で当たり前だが繋がらなくなる。ので全部で

    $ vagrant up
    $ vagrant ssh-config > ssh.config
    $ ansible-playbook -i hosts setup.yml (一度目)
    
    ・vagrantfileのsshの設定を変更
    ・private_keyを削除
    
    $ vagrant reload
    $ vagrant ssh-config >! ssh.config
    $ ansible-playbook -i hosts app.yml (二度目)
    

    という手順を踏まないといけなくなる。めんどくさい。これ普通どうしてるんだろう?

  3. 最後に、Vagrant上のCentOSに、iptablesの設定でプライベートIPアドレスを弾く設定をすると、設定後、Vagrantにsshが通らなくなる。今となってはなるほどという感じだけど…。

アプリケーションサーバー

最後にアプリをデプロイするに辺り、アプリケーションサーバーをどうするかという問題に当たった。例に違わずとりあえず参考になりそうな記事を元に手を動かす。

これをやってみてuWSGI+Nginxはわかってきたが、Gunicornが気になったのと、もしエラーなどでアプリが落ちた時の死活監視を考えないといけないことに気づきSupervisorを試してみた。

結果、Gunicornが良さそうだったので乗り換えたのと、Python3.4だとSupervisorが上手く動かなかった…。調べた結果、代わりに Circus が良さそうということで、最終的にCircus+Gunicorn+Nginxで行くことにした。静的ファイルはNginxで返して、ソケット通信でGunicornとやり取りしてる。

Mackerel あとは、監視ツールとしてMackerelを入れてSlackと連携し、とりあえずOKということにした。デプロイはAnsibleでやったけど、結局まだ手動でやらないといけないことも残っているので、今後はデプロイの自動化を考えないといけない。

まとめ

ちまちまと色々勉強してきた。勉強した結果、このブログの他に、Photoshopと連携する各種自作ツールなどを自分でサーバーに置いて使えるようになって、仕事の効率がかなりアップしたりしている。良い。(注:一応ある程度セキュリティにも気をつけてる)

まだ、カテゴリページ作ったり、DBの定期バックアップするとかやらないといけないことが残っているので、ちまちま作りながらこのブログも更新していきたいと思う。