2021年08月16日
lsyncd を使ってコンテンツを S3 に同期する
2020年5月に、総務省より自治体情報セキュリティ対策の見直しについて取りまとめた資料が公開されており、ウェブ制作の現場でよく利用される AWS のブログでもこれに触れた記事が公開されています。
この記事の中で触れられているように、コンテンツを Amazon S3 へコピーしつつ、これをオリジンとして Amazon CloudFront を使った CDN を配置する、といった運用をお考えのお客様もいらっしゃるかと思います。製品サポートにカスタマイズのお問い合わせをいただくこともあり、もちろん対応可能ですが、実は CMS の機能としての実装でなくとも、実現のハードルはさほど高いものではありません。
この記事では、CDN を配置する前段として、ドキュメントルートに配置したコンテンツを lsyncd を使って S3 に同期する仕組みを作る手順の例をご紹介いたします。PowerCMS においては、トップページを持つウェブサイトの公開パスがドキュメントルートとなることが多いと思いますので、本記事ではこの状況を想定しています。
前提
AWS 内に設置した EC2 インスタンス内に仕組みを構築します。OS は無料利用枠のある Red Hat Enterprise Linux 8 を使用します。また、S3 への同期の際には AWS CLI を利用します。
- 東京リージョン(ap-northeast-1)を使用します。
- 事前に AWS コンソールから、S3 バケット「lsyncd-sample」を作成しておきます。
- EC2 インスタンスには、AmazonS3FullAccess を含む IAM ロールを付与しておきます(運用ポリシーに沿って権限を付与してください)。
EC2 インスタンスで AWS CLI を使えるようにしておく
インスタンスを起動し、SSH で EC2 インスタンスにログインします。まずは python をインストールします。
$ sudo yum -y install python3 python3-pip
$ python3 --version
Python 3.8.6
AWS CLI をインストールします。
$ sudo pip3 install awscli
$ aws --version
aws-cli/1.20.12 Python/3.8.6 Linux/4.18.0-305.el8.x86_64 botocore/1.21.12
AWS CLI を使って、S3 にファイルを同期してみます。
$ touch /tmp/test.html
$ aws --region=ap-northeast-1 s3 cp /tmp/test.html s3://lsyncd-sample/test.html
upload: ../../tmp/test.html to s3://lsyncd-sample/test.html
※ ここで、下記のようなエラーが発生する場合は、権限の付与が正しく行われていない可能性があります。EC2 インスタンスの IAM ロールや、認証情報について確認してください
upload failed: ../../tmp/test.html to s3://lsyncd-sample/test.html Unable to locate credentials
AWS CLI のインストールについては下記ページも参考にしてください。
- 4.2. AWS CLI のインストール Red Hat Enterprise Linux 8 | Red Hat Customer Portal
- Linux での AWS CLI バージョン 2 のインストール、更新、アンインストール - AWS Command Line Interface
httpd のインストール
もちろんインストール済の場合は不要です。
$ sudo yum -y install httpd
$ sudo systemctl start httpd
S3 に同期を行うシェルスクリプトの作成
$ sudo mkdir -p /var/www/lsyncd-s3
$ sudo vim /var/www/lsyncd-s3/s3-upload.sh
s3-upload.sh の内容は下記とします。
#!/bin/sh
src_dir=/var/www/html/
s3_bucket='lsyncd-sample'
region='ap-northeast-1'
aws="/usr/local/bin/aws --region=${region}"
if [ "${1}" = "" ]; then
${aws} s3 sync ${src_dir} s3://${s3_bucket}/
else
src_path="${1}"
src_path=${src_path/\/\//\/}
s3_path=${src_path#$src_dir}
if [ -f ${src_path} ]; then
${aws} s3 cp ${src_path} s3://${s3_bucket}/${s3_path}
else
${aws} s3 rm s3://${s3_bucket}/${s3_path}
fi
fi
実行権限を付与し、実行してみます。AWS コンソールからも確認してみてください。
$ sudo chmod +x /var/www/lsyncd-s3/s3-upload.sh
$ sudo touch /var/www/html/test.html
$ /var/www/lsyncd-s3/s3-upload.sh /var/www/html/test.html
upload: ../../var/www/html/test.html to s3://lsyncd-sample/test.html
削除も行ってみます。こちらも、AWS コンソールから確認してみてください。
$ sudo rm /var/www/html/test.html
$ /var/www/lsyncd-s3/s3-upload.sh /var/www/html/test.html
delete: s3://lsyncd-sample/test.html
lsyncd のインストール
EPEL リポジトリを追加し、lsyncd をインストールします。
$ sudo dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
$ sudo yum --enablerepo=epel install -y lsyncd
$ lsyncd --version
Version: 2.2.2
$ sudo vim /etc/lsyncd.conf
設定ファイル lsyncd.conf の内容は下記とします。
settings{
logfile = "/var/www/lsyncd-s3/s3-upload.log",
statusFile = "/var/www/lsyncd-s3/s3-upload.stat",
statusInterval = 5,
}
exec = function(event)
local src_path = event.sourcePathname
spawnShell(event, "/bin/bash /var/www/lsyncd-s3/s3-upload.sh " .. src_path .. " || :" );
end
s3_upload = {
maxProcesses = 2,
delay = 0,
onCreate = exec,
onDelete = exec,
onMove = exec,
}
sync {
s3_upload,
source = "/var/www/html",
}
lsyncd を起動します。
$ sudo systemctl start lsyncd
$ ps aux|grep lsyncd
root 14691 0.0 0.2 12712 2308 ? Ss 07:00 0:00 /usr/bin/lsyncd -nodaemon /etc/lsyncd.conf
ec2-user 14693 0.0 0.1 9208 1176 pts/0 S+ 07:00 0:00 grep --color=auto lsyncd
同期され、ログが残るかテストします。
$ sudo touch /var/www/html/lsyncd.html
$ tail /var/www/lsyncd-s3/s3-upload.log
Tue Aug 3 07:00:13 2021 Normal: --- Startup ---
Tue Aug 3 07:01:00 2021 Normal: Finished Create on /var/www/html//lsyncd.html = 0
lsyncd のプロセスが落ちても自動起動させる
ここでは systemd の機能を利用しますが、monit 等の死活監視でも問題ありません。
$ sudo systemctl edit lsyncd
下記のように記述します。
[Service]
Restart=always
実際にプロセスを kill して、起動することを確認します。
$ ps aux|grep lsyncd
root 14691 0.0 0.2 12712 2308 ? Ss 07:00 0:00 /usr/bin/lsyncd -nodaemon /etc/lsyncd.conf
ec2-user 14755 0.0 0.1 9208 1148 pts/0 R+ 07:03 0:00 grep --color=auto lsyncd
14691 のプロセスを kill し、異なるプロセスで起動しているか確認します。
$ sudo kill 14691
ps aux|grep lsyncd
root 14760 0.0 0.2 12712 2272 ? Ss 07:03 0:00 /usr/bin/lsyncd -nodaemon /etc/lsyncd.conf
ec2-user 14762 0.0 0.1 9208 1152 pts/0 R+ 07:04 0:00 grep --color=auto lsyncd
以上で S3 への同期を行う仕組みを構築することができました。S3 をオリジンとした Amazon CloudFront を設置し、コンテンツの配信を行いましょう。もちろん、S3 の静的サイトホスティングの機能を利用することも可能です。
次回は、S3 への同期とともに、CloudFront のキャッシュをパージする方法について触れてみます。
お問い合わせ
環境構築やカスタマイズのご相談につきましては、お問い合わせフォームよりお問い合わせください。
- カテゴリー
- PowerCMS 5
- 技術情報
コメントを投稿する