Greenish central processing unit of a computer with some flames behind to try and make it cool

Hosting small websites on EC2

02 October 2022

You have a small site where you don’t expect many visitors, but you want dynamic server rendering and you want it cheap. My new favourite hosting for this use-case is Amazon Web Services’ EC2.

You might struggle with the fact you're giving the richest people in an unequal world more money. And maybe your time is worth too much to waste on server configuration. But if you have a small passion project, a cheap EC2 instance provides the most freedom for the lowest price.

AWS don’t heavily market how to do things cheaply. At the end of the day, it’s in their interest to push higher margin platform-as-a-service over dumb infrastructure.

AWS won’t give you detailed help with setting up your stack. There's too much to document for a rented computer which can do anything you want it to. Although, they make a valiant effort to document the most heavily trodden cow paths.

The secret is that you can install all your stuff on EC2. And on the cheapest type of instance. You can save a lot of money and complexity. Basic building blocks like EC2 help us bring back mildly dynamic websites.

It doesn’t even seem like it’s in AWS’s interest to bother to cater to cheapskates like me. And yet they serve my use-case better than any other hosting provider. I guess 15 years of running infra-as-a-service means they’re able to automate the sales, admin and maintenance away. And they benefit from an economy of scale of biblical proportions.

What type of website are we talking about? #

What is the use-case I’m talking about? If you want the absolute cheapest possible website, you’re going to want a static site. There’s a smorgasbord of cheap and free places to host static HTML, CSS, and JavaScript (github pages and neocities come to mind). The site you’re reading from now is all static files in azure storage, and I wrote a blog post about moving here.

But only running static files is limiting. I want to make websites that do things. You might yell at the screen: “use JavaScript” and “use a service”. But we can’t write everything in JavaScript: There’s always going to be a point where we have privileged data, or when we risk a spinnaggedon request waterfall. I’ve enjoyed making a lot of apps that only run on the client. But there are a lot of apps where this just doesn’t make any sense — see Jason Miller’s Application Holotypes.

And services? We’re trying to be cheap here! If I can pay $5.00 a month for a server, why would I want to pay another $5.00 a month for comments, another $5.00 a month for authentication, and another $5.00 a month for analytics. There’s a point where this is worth it, but it isn’t your side project. EC2 gives you a virtual machine that you can use for whatever you want.

Spinning up an instance #

I wanted to spin up a quick PHP website which didn’t need a database - just a JSON file for data. I created a T2.nano instance, using a gp3 volume for storage (this is like the hard drive for the VM). I went with Amazon Linux 2 for an operating system - I assume this OS has been optimized for the cloud. The marketing certainly says that it has been.

Now to make our instance do something, we need to connect to it. There are ways to connect to the machine graphically, but we’ll use SSL because I like to cosplay as someone good at computers.

After you create an instance, you’ll be prompted to download a .pem key. Keep this safe. If you lose it you won’t ever be able to connect to your EC2 instance. By default, the username on Amazon Linux will be ec2-user. And you need the Public IPv4 DNS. You can find it in the instance details.

Then, to connect to a fresh Amazon EC2 instance via SSL from windows PowerShell:

    ssh -i C:\path\to\mykey.pem ec2-user@my-instance-public-IPv4-address.amazonaws.com

You might be prompted for some trust warning or something which I said yes to without understanding what I was agreeing to.

Now you should get some ASCII art courtesy of Adam Selipsky.

Installing stuff #

You’re in. Let’s get Apache:

    sudo yum install -y httpd

This will use a Linux package manager called yum to download and install Apache. After this has finished, you can start Apache with:

    sudo systemctl start httpd

And test it with:

    curl http://localhost:80

And stop it with:

    sudo systemctl stop httpd

Great. Now you can grab and install PHP.

If you’re like me, you probably want nice URLs. You can do this with Apache’s mod_rewrite module, and redirect all traffic to index.php by editing /etc/httpd/conf/httpd.conf. Edit it over SSL by using a command-line text editor like nano. Add the following to the end of the config file:

    #This did not work for me
    <IfModule mod_rewrite.c>
        RewriteEngine on
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteRule . index.php [L]
    </IfModule>

Wait that didn’t work for me (even though it worked for everyone else on stack overflow). For me, (and maybe you), this was what I needed:

    #Redirecting all input to index.php
    <IfModule mod_rewrite.c>
        RewriteEngine on
        RewriteCond /path/to/document/root/%{REQUEST_FILENAME} !-f
        RewriteCond /path/to/document/root/%{REQUEST_FILENAME} !-d
        RewriteRule ^(.*)$ /index.php [QSA,L]
     </IfModule>

Now you can make your own little PHP router like this one from John O. Paul. And you’ll need some way to get your code onto the machine (I’ve just been pulling down from github using git but I’m sure there’s a better way . . . github action?).

You might run into another problem. Apache won’t have the rights to write files! There are some instructions on the setting-up-LAMP page on the AWS site for how to sort this out. It involves a command called chown which might be my favourite name for a command.

And we all love locks to the left of our URL bar. We better buy a domain, set up Amazon name servers, and also get a TLS certificate from let’s encrypt and install it into Apache.

Before you can connect with a site hosted on your EC2 VM, you’ll also need enable traffic from all IP addresses using Inbound rules.

The counterargument #

Wait. Those were a lot of steps. And for a site that might not scale very well? Was this all worth the time and effort? Was the cheapness really worth it? How much maintenance is this all going to require? What about security? Is everything configured properly in a way where no one’s going to steal my data?

These are all extremely valid questions. And they are the reason you might just want to run away and host a site on Netlify, or try AWS amplify if you’re still desperate to give Bezos more bucks.

However, the nerdy side of me enjoyed getting this all working, and (I hope) I’d be faster at setting it all up the second and third times I do this. I really like the idea that I can have a deployment environment which isn’t limited by what the powers-that-be decide I’m allowed.

And I love that it’s cheap . . . 🤷‍♂️

Back to blog