<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[/maker.]]></title><description><![CDATA[I am a startup CTO and part-time indie maker.  I write about software development, AWS and startups.]]></description><link>https://slashmaker.com</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1696694721563/Gd9RN0dSr.png</url><title>/maker.</title><link>https://slashmaker.com</link></image><generator>RSS for Node</generator><lastBuildDate>Thu, 08 Oct 2026 07:08:18 GMT</lastBuildDate><atom:link href="https://slashmaker.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[I just spent over $500 on a GoDaddy domain auction]]></title><description><![CDATA[This week I bought a domain name for $500. That's the most I've ever spent on a single domain name, and rather out of character for me. But it could have been a whole lot worse...
My wife has a health and fitness brand and when setting it up a couple...]]></description><link>https://slashmaker.com/i-just-spent-over-500-on-a-godaddy-domain-auction</link><guid isPermaLink="true">https://slashmaker.com/i-just-spent-over-500-on-a-godaddy-domain-auction</guid><category><![CDATA[#domains]]></category><category><![CDATA[Investment]]></category><category><![CDATA[branding]]></category><category><![CDATA[fun]]></category><dc:creator><![CDATA[Hamza]]></dc:creator><pubDate>Sat, 14 Oct 2023 16:51:35 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1697299554957/f4975ea8-9f7e-4639-8434-54e76de4cb6a.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>This week I bought a domain name for $500. That's the most I've ever spent on a single domain name, and rather out of character for me. But it could have been a whole lot worse...</strong></p>
<p>My wife has a health and fitness brand and when setting it up a couple of years ago, the .com was not available; it was registered back in 2007 or something.</p>
<p>The 2nd best option was the ".life" domain which was kinda relevant to the brand but of course a bit meh like all neo-TLDs.</p>
<p>Every now and then I would check the .com to see if it had become available - and 2 weeks ago I found that it had been listed on GoDaddy auctions after expiring.</p>
<p>The domain itself is a 5-letter .com, so reasonably short and reasonably rare. It's not a real word (at least, not in English), but very pronounceable and with no "weird" letters like X, Q or Z.</p>
<p>I figured that if it kept a low profile it would go under most buyers' radars, and with a prevailing wind we could probably pick it up for a hundred dollars or so.</p>
<p>So I didn't make any bid until a few hours before the end, and that was just in case I forgot to bid later and missed the whole thing (which in retrospect was unlikely since my wife would never allow me to do that).</p>
<p>However, later that evening we went out for dinner with friends and in the fun we actually did completely forget about the auction.</p>
<p>I remembered about it in the car on the way home. It was 10.15pm and I knew the auction ended at 10.*something* but I couldn't remember what.</p>
<p>Panicked, we drove home as quickly (and of course as safely) as possible. On the way we discussed whether worst-case scenario we were willing to spend 100 or 200 bucks on this thing.</p>
<p>We got home with 10 minutes to spare, and the price had shot up to $443 with 4 or 5 other bidders in the fray.</p>
<p>"Well that escalated quickly."</p>
<p>There's an interesting psychology that losing something has more emotional cost than gaining something. Price anchoring also has a funny effect on your mind.</p>
<p>So now the $200 we were willing to spend seemed cheap. The conversation became "what's the absolute maximum we're willing to go up to?"</p>
<p>GoDaddy, like most online auctions, works using proxy bidding. The system will on your behalf automatically bid up to whatever limit you set.</p>
<p>If the price is currently $430 and you set your bid to $500 then the price will jump to $435 and you'll be the highest bidder.</p>
<p>If someone then comes in at $475 the proxy system will automatically raise the price to $480 on your behalf and you'll still be the winner.</p>
<p>So the most sensible strategy in a proxy auction is to decide the most you want to pay for something, enter that amount, and forget about it. Things get real dangerous real quick if you keep adjusting your limit every time you are outbid.</p>
<p>So now we have 10 minutes to actually evaluate how much we're willing to go to.</p>
<p>GoDaddy itself estimated the domain to be worth $3k, but of course that's complete fiction. I checked a few other estimate tools and they came back with numbers ranging from $130 to $400.</p>
<p>I reasoned that if 2 other humans in this auction were prepared to spend $400+ then $300 is a fair base value. That is, if I bought the domain and then changed my mind I could just flip it and get at least $300 back.</p>
<p>I don't see the value of 5-letter .com domains dropping in the future. If anything I would expect short domains to keep rising, because by their very nature there's only a finite supply of them. So owning one would be a fairly safe asset, and the actual cost is only whatever I pay over $300.</p>
<p>Then there is the value that the .com would add to my wife's brand. This is much harder to quantify, but she has huge ambitions for her business and it's hard to argue that a .com doesn't bring trust and credibility - which is super important in the fitness industry.</p>
<p>5 minutes left.</p>
<p>"Would you be gutted if we bid $600 and didn't win it?" I asked my wife.</p>
<p>She immediately said yes.</p>
<p>"800?"</p>
<p>"Yes."</p>
<p>This is starting to get silly. But I wasn't disagreeing with her.</p>
<p>"1,000?"</p>
<p>1 minute to go.</p>
<p>We agreed on $800 and to avoid any last-minute snipers I waited until the last 30 seconds before - to my wife's delight - I entered $1,000. What a gentleman.</p>
<p>Refreshing the page to see what we had done we were relieved to find the auction had risen to just $448. There was no one proxy bidding against us.</p>
<p>But we saw that the auction still had 5 minutes to run! I didn't realise that GoDaddy Auctions adds an extra 5 minutes to the duration if anyone bids at the last moment. My anti-sniping strategy was garbage.</p>
<p>Cue 5 minutes of frantic CMD-R'ing. No-one was coming after us. We'd left them in a trail of dust.</p>
<p>The auction ends still at $448. Whoops of joy, hugs, the works.</p>
<p>I'm a hero, and I only spent half of what it could have been.</p>
<p>(I remembered soon afterwards that the price doesn't include VAT, and as we were paying with a UK card that would slap on another 20% taking it over $500. So I was <em>very</em> relieved it went nowhere near 1k...)</p>
<p>Now we wait 10-15 days (for some reason that I will never understand) for the domain to be transferred, and then my wife's business moves firmly into the .com arena.</p>
<p>And now that I've smashed the $500 glass ceiling, $1,000 will be easy for my next purchase...</p>
<p>It's all about the anchoring.</p>
<hr />
<p>Thanks for reading! If you'd like more, drop me a follow at <a target="_blank" href="https://www.twitter.com/hamzaw">twitter.com/hamzaw</a> - I'll be happy to see you there.</p>
]]></content:encoded></item><item><title><![CDATA[Due Diligence ☠️ :  If you don't have all of these, your startup value is zero.]]></title><description><![CDATA[Due Diligence is make or break for your startup, whether you are being acquired or pitching for investment.
If you don't have the correct documentation in place, you might find that you don't even own your product. And generally speaking, no product ...]]></description><link>https://slashmaker.com/due-diligence-if-you-dont-have-all-of-these-your-startup-value-is-zero</link><guid isPermaLink="true">https://slashmaker.com/due-diligence-if-you-dont-have-all-of-these-your-startup-value-is-zero</guid><category><![CDATA[Startups]]></category><category><![CDATA[Open Source]]></category><category><![CDATA[legal]]></category><category><![CDATA[Due Diligence Company Checklist ]]></category><dc:creator><![CDATA[Hamza]]></dc:creator><pubDate>Wed, 11 Oct 2023 15:09:45 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/ukzHlkoz1IE/upload/e494130430aae72d92a74da228096c5f.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Due Diligence is make or break for your startup, whether you are being acquired or pitching for investment.</p>
<p>If you don't have the correct documentation in place, you might find that you don't even <em>own</em> your product. And generally speaking, no product == zero value.</p>
<p>I learned this lesson the hard way, and it caused at least a 6-month delay in my startup sale (and almost the collapse of the whole thing):</p>
<p><strong><em>Can you afford that when your time comes? Make sure you have everything in this checklist in place from Day 1.</em></strong></p>
<p>The good news: it's not too late. If your startup is already established, you should get together anything that you're missing ASAP, and ensure that it covers you from when you started.</p>
<details><summary>Important Note</summary><div data-type="detailsContent">I am not a lawyer; I'm just relaying my own experience. Make sure you get proper legal advice on everything I mention here. I'm sure you'd rather spend your budget on engineering than lawyers, but that could be a costly mistake in the long term...</div></details>

