I made a website. Now what?

So you built a website, and it works on localhost. How do you get the world to see your creation? You’ll need two things: a domain, and a place to host your website.

The domain is what people enter in the URL bar of their browser. It’s the very first impression you make–a long, difficult-to-spell website isn’t ideal. Getting a domain is the easy part: you go to a domain registrar, type in the domain name you want, and buy it. Popular domain registrars are Google Domains, GoDaddy, and NameCheap. It’s worth shopping around, although it’s likely you will see the same price everywhere. Somewhere around $12-$20/year is pretty common. In most cases, you buy a domain name for a year. Every year, you renew it. Most big domain registrars will let you renew for up to 10 years in advance. You usually do not get a discount for doing this–it’s just for the peace of mind. You cannot buy a domain name for a lifetime–do not let any website convince you of that. Any reputable registrar will let you buy annually, or renew up to 10 years. It is worth noting that if you purchase a domain name from one registrar, you’re not locked in: you can transfer your domain name to a different one if you prefer.

Having a domain name is great, and does enable a lot of things: for example, you can now have an e-mail address with your custom domain. More importantly, once you own a domain name, you can configure the DNS records to achieve what you need. For example, an A record is used to resolve your domain name into an IP address. If you host a website on a server, that server will have an IP address, and setting an A record with that IP address as the value will let users type in your domain name in the URL bar and end up on your website. But we’re getting ahead of ourselves: you cannot do any of this if you don’t have a server to point to. Let’s fix that.

There are two types of websites, broadly speaking: static, and dynamic. Most portfolio websites can be done statically, i.e., there’s no server involvement. It’s pretty easy to find out what kind you need: ask yourself, “Do I need to process anything that cannot be done in the browser?” For example, a search function usually requires a server to process the query, and run it through a database. Speaking of: if you need a database, you need a server. The reason we make this distinction here is that you can host a static website for free, but servers are typically not free. Whether you need a server or not will also depend on your choice of technology. The rest of this post is divided accordingly.

Static websites

A static website can be hosted for free. Personally, I use GitHub Pages, but there are others like Netlify and Heroku as well. Here, I will talk about GitHub Pages and my personal solution.

I use two repos on GitHub for my website: one for the source code, and one for the transpiled website. My website is built with React, and as with any modern front-end framework, it needs to be transpiled so that browsers can understand it. This is my source code repo. It’s a pretty standard setup for a React/Sass website. I have some specific scripts for deploying, though: you will see that the dist.sh file simply contains one command: npm run deploy. Going through package.json, we see that the following occurs:

rm -rf dist/                              # predist
webpack --config webpack.prod.js          # dist
cp assets/* dist/                         # postdist
cp dist/* ../yrahul3910.github.io/        # deploy
cd ../yrahul3910.github.io/ && git commit -am 'Update' && git push    # postdeploy

I first get rid of anything previously built; then I build my production package. This does not include assets such as images, so I copy those over. I then copy those files over to my other repo. Note that this other repo must be called username.github.io. Then, I simply push the changes. Let’s look at this other repo. It has all my usual build artifacts, but it does include a CNAME file. This is important, and must be named exactly that. The file merely contains my domain name.

Next, we need to work on the DNS side of things, which you do on your domain registrar’s website. For this, follow the GitHub Pages docs–they’re an excellent resource. Once you follow those instructions, you should have a working website, hosted on GitHub Pages.

Dynamic websites

A dynamic website is perhaps easier to host. You find a hosting provider, upload your code, run the server, and then point a DNS A record to that server’s IP address. You have plenty of great options here: AWS, DigitalOcean, and Google Cloud are some. You definitely want to shop around here, since prices do vary. DigitalOcean is nice because you see an upfront price–that is trickier with AWS EC2. You could instead use AWS Lightsail, which is great for small-scale websites like a personal website, and shows an upfront monthly pricing, starting at just $3.50/month.

Upload your code, including your server code, to the instance you just created. The easiest way is to just do a git clone on the server after you ssh into it. You have a couple of options here: use a reverse proxy server like nginx, use something from the cloud provider, or use firewall rules. Let’s look at one option using AWS Lightsail. We’ll start by creating a test directory and creating a Hello World app:

mkdir tmp && cd tmp
npm init
npm i --save-dev express

We can create a simple index.js file:

#!/usr/bin/env node
const express = require('express');
const app = express();
const port = 3000;

app.get('/', (req, res) => {
  res.send('Hello World!');

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`);

Head over to AWS, and search for Lightsail. Click Create Instance, choose Linux as the platform, and select Node.js under Apps + OS. For our purposes, the lowest instance plan should suffice. Click on Create Instance. Once the instance is done booting, click on it, and download the SSH key. Then, change its permissions and copy the code into the machine. Replace ~/test.cer with the location of your SSH key file.

chmod 400 ~/test.cer
cd .. && scp -r -i ~/test.cer ./tmp/ bitnami@<IP address>:~/
ssh -i ~/test.cer bitnami@<IP address>

Within the machine, let’s set things up:

cd tmp && npm i
chmod +x ./index.js
forever start ./index.js

The application is now running. Let’s test it locally. It won’t work out-of-the-box because ports other than 80 and 443 are blocked. We’ll use SSH tunneling as recommended instead. On your local machine, run:

ssh -N -L 8080: -i ~/test.cer bitnami@<IP address>

You can now visit localhost:8080 in your browser and it will show Hello World! Now, following their docs, we will configure virtual hosts that connect to our application:

sudo cp /opt/bitnami/apache/conf/vhosts/sample-vhost.conf.disabled /opt/bitnami/apache/conf/vhosts/sample-vhost.conf
sudo cp /opt/bitnami/apache/conf/vhosts/sample-https-vhost.conf.disabled /opt/bitnami/apache/conf/vhosts/sample-https-vhost.conf
sudo /opt/bitnami/ctlscript.sh restart apache

And now visiting the IP address of the machine will show you the same Hello World message. The end of the docs I linked to has instructions to set up HTTPS, which you should do.

Leave a Comment

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