Steps to Create a Web Server and Host a Domain Live on the Web


Typing on Laptop

In my case I am creating a blog for my website, mikeynic.com.

Pre-requisites

Here is a list of pre-requisites needed to perform all of the actions outlined in this post.

  • Install and set up git and GitHub on the command line
  • Install and set up the Heroku CLI and sign in to your heroku account on the command line
  • Install the the latest version of Node

Initialising and Running the Basic Service

Lets first get started with the service code.

Create the service directory:

mkdir mikeynic-service
cd mikeynic-service

Initialise npm project, install express, and create server.js file:

npm init -y
npm install express
touch server.js

Open the server.js file and put the following code inside:

// Import Express
const express = require('express');
const app = express();
const port = 3000;

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

// Start the server
app.listen(port, () => {
  console.log(`Server is running on http://localhost:${port}`);
});

Now you will be able to run the server and visit localhost:3000 by running:

node server.js

Setting up EJS

EJS (Embedded JavaScript) is a simple templating language that lets you generate HTML markup with plain JavaScript. It is commonly used in Node.js applications to render dynamic web pages.


Typing on Laptop

We are going to be using EJS for our entire blogging page. Later on we will probably introduce HTMX to replace elements of the page without having to reload the whole thing. But for now, whilst we get setup, it's okay to just use EJS.

On the command line run:

npm install ejs

And in server.js add this line in order to successfully render EJS code properly for the client i.e. the person looking at the website:

app.set('view engine', 'ejs');

To create an EJS file and render it, we need to create a views folder and then create a home page EJS file called index.js:

mkdir views
touch views/index.ejs

In your new index.js file paste the following code:

<html>
<head>
    <title><%= title %></title>
</head>
<body>
    <h1>Hello, <%= name %>!</h1>
</body>
</html>

In order to render the home page and inject the name and title variables replace the code below:

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

with:

app.get('/', (req, res) => {
    res.render('index', { title: 'Home', name: 'World' });
});

Uploading the Code to a GitHub repository


Typing on Laptop

Create a new EMPTY repo on GitHub call it whatever you want. Do not "Add a README file". I would probably make the repository private too. There is no reason to add a .gitignore or a licence upon GitHub repository instantiation.

Add the .gitignore file found here to your repository in the root of the directory.

Follow the "...or create a new repository on the command line" instructions:

git init
git add *
git commit -m "first commit"
git branch -M main
git remote add origin <your repo goes here>
git push -u origin main

Set-Up a deployment pipeline with Heroku


Typing on Laptop

Install the JavaScript dotenv package:

npm install dotenv

In the server.js file add the following line to the top:

require('dotenv').config();

This will allow Heroku to inject the desired port straight into our application in the process.env.PORT variable.

In server.js replace the following line:

const port = 3000;

With:

const port = process.env.PORT || 3000;

This allows us to assign the port to 3000 locally, but inject Heroku's desired port when being deployed.

Once you get to Heroku and have created an account, got to the home page and click the "new" button --> "create new app". Choose the region that you are in and give the app a name. I'm going to call mine "mikeynic-app". Click "create app".

  • Now that this has been created, connect your GitHub to Heroku under the "deployment method" section.
  • Find your repository by searching for it in the "Connect to GitHub" section and push "connect" on the GitHub repository you wish to deploy.
  • Click the "Enable Automatic Deploys" button so that every commit gets automatically built and pushed to your website.
  • Make sure in the "Deploy a GitHub branch" section the main branch is selected.
  • Click "Deploy Branch".
  • Wait for a second whilst the build logs are moving. Now once it's built successfully you can scroll all the way to the top of the page and click the "Open App" button. You should see that this has been successfully deployed to a link that looks like <app-name>-<random-sequence>.herokuapp.com.

Setup a Domain with CloudFlare

Typing on Laptop

I bought my domain from GoDaddy, but I wouldn't recommend using them to manage your DNS and re-routing rules. I prefer Cloudflare - so this guide will teach you how to use Cloudflare.

Open a Cloudflare account and navigate to the "websites" section, type in the domain you want to add and Cloudflare will walk you through how to allow Cloudflare to manage your GoDaddy domain.

On GoDaddy go to Domains --> Portfolio --> DNS --> Nameservers and push change nameservers --> "I'll use my own nameservers". Input the specified Cloudflare nameservers.

On the cloudflare website push continue and it'll take you to the "Quick Start Guide". Push "Get Started" and make sure the "Automatic HTTPS rewrites" is checked and the "Always Use HTTPS" is also checked. Push "Finish" and you will be taken to the overall configuration page.

In Heroku, go to the "settings" page for your app and go to "Domains" --> "Add domain". Put your domain name in this field and create - note that your domain must have www. before it. You want to copy this "DNS target".

Go back over to Cloudflare and go to DNS --> Records and edit the CNAME record with the name: www and paste the "DNS target" from Heroku in the "target" box in Cloudflare.

Back on the command line execute the following where <app-name> is replaced by your Heroku app name:

heroku certs:auto:enable -a <app-name>

This will mean that https is allowed from cloudflare.

Ensure all routing of www and non-www works in Cloudflare.

Typing on Laptop

In Cloudflare go to Rules --> "Redirect Rules" --> "Create Rule".

  • I use the name "non-www-re-route"
  • Tick the "Custom filter expression"
  • "When incoming requests match"
    • Field: hostname
    • Operator: equals
    • Value: your-url (WITHOUT www)
  • Then:
    • Type: Static
    • URL: https://www.<your-domain-name>
    • Status Code: 301

Set up The Landing Page

Now you are free to set up the landing page however you wish in the index.ejs file. Happy programming!

Final Remarks

You could've just used netlify.