<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Shaharyar Ahmed</title>
    <description>The latest articles on DEV Community by Shaharyar Ahmed (@shaharyarahmed).</description>
    <link>https://dev.to/shaharyarahmed</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F797766%2Fe56b71e8-af95-4ade-967c-e4322db4a24e.jpeg</url>
      <title>DEV Community: Shaharyar Ahmed</title>
      <link>https://dev.to/shaharyarahmed</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/shaharyarahmed"/>
    <language>en</language>
    <item>
      <title>Static website + Wordpress blog - Hosting on AWS</title>
      <dc:creator>Shaharyar Ahmed</dc:creator>
      <pubDate>Tue, 18 Jan 2022 22:22:00 +0000</pubDate>
      <link>https://dev.to/shaharyarahmed/static-website-wordpress-blog-hosting-on-aws-pl4</link>
      <guid>https://dev.to/shaharyarahmed/static-website-wordpress-blog-hosting-on-aws-pl4</guid>
      <description>&lt;p&gt;Basic AWS knowledge is required.&lt;/p&gt;




&lt;p&gt;A static website + WordPress blog 🤔&lt;/p&gt;

&lt;p&gt;A very very common scenario where you want to keep your website static or build with Nextjs SSG, or probably with Reactjs. On the other hand, your marketing team wants WordPress to write blogs because it's in their comfort zone and they don't want to learn anything new.&lt;/p&gt;

&lt;p&gt;In a startup, where you don't have much time to deal with all these. You might choose one of the three following options:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Build your entire website with WordPress using a theme so your content writers feel at home&lt;/li&gt;
&lt;li&gt;Create static pages for each blog and deploy them with the static site&lt;/li&gt;
&lt;li&gt;Create a custom blogging tool&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;But hold on, you have another option. It requires a bit of a hassle though for the first time. But it will make your life much easier on the long run.&lt;/p&gt;

&lt;p&gt;Serve your website statically using Nginx from one server, and run WordPress on another server. Now use AWS load balancer's smart routing to load blogs whenever someone goes to &lt;code&gt;/blog&lt;/code&gt; on your site.&lt;/p&gt;

&lt;p&gt;Feeling overwhelmed? 🤯 Let's break it down and understand it in more detail.&lt;/p&gt;

&lt;p&gt;But first, look at an example&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://www.teamingway.com"&gt;www.teamingway.com&lt;/a&gt; (Main website is built with Nextjs SSG (static site generation) and statically deployed on an EC2)&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://www.teamingway.com/blog/"&gt;www.teamingway.com/blog/&lt;/a&gt; (A WordPress site, running on another EC2, routed using AWS load balancer)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We will set up the same thing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploy static website
&lt;/h2&gt;

&lt;p&gt;Create a &lt;code&gt;t2.micro&lt;/code&gt; EC2 instance with the following Nginx config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="c1"&gt;# filename: example.com&lt;/span&gt;
&lt;span class="c1"&gt;# location: /etc/nginx/sites-enabled&lt;/span&gt;

&lt;span class="c1"&gt;# redirect http to https&lt;/span&gt;
&lt;span class="c1"&gt;# redirect example.com to www.example.com&lt;/span&gt;
&lt;span class="k"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;server_name&lt;/span&gt; &lt;span class="s"&gt;example.com&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;301&lt;/span&gt; &lt;span class="s"&gt;https://www.example.com&lt;/span&gt;&lt;span class="nv"&gt;$request_uri&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# main block&lt;/span&gt;
&lt;span class="k"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kn"&gt;server_name&lt;/span&gt; &lt;span class="s"&gt;www.example.com&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;# path to the static website folder&lt;/span&gt;
    &lt;span class="kn"&gt;root&lt;/span&gt; &lt;span class="n"&gt;/srv/www/your-website-folder&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;index&lt;/span&gt; &lt;span class="s"&gt;index.html&lt;/span&gt; &lt;span class="s"&gt;index.htm&lt;/span&gt; &lt;span class="s"&gt;index.nginx-debian.html&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;# serve static website files, throw "nginx 404 error" if file not found&lt;/span&gt;
        &lt;span class="kn"&gt;try_files&lt;/span&gt; &lt;span class="nv"&gt;$uri&lt;/span&gt; &lt;span class="nv"&gt;$uri&lt;/span&gt;&lt;span class="s"&gt;.html&lt;/span&gt; &lt;span class="nv"&gt;$uri&lt;/span&gt;&lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Notice, we only handled "HTTP" and not "HTTPS", because we will handle HTTPS at Load Balancer level and attach &lt;code&gt;ssl&lt;/code&gt; certificate there too.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Restart &lt;code&gt;Nginx&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;service nginx restart
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our static website is now up and running.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploy WordPress site
&lt;/h2&gt;

&lt;p&gt;We will not go into the details of creating a WordPress instance on AWS because we're solving a different problem here. We will only explore things that are relevant to our goal.&lt;/p&gt;

&lt;p&gt;To create a WordPress instance, go to &lt;code&gt;Launch Instances&lt;/code&gt; on the main instances page. Search &lt;code&gt;WordPress&lt;/code&gt; and select a &lt;code&gt;Bitnami&lt;/code&gt; WordPress instance (as shown in the image below):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ktMDaTi0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/slskk4exqpovujazqp2y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ktMDaTi0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/slskk4exqpovujazqp2y.png" alt="AWS create Wordpress instance" width="880" height="275"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Or you can manually set up one, it's all up to you. Once your WordPress instance is up and running, move to the next step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Set up redirection using "AWS Load Balancer" and "Route 53"
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1) Create Load Balancer
&lt;/h3&gt;

