お取引先様のコンバージョン率(お問合せ・成約のこと)を上げるため、ランディングページ(メールフォームとトランザクションメール配信付)を作ったときの話をする。
当方、ホームページ屋(Web制作)は本業では無いが、専門業者に頼むほどでもないので、自分がついでにやることになった。
ランディングページではイメージ画像を多用するので、お取引先様が契約する Adobe Stock から素材を購入する。
ランディングページとは
WEB業界用語である。コーポレートサイト(自社ホームページ)とは異なる、商品(サービス)を売るために特化した自己完結型のページのことで、LPと略される。
ページが縦長で、縦スクロールで読み進めるのが特徴。営業のセールストークを1枚に書き連ねた感じ。
ページ移動があると訪問者が離脱しやすいので、他ページへのリンクは極力つけないのが一般的。
サーバ手配
WordPressだけ動けば良いので、エックスサーバやさくらサーバなどの国産レンタルサーバ(共用タイプ)でも事足りるが、自由度(root権限は欲しい)と拡張性を重視し、AWSで構築する。
とはいえ、Amazon EC2 では流石にオーバースペックなので、月額 $3.50 の固定料金から始められる Amazon Lightsail を採用する。サンドボックスとしても使えるお手軽なサーバである。低価格ながら、VPSタイプなので自由度が高く、LightsailインスタンスのスナップショットからAMIを作成できるため、将来EC2に載せ替えるのも容易で、拡張性も問題ない。
この「小さく作って大きく育てる」ソリューションが筆者好み。必要になったら継ぎ足していけば良い。クラウドファーストの利点である。
ドメイン購入
Amazon Route 53 でもドメインは購入できるが、お名前.comの方が安く買えるので後者から購入。
ネームサーバを Route53 に変更し、AWSからゾーン編集できるようにする。ドメイン自体の管理と更新費用はお名前.com、ネームサーバの管理はAWS、という棲み分けとした。
ちなみにOffice365もお名前.comで買う方が若干安い。
セットアップ手順
WordPress付きのAWS公式イメージを選択すると10分も掛からずに構築できるのだが、自分の預かり知らぬところでセットアップが終わるのは好きでは無いので、今回はOSのみのイメージを選択した。
今回は「OSのみ」を選択。
筆者はずっと長いこと Red Hat Enterprise Linux(RHEL)ばかり弄ってきたため、同じ感覚で使える CentOS を選びがちであったが、LTSが10年に延長されたことを機に Ubuntu に乗り換えている。ここは自身がやり易いOSを選べば良いだろう。
静的IPアドレスの作成
IPアドレスを固定化し、インスタンスにアタッチする。
ファイアウォールの設定
SSH(22/TCP)、HTTP(80/TCP)、HTTPS(443/TCP)の接続を許可する。
DNSゾーンの作成
お名前.comで購入したドメインを【登録済みドメインの入力】に設定し、【DNSゾーンの作成】をクリックする。
このとき表示されるネームサーバはすべてメモしておこう。
続いて、Aレコードをゾーンに追加する。今回はサブドメインが無いので、サブドメインの欄は「@」とする。
解決先の欄には、IPアドレスを直接指定することは避け、先ほど作成した静的IP名を指定しよう。デフォルトのままなら名前は「StaticIp-1」になっているはずだ。
ネームサーバの変更
お名前.comにログインし、前項でメモしたAWSのネームサーバを設定する。
これで、DNSレコードの管理をAWSに引き渡したことになる。
サーバに接続
インスタンス作成時にダウンロードしたSSHキーでサーバに接続する。
パッケージを最新に更新
sudo -i
apt -y update
apt -y upgrade
スワップファイルの作成
物理メモリの少ないマシンなのでスワップ領域を作成する。MySQLがメモリ不足で落ちることがあるからだ。
領域確保にはスワップパーティションを切る方法もあるが、クラウドによる動的な資源割り当てが簡単になった今日では、スワップファイルが一般的になりつつある。
dd
コマンドは時間が掛かるので、代わりにfallocate
コマンドを使っている。どちらでも良い。
fallocate -l 1G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo '/swapfile swap swap defaults 0 0' >> /etc/fstab
スワップイン、スワップアウトが頻繁に起こっているようであれば(vmstat
コマンドで確認可)、物理メモリを増やすことを検討しよう。
日本語化とホスト名の変更
これは必須では無いので必要に応じて対応するで良い。
apt -y install language-pack-ja-base language-pack-ja ibus-mozc
localectl set-locale LANG=ja_JP.UTF-8 LANGUAGE="ja_JP:ja"
source /etc/default/locale
apt -y install manpages-ja manpages-ja-dev
timedatectl set-timezone Asia/Tokyo
hostnamectl set-hostname ホスト名
一度リブートし、スワップメモリが効いているか念の為に確認する。
$ swapon -s
ファイル名 タイプ サイズ 使用済み 優先順位
/swapfile file 1048572 22784 -2
$ free -m
total used free shared buff/cache available
Mem: 479 208 14 18 256 240
Swap: 1023 22 1001
ここでスナップショットを取っておくと後でやり直すときにラクだが、最低の20GBプランでも月額100円程度の維持費が掛かるので、どうしても安く済ませたいなら無理にやる必要は無い。
Apache導入
apt -y install apache2
systemctl start apache2 && systemctl enable apache2
ブラウザからサーバにアクセスし、テストページが表示されることを確認。
追々 Nginx に移行するかもしれない。
PHP7導入
apt -y install php7.2 php7.2-mysql php7.2-mbstring php7.2-xml php7.2-curl
-
php7.2-mbstring
は、WordPressプラグイン WP Multibyte Patch で必要。 -
php7.2-xml
とphp7.2-curl
は、WordPressプラグイン WP Offload Media で必要。
php.ini 設定
アップロードできるファイルサイズ上限の変更、マルチバイト文字列の設定をする。
post_max_size = 30M
upload_max_filesize = 30M
date.timezone = "Asia/Tokyo"
mbstring.language = Japanese
mbstring.encoding_translation = Off
mbstring.detect_order = auto
MariaDB(MySQL)導入
規模が大きくなってきたらマネージドデータベース(Amazon RDSとか)に移行するのもあり。
apt -y install mariadb-server mariadb-client
systemctl start mariadb && systemctl enable mariadb
セキュリティ対策を行う。
mysql_secure_installation
Enter current password for root (enter for none): ← enter
Set root password? [Y/n] ← n
Remove anonymous users? [Y/n] ← y
Disallow root login remotely? [Y/n] ← y
Remove test database and access to it? [Y/n] ← y
Reload privilege tables now? [Y/n] ← y
WordPress用データベースを作成する。
mysql -u root
CREATE DATABASE wpdb;
CREATE USER 'wpdbuser'@'localhost' IDENTIFIED BY 'PASSWORD';
GRANT ALL PRIVILEGES ON wpdb.* TO 'wpdbuser'@'localhost';
FLUSH PRIVILEGES;
exit;
WordPress導入
cd /tmp && wget https://ja.wordpress.org/latest-ja.tar.gz
tar zxvf latest-ja.tar.gz
mv wordpress/* /var/www/html/
cd /var/www/html
rm index.html
chown -R www-data:www-data .
find . -type d -exec chmod 775 {} \;
find . -type f -exec chmod 664 {} \;
mv wp-config-sample.php wp-config.php
sed -i s/database_name_here/wpdb/g wp-config.php
sed -i s/username_here/wpdbuser/g wp-config.php
sed -i s/password_here/PASSWORD/g wp-config.php
https://api.wordpress.org/secret-key/1.1/salt/ で生成した秘密鍵を wp-config.php
に貼り付ける。
htaccessを許可
<Directory /var/www/html>
AllowOverride All
</Directory>
モジュール有効化
a2enmod rewrite
a2enmod ssl
a2dissite 000-default
apache2ctl configtest
systemctl restart apache2
ブラウザからサーバにアクセスし、WordPressの管理者アカウントを登録。
Amazon SES の設定
お問い合わせフォームに入力があると、お問い合わせをした本人、および営業窓口のメールアドレスに通知される。
このように、顧客が何らかのアクションを起こした際に、システムから自動で配信される確認メールのことをトランザクションメールという。迷惑メール防止法では、広告・宣伝を目的とする電子メール送信に関して事前に受信者から同意を得ることを義務付けているが、トランザクションメールは広告に該当しないため、受信者からオプトインによる同意を得ずに配信できる。許可を得ていないメールはスパムと見做される。一方、オプトアウトとは配信解除のことで、受信者がオプトアウトを簡便に行えるよう解除方法等などをメール本文に記載することも義務付けている。受信者から解除通知を受けた場合は以降のメール配信は行えない。
前置きが長くなったが、AWSには Amazon SES というフルマネージドのメール送信サービスがあるので、利用できるよう設定をする。
ドメインをSESで承認する
検証済ドメインIDリストに登録したドメインを From とするメールの送信を許可させる。これには、SESから指示されたTXTレコードをDNSに追加すれば良い。
Amazon SES コンソール の Domains >
Verify a New Domain からドメインを入力し、送信元メールのドメイン検証を行う。
新コンソールでは Configuration > Verified identities > Create identity
DKIM(DomainKeys Identified Mail) の仕組みでは、送信側で、差出人とメール本文を秘密鍵で電子署名し、受信側で、電子署名を公開鍵で照合するため、DNSにCNAMEレコード(公開鍵)の追加が必要になる。Generate DKIM Settings にチェックを入れるとドメインのDKIM署名を有効にできる。
SPF(Sender Policy Framework) の仕組みでは、MAIL FROM
コマンドで入力されたドメインがSPFレコードのチェックに使われるわけだが、Amazon SESでは、MAIL FROM
コマンドにamazonses.comのサブドメイン、エンベロープFromに登録ドメインがセットされるため、SPFレコードをDNSに追加しなくてもデフォルトでPASSされる。RFC4408でSPFレコードに設定するinclude回数は10回までと制限されているので、貴重な回数を消費せずに済んでいる。
より厳格なDMARCに準拠させるならカスタムドメインのDNSにSPFレコードを追加することになる。
キャリアメールに完全対応させるには カスタム MAIL FROM ドメイン も設定し、検証済ドメインのサブドメインにMXレコードとSPFレコードを追加する
Download Record Set as CSV をクリックし、DNSレコードの設定値をダウンロードする。
MXレコードは、SESを介してメールを受信したい場合のみ設定すれば良い。
ステータス "pending verification" (検証待ち)のドメインIDリストに追加されたことを確認したら、ドメインのDNSレコードを編集し、dig
コマンドで反映を確認する。
dig TXT _amazonses.example.com.
dig CNAME xxxxxxxxxxxxxxxxxxxxxxx._domainkey.example.com.
しばらくしたら再度ドメインIDリストを確認し、ステータスが "verified" (検証済)に変わっていればOKだ。
メールアドレスをSESで承認する
検証済メールアドレスリストに登録したメールアドレスを From とするメールの送信を許可させる。これには、SESから送信される確認メールのリンクをクリックすれば良い。
サンドボックス(後述)の外では、Domains でドメインを許可されていればそのドメインのメールアドレスを改めて許可する必要は無いが、サンドボックス内では、送信元メールアドレスと送信先メールアドレスは検証済みである必要がある。
Email Addresses >
Verify a New Email Address からメールアドレスを入力し、検証を行う。
検証済メールアドレスリストから From に使うメールアドレスを選択し、Send a Test Email でメール送信テストを行う。
SMTP認証情報の作成
SMTP Settings >
Create My SMTP Credentials より、SMTPサーバ名などを控える。
新コンソールでは Account dashboard > Simple Mail Transfer Protocol (SMTP) settings > Create SMTP credentials
IAMユーザ名を入力し、[作成] をクリックする。
SMTPユーザー名とSMTPパスワードを控えるか、CSVでダウンロードする。
サンドボックスの外に移動
初期状態ではサンドボックス(試用環境)の中にいるため、不特定のメールアドレスに送信できない。
理由は、SESから送ったメールがバウンスしたり苦情の対象になると、発信元のSESに問題があると判断され、SESがブラックリストに登録されてしまうからだ。
バウンスとは、送信メールが何らかのエラーによって送信者に差し戻されることで、苦情とは、メールの受信者がメッセージをスパムと報告することである。
SESでは、バウンス率や苦情率が一定の水準を超えるとそのアカウントのメール配信が停止されるので、運用には注意が必要だ。
運用(ユースケース)に問題が無ければ、次の手順でサンドボックスの外に移動(制限解除)できる。
Sending Statistics より Edit your account details をクリックする。
新コンソールでは Account dashboard > Request production access
必要事項を入力する。肝になるのは Use case description で、メール送信プロセスや手順について可能な限り詳しい情報を記載する。日本語で構わない。例えば、受信者リストのメンテナンス方法、バウンスやオプトアウトの管理方法、メール送信頻度などについて書くと良いだろう。
不備が無ければ24時間以内に申請が承認され、サンドボックスの外に移動される。
テスト送信
mailxコマンドを使う場合
mailx
コマンドを使うと、postfixなどでMTAを構築しなくても直接SMTPサーバに転送できる。
mailx -v \
-S smtp=smtp://email-smtp.ap-northeast-1.amazonaws.com:587 \
-S smtp-use-starttls \
-S smtp-auth=login \
-S ssl-verify=ignore \
-S smtp-auth-user=AKIXXXXXXXXXXXXXXXXX \
-S smtp-auth-password=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX \
-S nss-config-dir=/etc/pki/nssdb/ \
-s "subject" \
-r no-reply@example.com \
-c cc_address@example.com \
-b bcc_address@example.com \
to@example.com < /tmp/body.txt
Pythonコードの場合
#!/usr/bin/python3
import smtplib
from email.mime.text import MIMEText
from email.header import Header
from email.utils import formatdate
class SendMail():
Subject = u'テスト'
Charset = 'utf-8'
FromAddress = 'no-reply@example.com'
User = 'AKIXXXXXXXXXXXXXXXXX'
Pass = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
SmtpServer = 'email-smtp.ap-northeast-1.amazonaws.com:587'
def send(self, to_address, text):
msg = MIMEText(text.encode(self.Charset), 'plain', self.Charset)
msg['Subject'] = Header(self.Subject, self.Charset)
msg['From'] = self.FromAddress
msg['To'] = to_address
msg['Date'] = formatdate(localtime=True)
smtp = smtplib.SMTP(self.SmtpServer)
smtp.starttls()
smtp.login(self.User, self.Pass)
smtp.sendmail(self.FromAddress, to_address, msg.as_string())
smtp.close()
if __name__ == '__main__':
smail = SendMail()
smail.send('to@example.com', u'メール送信テスト\nこれはテストです')
ヘッダ確認
送信ドメイン認証の判定結果は Authentication-Results
ヘッダにあるので、spf=pass
とdkim=pass
があるか確認しよう。
Gmailでは「メッセージのソースを表示」からも確認できる。
WordPress の設定
wp-cliの導入
これは必須では無いが、開発でがっつりWordPressを使うなら、コマンドラインでWordPressを操作できるwp-cli
の導入すると捗る。
curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
chmod +x wp-cli.phar
mv wp-cli.phar /usr/local/bin/wp
テーマの追加
[外観] >
[テーマ] の [新規追加] から、ランディングページ向きのテーマをアップロードする。
ランディングページにはサイト型とブログ型があるが、今回は、かつてコンテンツマーケティングで一世を風靡したバズ部が提供するサイト型テーマ Xeory Extension を使うことにした。機能がシンプルなのでカスタマイズしやすい。
スターターテーマとかブランクテーマと呼ばれる、最初からカスタマイズ前提のテーマを使う手もある。今回はローンチまで1日しか無かったので諦めたが、Sage(Bootstrap4やSassが使える!)などのエンジニアに人気のテーマも時間があれば試してみたい。
子テーマを作成
Xeory Extension を親テーマとする子テーマを作成し、子テーマをカスタマイズしていくことになる。
親テーマを直接カスタマイズしてしまうと、テーマのバージョンアップによって変更内容が上書きされてしまうからだ。
テーマのカスタマイズにはPHPやCSSの知識が必須になるが、フロントエンドエンジニアなら朝飯前だろう。
以下に子テーマの基本形を示す。子テーマには「child」というサフィックスを付けるのが作法になっている。
<?php
add_action( 'wp_enqueue_scripts', 'theme_enqueue_styles' );
function theme_enqueue_styles() {
wp_enqueue_style( 'parent-style', get_template_directory_uri() . '/style.css' );
wp_enqueue_style( 'child-style', get_stylesheet_directory_uri() . '/style.css',
array('parent-style')
);
}
@charset "utf-8";
/*
Theme Name: xeory_extension_child
Template: xeory_extension
*/
SSHユーザの ubuntu
を www-data
に所属させると、開発環境によってはリモート編集が容易になるだろう。
usermod -aG www-data ubuntu
子テーマの有効化
[外観]→[テーマ] から xeory_extension_child を選択し、有効化をクリックする。
デバッグログを有効にする
functions.php
の改造や、独自プラグインを開発する場合、次のようにしてwp-content/debug.log
にデバッグログを出力すると良い。
define('WP_DEBUG', true);
if ( WP_DEBUG ) {
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);
@ini_set('display_errors', 0);
}
このとき、ログに出力する日時がずれているのを嫌うならタイムゾーンを修正する。
date_default_timezone_set( 'Asia/Tokyo' );
WP Mail SMTP プラグインの設定
WP Mail SMTP プラグインをインストール後、メーラーに「その他のSMTP」を選択。
同じ行にある「Amazon SES」はPro版(有償)でのみ選択できるようだが、何が違うのか良く分からない。
Amazon SES で控えたSMTP情報(SMTPホスト名、SMTPポート、暗号化方法、SMTPユーザ名、SMTPパスワード)を入力する。
さいごに
導入編はここまで。
次回以降、ACMのサーバ証明書とか、Amazon CloudFront とか、Googleアナリティクスなどの話をする予定。