WordPress架站!搭配AWS Cloudfront及Cloudflare同網域多服務整合

最近接手公司的一個專案,需求為新增一個「可以客製化的頁面」提供給行銷同仁使用並且需要「配合主網域優化SEO」。聽到「可以客製化的頁面」我第一個想到的是我平常在寫的wordpress,我平常只是單純寫文章,但我知道它也可以做得相當精美。

配合主網域就讓我有點頭痛了,然後還要配合現有架構短時間把服務架起來,暸解市面上的雲端產品後,最後決定使用AWS Cloudfront來解決,它是AWS CDN工具,並且可以在服務後端做反向代理(reverse proxy)完成我整合主網域的需求(這篇文章說明反向代理非常清楚明瞭)。

需求架構如下,後端有兩支AWS Elastic Beanstalk架起來的服務,一個事主網站,另一個是wordpress,我們要透過AWS Cloudfront整合兩支服務,終端用戶完全不知道後端其實有兩支服務。

架構確定之後,剩下的就是既簡單又複雜的技術問題了,以下紀錄我在過程中踩到的坑,並且將當時的解法作紀錄。

如何使用AWS Cloudfront

在我執行這個專案之前,我是第一次使用AWS Cloudfront,所以非常不熟悉。主要處理的只有兩個設定及快取的部分。

設定Origin

建立Distribution

  • Origin domain即服務的原始網域(我的情境有wordpress和網站)
  • Protocol為cloudfront與原始服務溝通的protocol,根據自己的情況設定,我用AWS EB所以使用HTTP

設定Behavior

  • viewer protocol policy選Redirect HTTP to HTTPS
  • Allowed HTTP methods選Get, HEAD, OPTIONS, PUT, POST, PATCH, DELETE

設定快取

快取行為非常重要,我的網站一直發生錯誤,從server上打log出來debug才找到問題原來出在這邊,Cloudfront預設的是沒有快取也不會傳遞URL參數,這部分必須要手動自行設定。

主網站的部分我用以下Cache Policy,origin request policy選用預設的AllViewer。

「Wordpress網站」(即Behavior為「/blog/*」)也使用上面的Cache Policy,因為需要快取origin request policy使用以下設定:

「Wordpress後台」也使用上面的Cache Policy,但不需要快取,所以用以下設定:

後台的Behavior包含這些東西,根據所有路徑,搭配上述Policy各自去新增Behavior:

所有的Behavior設定完成的結果如下:

AWS Elastic Beanstalk環境設定

.ebextensions/資料夾新增設定:

blog-link.config

commands:
  01_link:
    command: "ln -s /var/app/current/ /var/www/blog"

max-body-size.config

files:
  "/etc/php.d/max-body-size.ini":
    mode: "000755"
    owner: root
    group: root
    content: |
        upload_max_filesize = 25M
        post_max_size = 25M
        memory_limit = 15M

.platform/nginx/conf.d/elasticbeanstalk/資料夾新增設定:

01-redirect.conf

location ^~ /blog {
    root /var/www;
    index index.php index.html index.htm;
    try_files $uri $uri/ /blog/index.php?$args;

    location ~ \.(php|phar)(/.*)?$ {
        fastcgi_split_path_info ^(.+\.(?:php|phar))(/.*)$;

        fastcgi_intercept_errors on;
        fastcgi_index  index.php;

        fastcgi_param  QUERY_STRING       $query_string;
        fastcgi_param  REQUEST_METHOD     $request_method;
        fastcgi_param  CONTENT_TYPE       $content_type;
        fastcgi_param  CONTENT_LENGTH     $content_length;

        fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
        fastcgi_param  REQUEST_URI        $request_uri;
        fastcgi_param  DOCUMENT_URI       $document_uri;
        fastcgi_param  DOCUMENT_ROOT      $document_root;
        fastcgi_param  SERVER_PROTOCOL    $server_protocol;
        fastcgi_param  REQUEST_SCHEME     $scheme;
        fastcgi_param  HTTPS              $https if_not_empty;

        fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
        fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;

        fastcgi_param  REMOTE_ADDR        $remote_addr;
        fastcgi_param  REMOTE_PORT        $remote_port;
        fastcgi_param  SERVER_ADDR        $server_addr;
        fastcgi_param  SERVER_PORT        $server_port;
        fastcgi_param  SERVER_NAME        $server_name;

        # PHP only, required if PHP was built with --enable-force-cgi-redirect
        fastcgi_param  REDIRECT_STATUS    200;

        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        fastcgi_param  PATH_INFO $fastcgi_path_info;
        fastcgi_pass   php-fpm;
    }
}

02-settings.conf

client_max_body_size 100M;

調整Wordpress設定

調整wp-config.php

<?php
define('DB_NAME', $_SERVER['RDS_DB_NAME']);
define('DB_USER', $_SERVER['RDS_USERNAME']);
define('DB_PASSWORD', $_SERVER['RDS_PASSWORD']);
define('DB_HOST', $_SERVER['RDS_HOSTNAME'] . ':' . $_SERVER['RDS_PORT']);
define('DB_CHARSET', 'utf8');
define('DB_COLLATE', '');
define('AUTH_KEY',         $_SERVER['AUTH_KEY']);
define('SECURE_AUTH_KEY',  $_SERVER['SECURE_AUTH_KEY']);
define('LOGGED_IN_KEY',    $_SERVER['LOGGED_IN_KEY']);
define('NONCE_KEY',        $_SERVER['NONCE_KEY']);
define('AUTH_SALT',        $_SERVER['AUTH_SALT']);
define('SECURE_AUTH_SALT', $_SERVER['SECURE_AUTH_SALT']);
define('LOGGED_IN_SALT',   $_SERVER['LOGGED_IN_SALT']);
define('NONCE_SALT',       $_SERVER['NONCE_SALT']);
$table_prefix  = 'wp_';
define('WP_DEBUG', false);

if (isset($_SERVER['HTTP_CLOUDFRONT_FORWARDED_PROTO'])
  && $_SERVER['HTTP_CLOUDFRONT_FORWARDED_PROTO'] === 'https') {
  $_SERVER['HTTPS'] = 'on';
}
if ( !defined('ABSPATH') )
	define('ABSPATH', dirname(__FILE__) . '/');
require_once(ABSPATH . 'wp-settings.php');

安裝plugin

安裝cloudflare flexible ssl並事先啟用plugin

調整Site url & Home url

全部設置完畢之後在資料庫新增最終的網址,我的例子為「https://www.sotaverse.com/blog」

Cloudflare設定

最後就是在Cloudflare設定CNAME到AWS Cloudfront的位置就完成了!

那些我踩的坑

  1. WordPress後台讓我花非常多時間去調整,因為wordpress程式本身會對網址做轉址動作,無論是遇到網址不同或者是HTTP or HTTPS的不同都會做轉址,所以登入後台容易遇到Error Too Many Redirects。解決方式為wp-config.php內的header判斷去給予HTTPS potocol搭配cloudflare flexible ssl plugin。
  2. AWS Cloudfront的快取機制,因為預設是沒有任何快取的,全部都要自己設定。設定快取後還要留意origin request的設定,它可以解讀成如果沒有快取,如何與遠矢伺服器做溝通(要帶哪些headers)。

喜歡運用科技工具提升工作效率、並自主開發實用小工具的長時間使用電腦工作者。對新科技工具深感興趣,樂於分享如何運用科技工具提升生活和工作效率的技巧。

發佈留言