&lt;p&gt;On your EC2 dashboard, go to &lt;code&gt;Load Balancers&lt;/code&gt; from the left sidebar:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YiNy1phq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bn6rn57yqs81cmbx1zbz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YiNy1phq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bn6rn57yqs81cmbx1zbz.png" alt="Select load balancer from sidebar" width="216" height="106"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and then create a new load balancer, make sure you select &lt;strong&gt;Application Load Balancer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--93VHyruV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vna61b0twz8y8jzi472k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--93VHyruV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vna61b0twz8y8jzi472k.png" alt="Create AWS load balancer" width="880" height="456"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It should be:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Internet-facing&lt;/li&gt;
&lt;li&gt;In the same &lt;code&gt;VPC&lt;/code&gt; as your website and WordPress instance&lt;/li&gt;
&lt;li&gt;In the same &lt;code&gt;Availability zone&lt;/code&gt; as your website and WordPress instance&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Add &lt;code&gt;default listener&lt;/code&gt; as your website instance with port 80 and complete the load balancer creation. We'll change it later anyway.&lt;/p&gt;

&lt;h3&gt;
  
  
  2) Set up ALB routing
&lt;/h3&gt;

&lt;p&gt;Add the first listener for &lt;code&gt;port 80&lt;/code&gt;. Add one rule to permanently redirect to &lt;code&gt;HTTPS 443&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BTkfBqgj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2brvr2uhrhj3c7p3uodc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BTkfBqgj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2brvr2uhrhj3c7p3uodc.png" alt="AWS load balancer - http to https redirect" width="880" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add the second listener for &lt;code&gt;port 443&lt;/code&gt;. Now there will be two rules (See the image below for reference)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rule 1:&lt;/strong&gt; Default action will be to forward all the traffic to our static website.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Explanation:&lt;/em&gt; This means all requests coming on &lt;code&gt;example.com&lt;/code&gt; or &lt;code&gt;example.com/anypage&lt;/code&gt; will be forwarded to our static website instance. The instance name is &lt;code&gt;website-static&lt;/code&gt; in the image below.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rule 2:&lt;/strong&gt; If the &lt;code&gt;path&lt;/code&gt; matches the pattern &lt;code&gt;/blog*&lt;/code&gt;, forward the request to our &lt;code&gt;WordPress instance&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Explanation:&lt;/em&gt; This means if the request URL contains &lt;code&gt;/blog&lt;/code&gt; in it, the request will now be forwarded to our WordPress instance instead of the static website instance. If a request does not contain &lt;code&gt;/blog&lt;/code&gt;, it will satisfy &lt;code&gt;Rule 1&lt;/code&gt; and will be forwarded to the static website instance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lSg5KdlX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e4du6flxft5t64v6g8h1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lSg5KdlX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e4du6flxft5t64v6g8h1.png" alt="aws-load-balancer-listener-to-https" width="880" height="289"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: You will need to add your SSL certificate to the &lt;strong&gt;AWS Certificate Manager (ACM)&lt;/strong&gt; and attach it to the load balancer. We will not go into its details as well.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dgFiUejg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rcicai2yhfy3uo6jx46s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dgFiUejg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rcicai2yhfy3uo6jx46s.png" alt="Add ssl to AWS load balancer" width="880" height="115"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3) Add Load Balancer to Route 53
&lt;/h3&gt;

&lt;p&gt;We have everything ready now:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Static website instance&lt;/li&gt;
&lt;li&gt;WordPress site instance&lt;/li&gt;
&lt;li&gt;Load Balancer with https and rules to redirect based on URL&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The next and final step is to make a DNS entry for our website so we can access it via domain name.&lt;/p&gt;

&lt;p&gt;Go to your AWS Route 53 directory and create a new Route:&lt;/p&gt;

&lt;p&gt;Choose &lt;code&gt;Record type&lt;/code&gt; = &lt;code&gt;A&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Turn on the &lt;code&gt;Alias&lt;/code&gt; toggle in the &lt;code&gt;Route Traffic to&lt;/code&gt; section and select &lt;code&gt;Alias to Application and Classic Load Balancer&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GgMF7Zaf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z7912vrpzimw9o636w5p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GgMF7Zaf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z7912vrpzimw9o636w5p.png" alt="aws-route-53-entry-for-load-balancer" width="349" height="365"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select your zone i.e. &lt;code&gt;us-west-1&lt;/code&gt; and your load balancer will automatically appear, select and create the record.&lt;/p&gt;

&lt;h2&gt;
  
  
  Add sub path to your wordpress posts
&lt;/h2&gt;

&lt;p&gt;Change your site name and url, add &lt;code&gt;/blog&lt;/code&gt; at the end:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1drwakXq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y1x4xeizygv6a7sqzljl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1drwakXq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y1x4xeizygv6a7sqzljl.png" alt="Change wordpress site name" width="596" height="109"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Change permanent links by going into &lt;code&gt;Settings &amp;gt; Permalinks&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--962EXHcB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1m1vndbhmxxpeyoukq1x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--962EXHcB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1m1vndbhmxxpeyoukq1x.png" alt="Change wordpress permalink" width="577" height="59"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;and that's it 🥳&lt;/p&gt;

&lt;p&gt;Your main website is running on a separate instance which could be static site, reactjs, nextjs or anything you want it to be and when you open &lt;code&gt;/blog&lt;/code&gt; your wordpress site will load.&lt;/p&gt;

&lt;p&gt;That will make your marketing team lives much easier regarding posting blogs, updates and sharing them on social media and other sites with easy SEO via wordpress plugins like &lt;strong&gt;yoast seo&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>wordpress</category>
      <category>nextjs</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
