EC2 WordPress Behind CloudFront

Running your own WordPress server with all sorts of shiny Plugins you can install seemed cool and fun to explore. Unfortunately running your WordPress server with WooCommerce behind a Load Balancer turned out to be more costly than expected.

WooCommerce itself requires t2.large instance of EC2, which costs over $60 per month. I’ve tried using t2.medium to run it, and the server crashes every once in a while, requiring me to manually restart the EC2 instance, but it does reduce the cost by about half.

Then there’s the Load Balancer which I used to configure SSL, allowing the website to be accessed securely with HTTPS. That shows up on the bill as Virtual Private Cloud and costs about $7.50 per month. If you’re using Elastic Load Balancing, that’s an extra $15.

Here is what my billing currently looks like:

Since my sales are currently close to zero, it doesn’t make sense to incur these costs.

The solution I came up with for the WooCommerce problem is to use a free online shop service so I can reduce the EC2 instance requirements back down to t2.micro, which will cost about $10 per month after the 12 months of free tier has expired. I ended up using a Printify Pop-up store, but Etsy, Ebay, or lesser known ones like TeePublic are good alternatives to free online stores where you can post your products.

Then there’s the issue with the SSL certificate which I used a Load Balancer to apply. I’ve deleted the load balancer and I’m using Cloudfront pointed to the EC2 instance to apply the SSL certificate.

It turns out that Cloudfront configurations are more challenging than I expected. I’ve made the following changes to make it all somewhat work.

  • Create a SSL Certificate for both the base domain and www subdomain.
    • example: reikaxubia.com and www.reikaxubia.com
  • Configure Cloudfront properly.
    • Configure Cloudfront to be passthrough and not cache anything by using Legacy cache settings, and selecting All for each option, and have everything redirect HTTP to HTTPS, and allow all headers.
    • Make sure you add both your base domain and www subdomain as alternate CNAMEs under General > Settings for your Cloudfront.
    • Set your Origins protocol to HTTP only, and your origin domain is your Public IPv4 DNS. This value changes each time the server is stopped and started, so remember to update your Cloudfront if this happens.
  • Add the following lines to your wp-config.php on your WordPress server before your /* That's all, stop editing! Happy publishing. */ line:
    • define('WP_HOME', 'https://www.reikaxubia.com');
      define('WP_SITEURL', 'https://www.reikaxubia.com');
      if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
      $_SERVER['HTTPS'] = 'on';
      }
      define('FORCE_SSL_ADMIN', true);
  • Add the following lines to the top of your .htaccess file on your WordPress server:
    • <IfModule mod_headers.c>
      Header set Content-Security-Policy "upgrade-insecure-requests"
      </IfModule>
  • Restart your web server with the following line:
    • sudo systemctl restart httpd
  • Point your Route53 domains to your Cloudfront instance.

This mostly works. I am currently having trouble with dynamic pages such as trying to login to the admin account. I’ve been getting around this issue by replacing WP_HOME and WP_SITEURL values with the EC2 instance’s Public IPv4 DNS, and this allows me to login. Just remember to restart the server to apply the changes, and once you’re done logging into the admin account, set the WP_HOME and WP_SITEURL values back to the https domain values and restart the server to apply the changes.

I am happy with the way it currently works for now. If anyone knows how I can have login-required pages like wp-login and wp-admin work while having WP_HOME and WP_SITEURL still set to my Route53 domains, please let me know.


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *