boto を使って Sphinx を S3 にデプロイする

やりたかったこと

毎回 AWS Console からデプロイするのはアホだし、ミスも生まれるので自動化したかった

結論

  • わざわざ S3 にデプロイする必要なんかなくて、レンタルサーバ借りて FTP でデプロイしても別に何も問題ありません。
  • いくつかの条件がマッチした場合はいいかもしれません。
  • 商用利用の場合はまずはレンタルサーバを検討しましょう
  • OSS の場合等は AppEngine または github/bitbucket などを活用しましょう。

S3 を使う条件とか

今回はいくつかの条件が当てはまったので .. S3 にしました

  • もともと会社が AWS のアカウントを持っていた
  • DNS の設定だけで良かった
  • そもそも1日100人くるサイトではない
  • 社内である程度確認作業をしたらさくっとデプロイしたかった
  • 商用製品サイトである

人気サイトは基本静的 HTML だけなんてサイトが無い気がするのでかなりレアですね。

ちなみに今のところ 1 日 5 円程度です、運用費用。

コード

boto は昔ちょろっとバックアップツールを作ったときに使ったことがあっただけで、それ以外は使ったこと無いので、かなり久々でした。

やってることは Sphinx のビルド済みのディレクトリからファイルを根こそぎ持ってきて S3 の指定したバケットにアップロードしているだけです。

ポイントというものはほとんどありませんが ... 以下の二点くらいは意識しました

  • 公開もセットでやる
  • reduced_redundancy も自動で設定

本来は github と連携して自動で checkout してビルドするくらいはやりたかったのですが、やめておきました。最終的にはそこまで行きたいですね。

import os
import os.path

from boto.s3.connection import S3Connection, Location
from boto.s3.key import Key

S3_ACCESS_KEY = 'access-key'
S3_SECRET_KEY = 'secret-key'

S3_BUCKET_NAME = 'bucket-name'

SPHINX_BUILD_HTML_DIR = '/path/to/doc/build/html'

if __name__ == '__main__':
  connection = S3Connection(S3_ACCESS_KEY, S3_SECRET_KEY)
  try:
    bucket = connection.get_bucket(S3_BUCKET_NAME)
  except:
    bucket = connection.create_bucket(S3_BUCKET_NAME, location=Location.APNortheast)
    bucket.set_acl('public-read')
    bucket.configure_website('index.html')

  for root, dirs, files in os.walk(SPHINX_BUILD_HTML_DIR, followlinks=True):
    for filename in files:
      full_path = os.path.join(root, filename)
      path = full_path.replace(SPHINX_BUILD_HTML_DIR, '')
      key = Key(bucket, name=path)
      key.set_contents_from_filename(full_path, reduced_redundancy=True)
      key.make_public()
      key.close()
      print path, 'uploaded'

  print 'url:', bucket.get_website_endpoint()

感想

boto 良く出来てますね、さすが AWS 人気とも言えるのか、サンプルコードも結構あったりして助かりました。
これで boto さえ入っていれば python スクリプトを叩くだけでデプロイが出来ます。ありがたい。
git-flow 使っていれば master ブランチを定期的に監視してデプロイとかもいいかもですね。

ただ S3 を使うメリットってそんなに無いんですよね ... 課金もある程度かかりますし。

今回は偶然マッチしたという位だと思います。