PowerCMS™

PowerCMS ブログ

ホーム > PowerCMS ブログ > lsyncd を使ってコンテンツを S3 に同期する

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 のインストールについては下記ページも参考にしてください。

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
技術情報

Recent Entries