<h3 id="heading-founders-employment-contracts">✅ Founders' Employment Contracts</h3>
<p>You may think "why would I ever do any harm to my own company?", but investors have seen it happen time and time again.</p>
<p>It may not feel like it in the white heat of your startup, but remember: You are not your company, and your company is not you. Whatever work you do in your company is building value for the company, not for you. You are just like any other employee.</p>
<p>So every founder or shareholder who does any work at all for your startup must have signed a contract that includes the following:</p>
<ol>
<li><p>Assignment of all copyright and Intellectual Property (IP) to the company</p>
</li>
<li><p>Non-competition / restrictive covenant clause</p>
</li>
<li><p>Non-disclosure agreement (NDA)</p>
</li>
</ol>
<h3 id="heading-employment-contracts-even-for-friends-and-freelancers">✅ Employment Contracts (even for friends and freelancers)</h3>
<p>As an early-stage startup you will employ all sorts of people to build your product and company. This might be friends, freelancers, contractors, temps or permanent employees.</p>
<p>I use the word "employ" because even if your friend is doing you a favour for free by writing a software module for you, that module is part of your product and therefore has value.</p>
<p>You might never think your best friend would do you any harm - but are you willing to test that later when there are millions of dollars in the picture? Money does funny things to people...</p>
<p>So <em>anybody</em> who does <em>anything</em> for your startup must have signed a contract that includes the following:</p>
<ol>
<li><p>Assignment of all copyright and Intellectual Property (IP) to the company</p>
</li>
<li><p>Non-disclosure agreement (NDA)</p>
</li>
</ol>
<p>Also, consider restrictive covenants for senior salaried employees.</p>
<p>Employing freelancers or contractors in a foreign country or jurisdiction may add another element of complexity. You may save a lot of money by offshoring, but their local laws may state that without a contract saying otherwise, they own the IP to everything they have developed - which would mean that you don't.</p>
<p>And if you don't own it you can't sell it.</p>
<p>It's no fun chasing down freelancers in another country - 4 years after they stopped working for you - to bribe / ask them politely to sign a retrospective contract in front of a Notary...</p>
<h3 id="heading-agency-contracts">✅ Agency Contracts</h3>
<p>If you use agencies to outsource design or development, make sure your contracts with them include IP assignment and non-disclosure agreement so that they have no possible claim against you in the future.</p>
<h3 id="heading-proper-use-of-open-source-software">✅ Proper use of Open Source Software</h3>
<p>I'm sure your product makes plenty of use of Open Source Software (OSS). It could be for small parts of functionality like a calendar UI, or it could be a major fundamental component like Laravel.</p>
<p>You might not even be consciously <em>aware</em> that you're using Open Source Software, because it is just so prevalent now. <code>npm install</code> and boom!</p>
<p>There are 2 main points to consider when using OSS.</p>
<ol>
<li><p>Ensure that you are using the open source component properly by <em>including</em> it fully intact within your project, rather than copy pasting the bits you want to use into your own code. Unless the licence explicitly states otherwise, this will violate the licence and potentially give the OSS author(s) IP ownership of your code.</p>
</li>
<li><p>Make sure that you are only using OSS which has a "Permissive Licence". This means that you are free to use the software in a commercial application. Using OSS which doesn't allow this means that you cannot distribute it (ie. sell your product or company) and would render your product worthless until you replace that software. This could be a big job depending on how complex the OSS is and how deeply embedded it is into your product.</p>
</li>
</ol>
<p>Consider using a service like FOSSA (<a target="_blank" href="https://fossa.com/blog/all-about-permissive-licenses/">https://fossa.com</a>) to continuously audit your software and ensure that no-one on your team has started to use a random piece of software or OSS in a problematic manner.</p>
<h3 id="heading-bonus-policies-and-procedures">💰 BONUS: Policies and Procedures</h3>
<p>A missing policy is technically not going to cause your investors to run for the hills, but it builds their confidence if you show that you have the little things in place too.</p>
<p>Write up short policies and procedures for the following, share them with your teams and try to enforce them as much as possible:</p>
<ol>
<li><p>Security - include physical security of servers and infrastructure, personal security (use of tokens etc), and principles for security-first software development</p>
</li>
<li><p>Audit of data breaches, data loss and security vulnerabilities: what happened; who discovered / reported it; when did it happen; what was lost / exposed; how was it fixed</p>
</li>
<li><p>Backups - how are backups taken; where are they stored; how long are they retained for; how are they restored; how long does it take to restore them. Consider running regular restoration tests so you're not caught out if something happens.</p>
</li>
</ol>
<hr />
<p>So there you have it: 5 critical items that investors or acquirers expect you to have in place. Without them all, your ownership of your product is in serious jeopardy.</p>
<p>Don't spend years and years of blood and toil only to end up with nothing.</p>
<p>And remember - it's never too late to put these in place: see a lawyer ASAP to get things moving properly.</p>
<p>If you like this article, please comment and share, and follow me at <a target="_blank" href="https://www.twitter.com/hamzaw">twitter.com/hamzaw</a> for more!</p>
]]></content:encoded></item><item><title><![CDATA[How I run a blog with free hosting on AWS]]></title><description><![CDATA[I was a big Wordpress fan for years, but I got sick of its bloat and continuously babysitting its "sneeze and you'll get hacked" vulnerabilities.
Then I used Wix for my wife's blog for a while, but the cost just wasn't worth it.
So now I'm running a ...]]></description><link>https://slashmaker.com/how-i-run-a-blog-with-free-hosting-on-aws</link><guid isPermaLink="true">https://slashmaker.com/how-i-run-a-blog-with-free-hosting-on-aws</guid><category><![CDATA[AWS]]></category><category><![CDATA[Laravel]]></category><category><![CDATA[cloudflare]]></category><category><![CDATA[hosting]]></category><category><![CDATA[#walkthrough]]></category><dc:creator><![CDATA[Hamza]]></dc:creator><pubDate>Wed, 11 Oct 2023 13:47:35 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/npxXWgQ33ZQ/upload/331bba58ae637e84a4e25fac8867531a.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I was a big Wordpress fan for years, but I got sick of its bloat and continuously babysitting its "sneeze and you'll get hacked" vulnerabilities.</p>
<p>Then I used Wix for my wife's blog for a while, but the cost just wasn't worth it.</p>
<p>So now I'm running a Laravel blog on free hosting with AWS free tier for 12 months.</p>
<p>(And after the first 12 months the cost will be less than $6 per month with a 3-year commitment)</p>
<p>Here's how I did it from installation through to optimization - and I'll share some benchmarking results on just how many hits your blog can realistically handle for $0 hosting.</p>
<p>(I'm not going into crazy detail here, just providing a high-level guide. You will need a basic understanding of PHP / Laravel / Linux / AWS to follow along. Feel free to Google, or ask me anything and I will be happy to help you)</p>
<h1 id="heading-objectives-and-tech-stack">🎯 Objectives and Tech Stack</h1>
<p>My objective was to get a fully functional blog online - and loading pages as fast as any commercial offering - with zero hosting costs for at least a year.</p>
<p>"Fully functional" means that my wife - the antithesis of a techie - can operate it on a day-to-day basis without assistance (creating posts, categories etc). So sadly "just push your posts to Github in markdown" wouldn't cut it...</p>
<p>The tech stack I decided on was:</p>
<ol>
<li><p><strong>Off-the-shelf Laravel blog app</strong> - I didn't want to spend 40 hours creating a blog system from scratch, and I wanted a tech that I was comfortable messing around with to customize, add features etc.</p>
</li>
<li><p><strong>Amazon Web Services (AWS)</strong> - specifically their free tier offering: EC2 instance to host the blog, and RDS MySQL database.</p>
</li>
<li><p><strong>Cloudflare</strong> - I wanted Cloudflare's caching to max out the performance of the blog and and to reduce egress charges from AWS (OK so AWS gives you 100GB per month free, but a just-in-case strategy doesn't hurt...)</p>
</li>
</ol>
<h1 id="heading-the-laravel-app">💻 The Laravel App</h1>
<p>I'm a big fan of <a target="_blank" href="https://creative-tim.com">Creative Tim</a>, and I had just picked up their entire Laravel collection for a bargain in their 10-year anniversary sale. Included in that collection is a <a target="_blank" href="https://www.creative-tim.com/product/material-blog-pro-laravel">blog app</a> which has a nice clean layout and a pretty comprehensive backend feature set: CRUD for users (including readers who can comment on posts), categories, tags and of course posts. It even includes a full-text search feature.</p>
<p>Although the app I chose was <em>technically</em> a paid solution, you can find many free Laravel-based blogs on the internet, from <a target="_blank" href="https://madewithlaravel.com/pj-blog">simple</a> to <a target="_blank" href="https://github.com/guillaumebriday/laravel-blog">crazy-fully-featured</a> to <a target="_blank" href="https://octobercms.com">entire CMS platforms</a>.</p>
<p>After downloading the app, the first thing I did was strip out all the junk templated content that Creative Tim always helpfully bloats for you: Lorum ipsum text, footer links, placeholders, etc.</p>
<p>I also cleaned up the included database seeders to make them more useful, and connected my local installation to my sqlite database for testing.</p>
<p>I want to re-use the same blog app for multiple blogs (my kids are pestering me to build one for them) so next I replaced some of the hardcoded text with <code>.env</code> variables. This included the site name, homepage hero heading and sub-heading, copyright text, logo URL and social link URLs. I did this using <code>.env</code> instead of database to make it super easy (<code>&lt;img src="{{ env('LOGO_URL') }}"/&gt;</code>) and to avoid DB hits.</p>
<p>There are lots of other hardcoded details like OG Meta Tags that I will fix later.</p>
<p>Finally, I made some small customizations like adding the logo to the navbar and changing some of the wording on the app. I didn't make any changes to the backend (admin panel) code. There's a lot of theme junk there too, but no-one is going to see it yet. I'll worry about that if someone actually signs up as a member...</p>
<h1 id="heading-aws">🧠 AWS</h1>
<p>I opened a brand new AWS account in my wife's name to make use of their 12 month free tier. There is actually <a target="_blank" href="https://aws.amazon.com/free/?all-free-tier.sort-by=item.additionalFields.SortRank&amp;all-free-tier.sort-order=asc&amp;awsf.Free%20Tier%20Types=*all&amp;awsf.Free%20Tier%20Categories=*all">a ton of stuff</a> they give you to play around with for free, but for now all I want to use is EC2 for a linux instance on which to run my blog, and RDS for its MySQL database.</p>
<h2 id="heading-set-up-ec2-instance">Set up EC2 Instance</h2>
<p>I created a new <code>t2.micro</code> instance with Amazon Linux 2023, and gave it 30gb of gp3 disk space, which is basically what you can use for the free tier. <code>t2.micro</code> is an <em>ancient</em> instance type, with 1GB RAM and 1 vCPU, but it runs nginx, PHP and Laravel with no problems at all. We're not going to run MySQL server on the instance, which helps.</p>
<p>Create a new Security Group with inbound SSH, HTTP and HTTPS access from anywhere. When you have SSL set up later, remove the HTTP access.</p>
<p>Once your EC2 instance is created, assign an Elastic IP to it and log in via SSH (you did save your PEM didn't you...?) Now it's time to install nginx, PHP and your blog.</p>
<p>Here's a quick summary:</p>
<ol>
<li><p>Make sure OS is up to date:</p>
</li>
<li><pre><code class="lang-bash">   sudo dnf update
</code></pre>
</li>
<li><p>Install and run nginx:</p>
<pre><code class="lang-bash"> sudo dnf install nginx
 sudo systemctl <span class="hljs-built_in">enable</span> --now nginx
</code></pre>
</li>
<li><p>Install PHP 8.2:</p>
</li>
<li><pre><code class="lang-bash">   sudo dnf install php8.2
</code></pre>
</li>
<li><p>Install Composer:</p>
<pre><code class="lang-bash"> curl -sS https://getcomposer.org/installer | php
 sudo mv composer.phar /usr/<span class="hljs-built_in">local</span>/bin/composer
 sudo chmod +x /usr/<span class="hljs-built_in">local</span>/bin/composer
</code></pre>
</li>
<li><p>Install PHP MySQL module:</p>
</li>
<li><pre><code class="lang-bash">   sudo dnf install php8.2-mysqlnd.x86_64
</code></pre>
</li>
<li><p>I pushed my modified blog app to github, so I needed to install git:</p>
</li>
<li><pre><code class="lang-bash">sudo dnf install git
</code></pre>
</li>
</ol>
<p>Then it was a case of pulling my code, doing the usual Laravel stuff (chmod, chown, symlinking storage, etc) and creating my .env file.</p>
<p>It's also time to configure the nginx virtual server. I created a <code>.conf</code> file for my site in <code>/etc/nginx/conf.d</code>. So far I've left the PHP-FPM configuration as default (eg. max workers 50) but I may tweak them later to optimize.</p>
<h2 id="heading-set-up-rds-database">Set up RDS database</h2>
<p>Next I created the MySQL database in RDS. In the UI for creating a new database, there's actually an option to set up within the free tier, so it's very simple.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696699889595/3cf5b8a7-bba1-49c5-85dd-6f6229b7d891.png" alt class="image--center mx-auto" /></p>
<p>You get a <code>t3.db.micro</code> instance (1GB, 2vCPU) which is slightly less sucky than the EC2 offering, but again it gets the job done. You also get 20GB of storage which is plenty for a blog. Make sure you change the default <code>gp2</code> SSD storage setting to <code>gp3</code> for better performance.</p>
<p>Also, make sure you have public access disabled. That means that only your EC2 instance (or anything else in your VPC) can access the database, and it cannot be accessed from outside.</p>
<p>Finally, just set the master (root) username and password (and make a note of them!) and you're good to go. It will take a few minutes to create your DB, and then you will get its endpoint (host URL) from the "Connectivity &amp; security" tab in the RDS console.</p>
<p>Once your DB is created, log in with your master credentials tunnelling via your EC2 instance (remember, there is no public access to your database) and create a new schema and user for your blog.</p>
<pre><code class="lang-sql"><span class="hljs-keyword">create</span> <span class="hljs-keyword">database</span> blog;
<span class="hljs-keyword">create</span> <span class="hljs-keyword">user</span> <span class="hljs-string">'blogger'</span>@<span class="hljs-string">'&lt;ipaddress&gt;'</span> <span class="hljs-keyword">identified</span> <span class="hljs-keyword">by</span> <span class="hljs-string">'&lt;password&gt;'</span>;
<span class="hljs-keyword">grant</span> <span class="hljs-keyword">all</span> <span class="hljs-keyword">privileges</span> <span class="hljs-keyword">on</span> blog.* <span class="hljs-keyword">to</span> <span class="hljs-string">'blogger'</span>@<span class="hljs-string">'&lt;ipaddress&gt;'</span> <span class="hljs-keyword">with</span> <span class="hljs-keyword">grant</span> <span class="hljs-keyword">option</span>;
</code></pre>
<p>Replace <code>&lt;ipaddress&gt;</code> with the <em>private</em> IP address of your EC2 instance. This ensures that only the server itself can access the database.</p>
<p>Finally, configure your DB driver, host, database name, user and password in the Laravel app and run the seeders.</p>
<h1 id="heading-cloudflare">☁️ Cloudflare</h1>
<p>I love Cloudflare. There aren't many companies that give so much functionality for free and update their product so often with new features.</p>
<p>Cloudflare gives you performance enhancements and free CDN which I use to reduce AWS egress charges (AWS charges you for all data sent out from your EC2 instance etc S3 buckets etc).</p>
<p>I'm also using Cloudflare's free SSL to give me a lovely long 15 year certificate instead of using Certbot and having to renew it every 3 months.</p>
<p>I created a new Cloudflare account for my blog, but you can add as many domains as you like to a single account.</p>
<p>The first step was to switch my domain's DNS nameservers to Cloudflare. Cloudflare can't help you until they have full control of your domain.</p>
<p>I was expecting to have to set up my DNS entries for email MX records etc. again once the nameservers switched over, but I was pleased to find that Cloudflare had automatically imported them all.</p>
<h2 id="heading-dns-settings">DNS Settings</h2>
<p>I created 2 DNS entries for my blog. I want it accessible on the root domain name, and also on www.</p>
<p>So I created an A Record with Name as <code>@</code> and Value as the Elastic IP address of my EC2 instance. Then I created a CNAME Record with Name as <code>www</code> and Value as the domain name.</p>
<p>Both records are set as "Proxied" which means they can make use of Cloudflare's caching, DDOS protection and SSL.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696711406697/e01f9c3d-56f9-4112-bc24-99817aa14037.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-performance-settings">Performance Settings</h2>
<p>Most of Cloudflare's default performance settings are fine, but I enabled a couple of extra settings. There isn't much else to do on the free package.</p>
<p>Go to Optimization -&gt; Content Optimization</p>
<ul>
<li><p>Rocket Loader - enabled</p>
</li>
<li><p>Auto-Minify - enabled for all media types</p>
</li>
</ul>
<h2 id="heading-ssl-certificate">SSL Certificate</h2>
<p>It's very simple to create an SSL certificate on Cloudflare and use it on your website. The expiry time is up to 15 years, which is far more convenient than using Certbot and hoping that the renewal cron job is going to work every 3 months...</p>
<p>(Note on long certificate expiry: the certificate we are creating here is just for Cloudflare's use; it is not served to the user's browser. Cloudflare will generate a browser cert for your site and automatically renew it every 6 months)</p>
<ol>
<li><p>From the Cloudflare dashboard go to SSL / TLS -&gt; Origin Server. Click "Create Certificate" button.</p>
</li>
<li><p>Ensure the hostnames are correct (you can use <code>*.yourdomain.com</code> to generate a wildcard SSL for all your hosts which is really nice) and choose your certificate validity (15 years FTW). Click "Create"</p>
</li>
<li><p>Copy the Origin Certificate and Private Key that Cloudflare generates, and put them into files on your server called <code>origin.pem</code> and <code>private.key</code> . Place them in the <code>etc/ssl</code> directory.</p>
</li>
<li><p>Update your nginx conf file to change the port from 80 to 443 and to add the certificates.</p>
</li>
</ol>
<pre><code class="lang-bash">server {
    listen 443 ssl;
    ....
    .... 
    ....
    ssl_certificate /etc/ssl/.pem;
    ssl_certificate_key /etc/ssl/private.key;
}
</code></pre>
<ol>
<li><p>Restart nginx service for your changes to take effect.</p>
</li>
<li><p>On the Cloudflare dashboard go to SSL / TLS -&gt; Overview and change the encryption mode to "Full (strict)"</p>
</li>
</ol>
<p>That's it! You now have a fully SSL'd up site, with a certificate that will be automatically renewed for the next 15 years.</p>
<h1 id="heading-performance-and-capacity">💨 Performance and Capacity</h1>
<p>So now I have my nice shiny blog, and it's running fine in my browser. Time to run some performance tests to ensure it won't fall over if someone else views it at the same time....</p>
<p>I spammed the refresh button on the homepage continuously for over a minute, and the CPU hardly noticed: utilization only went up to 5%:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696700330930/63727794-1499-4de9-bb74-0aad4f09afdd.png" alt class="image--center mx-auto" /></p>
<p>The 1GB RAM is comfortably settled, with only ~250mb in use when idle.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696699628029/c5920758-7ebc-4573-b108-50fd778a94ec.png" alt class="image--center mx-auto" /></p>
<p>I stress-tested with 50 simultaneous users using <a target="_blank" href="https://loadium.io">Loadium</a>. They have a free package which gives you 10 tests per month. I programmed it to simulate each user hitting the homepage and then 2 other pages with a few seconds pause between each page.</p>
<p>Even with a ton of php-fpm processes (each process is a single connection, and nginx is currently configured to allow 50 maximum by default) the CPU never really maxed out and the RAM still had 500mb buffer.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696701588720/3073d576-46a4-47d6-817c-b853fdd8b1f9.png" alt class="image--center mx-auto" /></p>
<p>I was browsing the site while the test was going on and although each page load was a little bit slow, it was still very usable.</p>
<p>Here are the stress test results:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696702420905/5f4a9e97-1ded-43ae-85a9-fd6723101d84.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696702431663/83c583b0-3331-4fbd-8d3a-cef8af306015.png" alt class="image--center mx-auto" /></p>
<p>The RDS database CPU utilization peaked at 22% - still plenty of mileage there.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696702802083/b6644328-40ef-423f-86a4-4ae768cfa2b1.png" alt class="image--center mx-auto" /></p>
<p>The site handled the onslaught better than I had expected. My free AWS-hosted blog might not survive a link from the front page of Hacker News, but it should be able to take anything else in its stride. And with better caching I reckon it could handle Hacker News too.</p>
<h1 id="heading-the-future">🚀 The Future</h1>
<p>There are a few things I want to optimize and improve on the blog.</p>
<ol>
<li><p>Build more features. My wife had things on her Wix blog like an Instagram wall and testimonials, and it would be super easy to build them on the Laravel blog. Also I will add landing pages for email lead capture - again really simple using Laravel.</p>
</li>
<li><p>Try using <a target="_blank" href="https://github.com/laravel/octane">Laravel Octane</a> to squeeze more performance out of the server.</p>
</li>
<li><p>Move static assets to a separate subdomain backed by CDN. Also add better caching, either through Cloudflare, nginx or Varnish.</p>
</li>
<li><p>Play around with nginx configuration to improve stress test performance - I'll report back.</p>
</li>
</ol>
<p>When my free 12 months hosting ends with AWS, I will switch the server to an instance like t3a.small (2vCPU, 2GB RAM) and move the database off RDS and on to MySQL server running on the instance itself. RDS is way too expensive to justify using on something like this....</p>
<hr />
<p>Thanks for reading. If you would like to follow along for more, connect with me on <a target="_blank" href="https://twitter.com/hamzaw">Twitter</a> where I write about building products and startups.</p>
]]></content:encoded></item></channel></rss>