Jenkinsを使ったSphinxとS3によるドキュメントサイト構築
渡辺です。
開発者の間ではgithub式Markdownでドキュメントを書くのが主流となっている昨今ですが、エンドユーザ向けのドキュメントとなると出力フォーマット・版管理・クロスリファレンスなど、機能的にもう少し欲しいところです。しかし、Wordといった専用の文書作成ソフトを使うほどでもないし、表計算ソフトを使うのは論外だと思われます。
そんな要求を満たすツールはSphinxです。今回は、Sphinxを利用してドキュメントを生成し、Jenkinsによる自動ビルドでHTML形式のファイルを作成し、S3へのリリースする手順を解説してみます。Sphinxは静的ファイルを生成するため、S3やCloudFrontと相性良く利用できるソリューションです。
Sphinxとは?
Sphinxは、ドキュメント生成ツールです。SphinxではPythonで採用されているreStructuredText(reST)で記述します。reSTはMarkdown記法のひとつで、他のMarkdown記法と同様に見出し・強調・リスト・リンク・表組みなどをプレインテキストで表現します。
Sphinxのインストール
SphinxはPythonの実行環境がインストールされているのであれば、easy_installで簡単にインストールできます。
$ easy_install sphinx
プロジェクトの作成
Sphinxのプロジェクトはsphinx-quickstartコマンドで作成します。
$ sphinx-quickstart
ウィザード形式でドキュメントの名前や作成者などを入力すればプロジェクトが作成されます。設定内容を後から変更する場合は、conf.pyを編集してください。
マスタードキュメントの作成
Sphinxでは構造化されたドキュメントを構築できることが大きな特徴です。見出しなども自動的に作成されるため、マニュアルといった明確な構造を持ったドキュメントが作りやすくなっています。
はじめにマスタードキュメント(index.rstファイル)を開き、ドキュメントを追加しましょう。具体的には、toctreeディレクティブに追加するドキュメントのファイル名(拡張子無し)を追記します。例えば、firststeps(最初の1歩)とfeatures(機能概要)を追加すると次のようになります。
.. toctree:: firststeps features
このtoctreeディレクティブは、ビルドされた時にドキュメントの目次となります。
ドキュメントの追加
続いてドキュメントを追加していきます。
firststeps.rst
最初の1歩 ======================== アプリケーションXへようこそ。 ここでは初めてXを使う方向けに、簡単な使い方を解説します。
features.rst
機能概要 ======================== 機能概要です。
それぞれ、1行目から2行目がドキュメントの見出しになります。このようにrSTでは=などの文字を連続で記述した時に見出しとなる仕様です。 各ドキュメントで最初に作った見出しは、自動的に収集されてマスタードキュメントの目次となります。
その他のrST記法については、ドキュメントを参照してください。勿論、このドキュメントもSphinxで作成されています。
ドキュメントのビルド
ドキュメントをビルドするには、引数に出力するフォーマットを指定し、makeコマンド(Windowsの場合はmake.bat)を使います。例えばhtml形式で出力するにはmake htmlとコマンドを実行するだけです。
ビルドが成功するとbuild/htmlディレクトリにhtmlとして出力されます。
Makefileの修正
デフォルトではビルド先はプロジェクトを作成した時に設定されるビルドディレクトリ(デフォルトはbuild)に生成されます。通常はデフォルト設定で構わないのですが、今回はJenkinsサーバ上でビルドする時に特定のディレクトリに出力したいため、Makefileを次のように修正します。
修正前
BUILDDIR = build
修正後
ifndef BUILDDIR BUILDDIR = build endif
これで環境変数BUILDDIRが設定されている場合は、環境変数BUILDDIRがビルド出力先になります。
S3バケットの作成
今回はドキュメントをS3にアップロードして公開するため、はじめにS3バケットを作成します。
S3バケットを作るには、AWS Consoleにログインし、S3のメニューから「Create Bucket」をクリックし、Bucket Nameを入力するだけです。
また、S3のデフォルトでは外部からのアクセスを許可していません。Bucket PolicyにAnonymous Userからの接続を許可するようなポリシーを追加します。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "AddPerm", "Effect": "Allow", "Principal": { "AWS": "*" }, "Action": [ "s3:GetObject" ], "Resource": [ "arn:aws:s3:::BUCKET-NAME/*" ] } ] }
最後にS3ではアップロードしたファイルをWebページとして公開する機能(Static Website Hosting)があるので、これを有効にしておきましょう。
独自ドメインを利用する
S3バケットは作成時点でホスト名を割当てられますが、独自ドメインでアクセスさせたい場合はRoute53を利用します。 独自ドメインをRecord Setとして登録し、CNAMEとしてS3バケットのエンドポイントを設定してください。
CloudFrontを利用する
S3のStatic Website Hostingを使わずにCloudFrontを利用して公開する方法もあります。この場合はキャッシュが有効になることがメリットでありデメリットとなるでしょう。アクセス数や更新頻度から選択していくと良いと思います。
Jenkinsによるビルドの自動化
SphinxドキュメントのビルドはJenkinsをインストールしたEC2インスタンスで行います。EC2からS3にアクセスするために、あらかじめIAM Roleを作成しておくとアクセスキーやシークレットキーを使わずに済むため、安全で、かつ便利です。
なお、SphinxドキュメントのソースはGithubやStashなどを利用してバージョン管理しておきましょう。プレインテキストなのでGitなどを利用してバージョン管理しやすいこともポイントです。
IAM Roleの作成
IAM RoleはAWS ConsoleのIAMメニューから、Rolesを選択し、「Create New Role」で作成します。Roleの名前はec2-jenkinsなど適当につけてください。
適用するRoleはTemplateにあるAWS Service Role/Amazon EC2 のAmazon S3 Full Accessで良いでしょう。
EC2インスタンスの作成
先ほど作成したIAM Roleを使ってEC2インスタンスを作成します。EC2インスタンスを作成したらJenkinsをインストールしましょう。
AWS-CLIのアップデート
Amazon LinuxはデフォルトでAWS-CLIがインストールされています。しかし、バージョンが古く、今回使うS3へのsyncコマンドがないバージョンの可能性があります。EC2を起動したならばログインし、AWS-CLIをアップデートしてください。
$ sudo easy_install --upgrade awscli
Sphinxのインストール
JenkinsサーバにもSphinxをインストールしておきます。
$ sudo easy_install sphinx
ビルド用プロジェクトを作成する
Jenkinsでフリースタイルプロジェクトを作成します。バージョン管理とビルドトリガーはお好みで設定してください。
ビルド設定
シェルスクリプトでビルド手順を追加します。
Jenkinsのワークスペースにビルドすると同期させるのが面倒なので、ここでは/var/dist/docsをビルドディレクトリとして指定しました。
export BUILDDIR=/var/dist/docs make clean html
/var/distは777パーミッションで予め作成しておきましょう。
2つ目のビルド手順としてシェルスクリプトを追加し、S3との同期を行わせます。
aws s3 sync --region ap-northeast-1 /var/dist/docs/html/ s3://BUCKET-NAME
まとめ
簡単にドキュメント作成から公開までのフローを自動化できました。ドキュメントを公開するためにWordpressやMovable TypeといったBlogシステムをインストールすることもひとつの手かと思いますが、開発者主導で行うのであれば、Sphinxを使って自動化する方がしっくりと来るのではないでしょうか?
また、CMSやWikiと異なり静的ファイルのホスティングとすることで、スケールしやすくなります。Sphinxによるビルドを行うサーバは小さなインスタンスで済むため、アクセスが多いケースなどでは効果的なコスト削減になるでしょう。ひとつの選択肢として、Sphinx + S3という選択は素敵だと思います。