Building This Website

Introduction

  • This is the first post on this website
  • I will be documenting the process of building & hosting this website
  • I will be using Hugo to build this website

Sections

Done & Published as blogs

Done but not published as blogs

  • Gitlab CI setup

To-do

  • Improve SEO
  • Create a sitemap
    • I think Hugo has a built-in sitemap generator
    • But want to learn more about it & maybe customize it
  • Create a newsletter
  • Add a comments section

Subsections of Building This Website

Create Hugo Website

Pre-requisites

  • Hugo installed on your machine docs here
  • Git installed on your machine docs here

Create a new Hugo website

  • Create a new Hugo website : hugo new site <website-name>
  • Go to the website directory : cd <website-name>
  • Initialize a new git repository : git init
  • I am using the Relearn theme.
  • By followong the docs here you customize & setup your website locally.
  • Once you are done with the setup, you can build the website using hugo command.
  • This will generate a public folder in your website directory.
  • This folder contains all the static files for your website and is ready to be deployed.

Git setup

  • Create 2 seperate repositories for the website (public folder) and the other source code.

  • Add the public folder to the .gitignore file in the source code repository.

  • Add the source code repository as a submodule in the public folder.

    • cd public
    • git init && git add . && git commit -m "Initial commit"
    • git submodule add <source-code-repo-url> <path-to-source-code-repo>
  • Push the public folder to a remote repository (I am using GitLab)

VM setup

Setting up a cloud VM

Requirements

  • A linux server with a public IP address.

I am using a Ubuntu 22.04 server with 1GB RAM and 1vCPU on Oracle Cloud.

Update the system

  • Boot the VM & ssh into it.
  • Update the system: sudo apt update && sudo apt upgrade -y

Install docker

sudo apt remove docker docker-engine docker.io containerd run

sudo apt update
sudo apt install \
    ca-certificates \
    curl \
    gnupg \
    lsb-release

sudo mkdir -p /etc/apt/keyrings
 curl -fsSL <https://download.docker.com/linux/ubuntu/gpg> | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] <https://download.docker.com/linux/ubuntu> \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin

Add current user to docker group

  • If you are not logged in as root, you will need to add your user to the docker group to run docker commands without sudo.
sudo usermod -aG docker $USER

Open ports for http & https

  • This is Oracle Cloud specific as I am using it.
  • Go to the VM’s home page.
  • Find “Subnet” under “Primary VNIC” section and click on it
  • Navigate to “Security Lists” > “Default Security List for VCN” > Add Ingress Rules button
  • Source CIDR: 0.0.0.0/0, IP Protocol: TCP, Destination Port Range: 80, 443
  • Click on “Add Ingress Rules” button
  • This will open ports 80 & 443 to the internet

Nginx setup

Docker network

  • Create a network my-services with following command
    • docker network create my-services
  • This network will be used by all the services that will be proxied by nginx.
  • It is created so that its easier for us to connect to the services from nginx just by their container name.

Create nginx proxy manager container

  • Create a directory apps in home dir
  • Inside it, create following directories:
    • apps/nginx
    • apps/nginx/data
    • apps/nginx/letsencrypt (its only required if you want to use letsencrypt)
  • Create a file apps/nginx/docker-compose.yml with following content:
version: '3.8'

services:
  nginx:
    container_name: 'nginx'
    image: 'jc21/nginx-proxy-manager:latest'
    restart: unless-stopped
    ports:
      - '80:80'
      - '81:81'
      - '443:443'
    volumes:
      - ./nginx/data:/data
      - ./nginx/letsencrypt:/etc/letsencrypt
    networks:
      - my-services

networks:
  my-services:
    name: 'my-services'
    external: true
  • Run docker-compose up -d to start nginx proxy manager.

Configure nginx proxy manager from browser

Cloudflare & SSL

Pre-requisites

  • A registered domain name
  • A Cloudflare account

Cloudflare setup

  • Add your domain to Cloudflare
  • Cloudflare will give you two nameservers
  • Go to your domain registrar and change the nameservers to the ones provided by Cloudflare
  • Wait for the nameservers to propagate
  • Go to Cloudflare and click on SSL/TLS tab
  • Select Full under Overview section
  • Select Edge Certificates tab and enable Always Use HTTPS option
  • Select SSL/TLS tab and enable Automatic HTTPS Rewrites option
  • Select DNS section and add following records:
    • A record with name @ and value your-server-ip
    • A record with name www and value your-server-ip
  • Navigate to Origin Certificates tab and click on Create Certificate
  • Generate a certificate with default settings.
  • Download the certificate and key files.

SSL setup

  • Go to the NPM dashboard and click on SSL Certificates and add the certificate and key files.
  • Visit your domain and you should see the nginx welcome page with a valid SSL certificate.

Deploy to server

Pre-requisites

  • A website built with Hugo (i.e the generated public folder)

Folder structure

  • cd into the apps folder created earlier
  • Create a new folder for your website mkdir blog-site
  • cd blog-site
  • Pull the public folder from the git repository of the public folder
    • git clone <repo-url>
    • If your repo is private, you can use the following command:
    • git clone https://username:[email protected]/username/blog-site.git

Nginx setup

  • How I did this was that I created a new nginx container (not Nginx Proxy Manager) and mounted the public folder to /usr/share/nginx/html in the container.
  • Here’s the docker-compose.yml file for the container:
# ~/apps/blog-site/docker-compose.yml
version: '3.8'

services:
  blog:
    container_name: 'blog'
    image: 'nginx:stable'
    restart: unless-stopped
    expose:
      - '80:80'
    volumes:
      - ./<path-to-cloned-folder>:/usr/share/nginx/html
    networks:
      - my-services

networks:
  my-services:
    name: 'my-services'
    external: true

Configure Nginx Proxy Manager

  • Now, we will configure Nginx Proxy Manager to proxy requests to our website.
  • Go to the Nginx Proxy Manager dashboard and click on Proxy Hosts tab.
  • Click on Add Proxy Host and fill in the details: New Proxy Host New Proxy Host
  • Go to the SSL tab and select the SSL certificate we created earlier. SSL Certificate SSL Certificate
  • Save the configuration and visit your domain. You should see your website.