最近Sphinxを使って自分用のドキュメントをまとめているのですが、Sphinxの静的コンテンツを自動でAmazonのS3へデプロイできる方法が紹介されていました。
https://dev.classmethod.jp/articles/sphinx_auto_deployment_to_aws_s3/
今のところ自分の用途は、自分のローカルPCの中でDocker+Sphinxを使っているだけなので、AWSのS3にデプロイする必要はないのですが、AWSへの自動デプロイというものがどんなものかと試してみることにしました。
AWSではS3を使ってるだけなので他はさっぱりというレベルです。参考のページではCloudFormation、CodePipeline、CodeBuildを使っているのですが、
CloudFormation →ナニソレ?
CodePipeline →パイプカットなら知ってるが。。。
CodeBuild →なにかビルドする感じね。
という素人レベルです。(そして恥ずかしいことにGitHubもまともに使っていない状況であります)
まず、参考のページを読んで理解したことは、
CodePipeline:GitHubからソース事をとってきてCodeBuild走らせて デプロイまでの一連の処理をしてくれる
CodeBuild:ソースからビルドをしてくれる
CloudFormation:今の所は知らなくてもよさそう
ってことです。
参考にしたページではpipenvを使っているので、Dockerイメージからビルドする方法がよくわかりませんでした。なので試しながらやってみました。この部分でハマってしまい、解決するのに時間がかかりました。
参考ページの構成と同じですが、DockerでSphinxを使っているところを追加しました。
①ローカル環境でdocker+Sphinx環境を構築
②GitHubでソースコードを管理
③GitHubへPushしたタイミングでCodePiplineでビルド・デプロイが自動で実行
④CodebildでdockerからSphinxのビルドを行う
⑤S3へデプロイする
※この図は作図ツール「draw.io」で作成してみました。初めて使ってみたんですが、なかなかいいですね。フリーで使えるなんて便利になってますね(https://www.draw.io/)
Dockerに公開されているイメージ(sphinxdoc/sphinx)からjbc/sphinxというイメージを作成しています。
docker build ./ -t jbc/sphinx
Dockerfileはこんな感じです。
FROM sphinxdoc/sphinx WORKDIR /docs RUN pip install --upgrade pip RUN pip install sphinx-autobuild RUN pip install sphinx-corlab-theme
Sphinxを始めるときにプロジェクトを作成するコマンドです。自分のPC(Windows10)のディレクトリ「$(pwd)/docs」をイメージ上の「docs」にマウントするようにしています。
docker run --rm -it -v "$(pwd)/docs:/docs" jbc/sphinx sphinx-quickstart
ビルドするには以下のコマンドになります。
docker run --rm -it -v "$(pwd)/docs:/docs" jbc/sphinx make html
ブラウザでアクセス可能な状態にするには以下のコマンドです。
docker run --rm -it -v "$(pwd)/docs:/docs" -p 8000:8000 jbc/sphinx sphinx-autobuild source build/html -H 0.0.0.0
これで自分のPCのブラウザで「http://127.0.0.1:8000/」にアクセスするとドキュメントを確認できます。ここまでで一旦は自分のPC内で使えます。
GitHubにPushするときの最終的なディレクトリ構成はこうなります。
. ├─buildspec.yml #Codebuildで自動ビルドするためのビルド仕様 ├─Dockerfile #Dockerファイル └─docs #Sphinx関連のファイル ├─build ├─ make.bat ├─ Makefile └─source ├─ conf.py ├─ index.rst ├─_static └─_templates
Dockerfileをおいているディレクトリにdocsというディレクトリができ、Sphinx関連のドキュメントができます。このファイルを(※buildディレクトリ以外)をGitHubにpushするとCodePiplineで自動ビルドが走り、ローカル環境と同じDockerでビルドしてS3へデプロイすることができます。
AWSのコンソールからパイプラインの作成していきます。 流れはソースの設定→ビルドの設定→デプロイの設定になります。
サービスロール?なんじゃそりゃって感じですが、適当でいいと思います。
ここでは、ソースをGitHubと連携して接続できればよいかと思います。
CodeBuildの設定でハマりました。dockerのイメージを指定するところで、サンプルではdocker:dindとなっていたので じゃあsphinxのイメージを使う場合はsphinxのイメージ(sphinxdoc/sphinx)を指定すればよいのかなと思っていましたが、 全然うまくいきませんでした。どうやらDockerコンテナを起動してその上でsphinxのコンテナを構築するようなイメージでした。 dindはdind = docker-in-dockerで、dockerホストの中にdockerホストを立てることができるものだということを初めて知りました。 以下のように設定しました。
buildspec.ymlはAWSのユーザーガイドに紹介されているbuildspec.ymlを元に作成しました。 まずは、サンプルのbuildspec.ymlファイルで動くかを確認してから設定すれば良いと思います。https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/sample-docker-custom-image.html
buildspec.ymlファイル
version: 0.2 phases: install: commands: - nohup /usr/local/bin/dockerd --host=unix:///var/run/docker.sock --host=tcp://127.0.0.1:2375 --storage-driver=overlay2& - timeout 15 sh -c "until docker info; do echo .; sleep 1; done" pre_build: commands: - docker build ./ -t jbc/sphinx build: commands: - docker images - docker run --rm -v "$(pwd)/docs:/docs" jbc/sphinx make html artifacts: files: - "**/*" base-directory: "docs/build/"
S3のデプロイする場所を指定します。以下の例ではtestバケットと指定しています。 入力アーティファクトはCodebuildでビルドされたファイルの場所になります。S3にそれっぽいファイルができています。 デプロイする前にファイルを抽出するにチェックをしておくとファイルが解凍されます。 デプロイパスに「/」とか入れると、S3のディレクトリがおかしな事になるので注意です。
こんな設定で自動でビルド・デプロイができました。ここまで、自分の躓いたところを中心に書いてきたんですが、詳しくは、ちゃんとしたエンジニアの書いたものを見ていただけると理解できるかと思います。
CodePipelineは1コードで1ドル/月、CodeBuildはLinux でのビルドが 1 分0.005ドルで、自分の場合は1回1分くらいだったので1ヶ月100回ビルドしても0.5ドル/月くらいです。S3は2ドル/月くらいかな。たぶん全部でも10ドル/月いかないくらいだと思います。
作ってみて、ちょっとどころじゃないくらい驚きました。昔に比べると格段に低コストでシステムが作れる環境になっています。昔の考えでシステムを作っているといつまでも高コストのままなので、そういうシステムを使っている企業はどんどん競争力が低下していくと感じました。また、クラウドになってインフラをコードで管理するようになってきているので、インフラエンジニアだからGitなんて知らんし、クラウドなんて知らんし、とかでやってると、どんどん使えないエンジニアになって行くと思います。
ほとんどの企業では今までの使っているシステムの踏襲で「今までの構成がこうだったから、クラウドでもこういう構成だろう」(リフト アンド シフト)とするんじゃないかなと思うんですが、そうであればまったくクラウドの利点を活かせないと思います。「クラウド環境にはこんなメリットがあるから新しい構成にするんだ!」(リアーキテクト)という意思がないと、他の企業と大きく差がついてきますね。あれ、最近観たYoutubeの動画でも同じようなこと言ってたな。
「今までのモノがこうだから次もこうだ」ではなく、ギターのフェンダー社やiphoneを作ったジョブスのように「そもそもこういうモノを作る」という発想が重要だと改めて思いました。
以上