AWS Elastic Beanstalk+Grav(Flat-File CMS)でお手軽Webサイト構築
こんにちは、城内です。だんだん梅雨も明けていき、暑い季節になってきましたね。 今回は、以前WordPressで紹介されていた簡単Webサイト構築のさらなる簡易版、データベース不要のFlat-File CMSのGravを使用したWebサイト構築を紹介したいと思います。
はじめに
Flat-File CMSといえば、このブログでも以前PicoというCMSが紹介されていました。
ちなみに、Picoには虚空(Coqoo)という日本語の拡張版もあるようです。こちらも気になったのですが、今回は現在も開発が盛んに行われているという理由で、Gravを選んでみました。
システム構成
システム構成は以下の通りです。
WordPressの時とほぼ同じような構成ですが、Gravはデータベースがないことで、WordPressのサイト更新時に発生していた、Webサーバ上のファイルとデータベース内の情報との一時的な不整合が発生しません。
また、Gravにはプレビュー機能がないのですが、上記の構成にすることで、Masterサーバ上で本番と同じ状態を確認することができるため、安心して更新ができるようになっています。
Grav構築
では、さっそく構築に入りたいと思いますが、システム構成は最初にご紹介したWordPressの構成と同じになりますので、細かいAWS上の操作は省略します。もし操作に迷うようでしたら、上記のWordPressの記事を参考にしてみてください。
EC2インスタンス作成
まず、Masterサーバを構築するため、EC2インスタンスを立ち上げます。 例のごとく、ベースとなる環境はユーザデータで整えてしまいますので、必要な環境要件はこちらの「Requirements | Grav Documentation」で確認してください。
#cloud-config repo_update: true repo_upgrade: all locale: ja_JP.UTF-8 timezone: "Asia/Tokyo" packages: - php56 - php56-gd - php56-mbstring - mod24_ssl - git runcmd: - cp -p /etc/php.ini /etc/php.ini.org && sed 's%;date.timezone =%date.timezone = "Asia/Tokyo"%' /etc/php.ini.org > /etc/php.ini - test -f /etc/sysconfig/httpd && echo "umask 002" >> /etc/sysconfig/httpd - service httpd start - chkconfig httpd on
また、S3やElastic Beanstalkの操作が必要となるため、今回はPower Userロールを付けています。
Gravインストール
Gravのインストールは、先ほどの「Requirements | Grav Documentation」とこちら「Installation | Grav Documentation」のサイトを参考にしてください。
手順は以下の通りです。
$ sudo git clone https://github.com/getgrav/grav.git /var/www/html/ Cloning into '/var/www/html'... remote: Counting objects: 10511, done. remote: Compressing objects: 100% (167/167), done. remote: Total 10511 (delta 60), reused 0 (delta 0), pack-reused 10322 Receiving objects: 100% (10511/10511), 3.93 MiB | 2.11 MiB/s, done. Resolving deltas: 100% (5836/5836), done. Checking connectivity... done. $ (cd /var/www/html && sudo php bin/grav install) Preparing to install vendor dependencies... Loading composer repositories with package information Installing dependencies - Installing erusev/parsedown (1.5.3) Downloading: 100% - Installing erusev/parsedown-extra (0.7.0) Downloading: 100% ... Cloning into 'user/themes/antimatter'... remote: Counting objects: 1242, done. remote: Compressing objects: 100% (9/9), done. remote: Total 1242 (delta 3), reused 0 (delta 0), pack-reused 1232 Receiving objects: 100% (1242/1242), 1.63 MiB | 776.00 KiB/s, done. Resolving deltas: 100% (698/698), done. Checking connectivity... done. SUCCESS cloned https://github.com/getgrav/grav-theme-antimatter -> /var/www/html//user/themes/antimatter $ sudo chown -R apache:apache /var/www/ $ sudo find /var/www/ -type f | xargs sudo chmod 664 $ sudo find /var/www/ -type d | xargs sudo chmod 775 $ sudo find /var/www/ -type d | xargs sudo chmod +s $ sudo vi /etc/httpd/conf/httpd.conf ... # Further relax access to the default document root: <Directory "/var/www/html"> # # Possible values for the Options directive are "None", "All", # or any combination of: # Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews # # Note that "MultiViews" must be named *explicitly* --- "Options All" # doesn't give it to you. # # The Options directive is both complicated and important. Please see # http://httpd.apache.org/docs/2.4/mod/core.html#options # for more information. # Options Indexes FollowSymLinks # # AllowOverride controls what directives may be placed in .htaccess files. # It can be "All", "None", or any combination of the keywords: # Options FileInfo AuthConfig Limit # AllowOverride All # # Controls who can get stuff from this server. ... $ sudo service httpd restart Stopping httpd: [ OK ] Starting httpd: [ OK ]
あと、今回の構成では、本番用の画像ファイル等はS3に格納するため、Elastic Beanstalk用のアーカイブに含まれないよう、一工夫入れます。 (imagesディレクトリを、アーカイブするディレクトリ外にコピーし、userディレクトリ配下にシンボリックリンクを作成します)
$ sudo cp -pr /var/www/html/images /var/www/ $ sudo ln -s /var/www/images /var/www/html/user/images
投稿用ユーザ作成
記事の投稿は、新しいページ用のディレクトリ作成とMarkdownファイル(.md)のアップロードで行います。 そのため、今回はgrav-userという名前で、Webサーバの実行ユーザと同じグループapacheに所属させたユーザを作成します。
$ sudo useradd -u 501 -g 48 -d /home/grav-user -m -s /bin/bash grav-user $ sudo cp -pr /home/ec2-user/.ssh /home/grav-user $ sudo chown -R grav-user:apache /home/grav-user/.ssh
また、権限の調整をするため、umaskの設定を入れます。
$ sudo bash -c "echo 'umask 002' >> /home/grav-user/.bash_profile" $ sudo cp -p /etc/ssh/sshd_config /etc/ssh/sshd_config.org && sudo bash -c "sed 's%/usr/libexec/openssh/sftp-server%/usr/libexec/openssh/sftp-server -u 002%' /etc/ssh/sshd_config.org > /etc/ssh/sshd_config" $ sudo service sshd restart sshd を停止中: [ OK ] sshd を起動中: [ OK ]
動作確認
以下のようなデフォルトのホーム画面が表示されれば成功です。
一応、以降の操作のために、動作確認を兼ねて以下のようなテストページを作成しておきます。
Dillingerのような適当なMarkdownエディタで、以下のようなMarkdownファイルを作成し、
--- title: Test --- # テストページ あいうえお * かきくけこ * さしすせそ ![classmethod logo](/user/images/cmlogo.png)
以下の場所に格納します(02.testディレクトリは手動で作成します)。
/var/www/html/ ┗user ┗pages ┣01.home ┗02.test ┗default.md
Elastic Beanstalk構築
次に、Elastic Beanstalkを構築します。
.ebextensions作成
Elastic BeanstalkにてEC2インスタンスが起動される際、必要なセットアップを行うため、.ebextensionsの機能を使用します。
$ sudo mkdir /var/www/html/.ebextensions $ sudo vi /var/www/html/.ebextensions/01_ossetup.config packages: yum: mod24_ssl: [] commands: set-timezone-os: command: cp /usr/share/zoneinfo/Japan /etc/localtime set-timezone-php: command: test -f /etc/php.ini.org || cp -p /etc/php.ini /etc/php.ini.org && sed 's%;date.timezone =%date.timezone = "Asia/Tokyo"%' /etc/php.ini.org > /etc/php.ini set-umask-httpd: command: test -f /etc/sysconfig/httpd && grep "umask" /etc/sysconfig/httpd || echo "umask 002" >> /etc/sysconfig/httpd make-directory-images: command: test -d /var/www/images || mkdir -m 777 /var/www/images
S3バケット作成
画像データやElastic Beanstalk用のアーカイブを格納するS3バケットを作成します。今回は、cm-grav-testというバケットを作成しました。 (ちなみに、バケットポリシーはCloudFrontでのオリジン設定時に自動で追加してもらうため、ここではあえて設定していません)
そこにuser/imagesディレクトリ配下の画像データと/var/www/htmlディレクトリ配下のファイルやディレクトリをアーカイブしたZIPファイルをアップロードします。
手順は以下の通りです。
$ (cd /var/www/html/ && sudo php bin/grav clear-cache --all) Clearing cache Cleared: cache/* Touched: /var/www/html/user/config/system.yaml $ aws s3 sync /var/www/html/user/images s3://cm-grav-test/user/images upload: user/images/cmlogo.png to s3://cm-grav-test/user/images/cmlogo.png upload: user/images/.gitkeep to s3://cm-grav-test/user/images/.gitkeep $ (export _ZIPFILE="grav_$(date '+%Y%m%d%H%M%S')" && cd /var/www/html && sudo zip -ry /tmp/${_ZIPFILE}.zip . && aws s3 cp /tmp/${_ZIPFILE}.zip s3://cm-grav-test/resource/ && sudo rm -f /tmp/${_ZIPFILE}.zip) adding: .editorconfig (deflated 43%) adding: bin/ (stored 0%) adding: bin/gpm (deflated 55%) ... adding: .gitignore (deflated 44%) adding: LICENSE (deflated 41%) upload: /tmp/grav_20150720175026.zip to s3://cm-grav-test/resource/grav_20150720175026.zip
S3バケット上は以下のようになっています。
$ aws s3 ls s3://cm-grav-test/ --recursive 2015-07-20 17:50:32 12565103 resource/grav_20150720175026.zip 2015-07-20 16:31:15 0 user/images/.gitkeep 2015-07-20 16:31:15 12871 user/images/cmlogo.png
Elastic Beanstalkアプリケーション作成
上記のZIPファイルをソースに、Webアプリケーションを作成します。 作成方法やパラメータについては、過去の記事で何度も出てきているので省略します。もし分からない場合は、過去のElastic Beanstalkの関連記事を参考にしてください。
仕上がりは以下の通りです。
$ aws elasticbeanstalk describe-environments --region ap-northeast-1 { "Environments": [ { "ApplicationName": "grav-test", "EnvironmentName": "grav-test-prod", "VersionLabel": "resource.grav_20150720175026.zip", "Status": "Ready", "EnvironmentId": "e-chtixvc7pa", "EndpointURL": "awseb-e-c-AWSEBLoa-1RHRA8A6JP2PZ-600687977.ap-northeast-1.elb.amazonaws.com", "SolutionStackName": "64bit Amazon Linux 2015.03 v1.4.3 running PHP 5.6", "CNAME": "grav-test-prod.elasticbeanstalk.com", "Health": "Green", "AbortableOperationInProgress": false, "Tier": { "Version": " ", "Type": "Standard", "Name": "WebServer" }, "DateUpdated": "2015-07-20T08:59:45.890Z", "DateCreated": "2015-07-20T08:55:27.913Z" } ] } $ aws elasticbeanstalk describe-environment-resources --environment-name "grav-test-prod" --region ap-northeast-1 { "EnvironmentResources": { "EnvironmentName": "grav-test-prod", "AutoScalingGroups": [ { "Name": "awseb-e-chtixvc7pa-stack-AWSEBAutoScalingGroup-YJR62DW6SRV5" } ], "Triggers": [], "LoadBalancers": [ { "Name": "awseb-e-c-AWSEBLoa-1RHRA8A6JP2PZ" } ], "Queues": [], "Instances": [ { "Id": "i-b53e4040" } ], "LaunchConfigurations": [ { "Name": "awseb-e-chtixvc7pa-stack-AWSEBAutoScalingLaunchConfiguration-13L9CG4AN2QZN" } ] } }
CloudFront構築
最後に、CloudFrontを作成します。
オリジンには、上記で作成したElastic BeanstalkのURL(grav-test-prod.elasticbeanstalk.com)とS3のバケット名(cm-grav-test.s3.amazonaws.com)を設定します。
なお、上記の手順ではS3バケット作成時にあえてバケットポリシーを設定していないため、S3バケットのオリジンを設定する際は、以下のようにバケットポリシーを追加してもらうようにしてください。
[Origins]と[Behaviors]の設定は以下の通りです。
出来上がり
以下のようにCloudFront経由でアクセスし、画像のリンク切れもなく正常に画面が表示されれば成功です。 (Elastic BeanstalkのURLへのアクセスでは、EC2インスタンス上には画像ファイルがないため、画像は表示されません)
さいごに
さて、いかがでしたでしょうか?ライトなWebサイトを作成してみたいと思っている方にはお薦めです! 個人的には、Gravはお手軽でなかなか面白いツールだと思ったので、もっとテーマやプラグインを追加してごにょごにょしてみたいと思います。
記事にできるかは分かりませんが(笑)。
おまけ
Masterサーバでサイトを更新した後、本番サーバに反映させるには、以下の手順を実施します(コマンド出力は省略)。
$ (cd /var/www/html/ && sudo php bin/grav clear-cache --all) $ aws s3 sync /var/www/html/user/images s3://cm-grav-test/user/images $ export _ZIPFILE="grav_$(date '+%Y%m%d%H%M%S')" $ (cd /var/www/html && sudo zip -ry /tmp/${_ZIPFILE}.zip . && aws s3 cp /tmp/${_ZIPFILE}.zip s3://cm-grav-test/resource/ && sudo rm -f /tmp/${_ZIPFILE}.zip) $ aws elasticbeanstalk create-application-version --application-name grav-test --version-label $_ZIPFILE --source-bundle S3Bucket=cm-grav-test,S3Key=resource/${_ZIPFILE}.zip --region ap-northeast-1 $ aws elasticbeanstalk update-environment --environment-name grav-test-prod --version-label $_ZIPFILE --region ap-northeast-1 $ unset _ZIPFILE