2024-10-28 Setting Up a Landing Page for Pointegrity

Several weeks into the journey (and this blog) in software development (here and here), I only get more and more stuff waiting for attention. It is impossible to complete all emerging tasks and document them properly, so I am going to relax a bit by keeping the posts chronologically, as journal entries, without having to complete each of them. I will come back and update the posts that need revision.

Preparation

I need a home site, i.e. pointegrity.com, as a hub to future contents and services that I am building. Initially this site does not have to contain a lot of information, so a simple landing page will do. After some considerations and web surfing, I pick the following tool set:

  • Use the static site generator Hugo and an accompanying theme to build and test the website locally.
  • The whole project, including the resulting website contents generated in a distribution folder, is made a git repo
  • On the VPS, pull the project repo, and create an Nginx Docker container serving the distribution folder
  • Use NPM as the reverse proxy for the container

Dummy Website

Before building the website, let's first deploy a dummy static website with NPM using an Nginx container with a volume bound. First create a folder for the container

mkdir pi-www
cd pi-www

Quickly create a static site using plain Nginx image. The docker-compose.yaml file looks like:

networks:
  mynet:
    name: mynet
    external: true

services:
  piwww:
    restart: unless-stopped
    image: nginx:1-alpine
    expose:
      - 80
    # volumes:
    # - ./html/:/usr/share/nginx/html
    networks:
      - mynet

We are going to change the volumes config later.

Now add a proxy host in NPM:

  • the destination is piwww at port 80
  • for now no asset caching

See if your site is up and running:

Local Development

Install Hugo

On local machine, install Hugo. According to Installation, I have many choices. I just download the prebuilt binary for my OS (a mac) from Releases for simplicity. You need to adapt

mkdir ~/bin
cd ~/bin
wget https://github.com/gohugoio/.../hugo_extended_...tar.gz
tar zxvf hugo_extended_...tar.gz

# keep the hugo executable and remove other files
# on MacOS, locate hugo file using Finder and right click to open it once 
# add $HOME/bin to your PATH environment variable

You need to adapt the steps above accordingly, so that you can run the shell command successfully:

$ hugo version
hugo v0.136.5-...+extended darwin/amd64 BuildDate=2024-10-24T12:26:27Z VendorInfo=gohugoio

Pick a Theme

I look up the themes, click Landing, and pick the Up Business Theme:

cd ~/ws # the parent folder
hugo new site pointegrity
cd pointegrity
git init
git submodule add https://gitlab.com/writeonlyhugo/up-business-theme.git themes/up-business-theme
rm hugo.toml
cp themes/up-business-theme/hugoBasicExample/config.yaml .
cp -a themes/up-business-theme/hugoBasicExample/content/* content/
cp -a themes/up-business-theme/hugoBasicExample/data/* data/

To run the local server and view the demo site, run hugo server:

$ hugo server
...
ERROR deprecated: .Site.GoogleAnalytics was deprecated in Hugo v0.120.0 and will be removed in Hugo 0.137.0. Use .Site.Config.Services.GoogleAnalytics.ID instead.
WARN  deprecated: resources.ToCSS was deprecated in Hugo v0.128.0 and will be removed in a future release. Use css.Sass instead.
ERROR The "twitter_simple" shortcode requires two named parameters: user and id...

So searching the web and find some quick fixes

  • in themes/up-business-theme/layouts/partials/head/_seo.html, change the line if .Site.GoogleAnalytics to if .Site.Config.Services.GoogleAnalytics
  • in themes/up-business-theme/layouts/partials/head/_resources.html change resources.ToCSS to css.Sass
  • in content/post/rich-content.md remove the Twitter shortcode

Now I can run the server and visit the site http://localhost:1313:

Let me change some words quickly and deploy it first. I'll come back to change the content later.

  • Change images in themes/up-business-theme/assets/images
  • Change menus.main in config.yml
  • Change content files in content folder
  • Copy the file in themes/up-business-theme/layouts/index.html to ./layouts and update it.

When everything looks ok, I then try to commit the repo locally. Because there are submodules involved, for simplicity, I remove the file .gitmodules and the folder themes/up-business-theme/.git all together and make the whole project a single repo.

cd ~/ws/pointegrity
hugo build
git add .
git commit -m "init pointegrity"
Make sure public folder is also included

Deployment

To deploy the website:

  • Create the repo (in GitHub or others) and sync with local repo
  • On the VPS, clone or pull the repo as pointegrity inside pi-www mentioned above. I have made some experiments using bare git ssh server without using GitHub below.
  • Uncomment the volume entry in the docker-compose.yaml
...
services:
  piwww:
    ...
    expose:
      - 80
    volumes:
      - ./pointegrity/pupblic/:/usr/share/nginx/html
    networks:
      - mynet

TLDR

I also want to use this as an example to explore common options out there. Note that I am not going for a full survey here, as the alternatives are too many, and the factors to considers are highly subjective.

Since I only need a static website, manual content authoring in HTML or markdown is fine, and I have a VPS and a domain name. For contents I can:

  • Hand write HTML files, and use some CSS library and corresponding theme, because styling is not what I am good at.
  • Use a static website generator and an accompanying landing page theme.

In all cases the site will be kept as a git repo. The site can be tested locally. Because of the tooling needed, there would be a "distribution" folder generated, which can also be a git repo itself or as part of the parent repo.

To deploy the web site, I can

  • Use GitHub Page, using the repo of the distribution folder plus files required from GitHub Page
  • On the VPS, pull the whole repo or only the distribution folder, and
    • Use Nginx to serve the folder
    • Use an Nginx container, behind NPM, to host the folder

I choose to make the distribution folder part of the larger repo because:

  • This is a simple site, and Hugo is just an executable requiring minimum resources. If a large tool chain is needed on the VPS this is not desirable.
  • If needed, e.g. away from the local environment, I can log in into the VPS and modify the generated pages directly or just update and rebuild the project.

Git Server via SSH

It is straightforward to create a git repo on GitHub for this website. To experiment on the concept of controlling own data, in this case I will try to use the core capability already offered by git itself. Later I can decide to use GitHub or self-hosted git server as the central place to keep my works.

First, I search the web for "ssh server", then visit the page Setting Up the Server. For simplicity, I also use the VPS as the host for the git repo:

$ sudo adduser git
$ su git
$ cd
$ mkdir .ssh && chmod 700 .ssh
$ touch .ssh/authorized_keys && chmod 600 .ssh/authorized_keys

On my machine I have my ssh public ready (~/.ssh/id_rsa.pub), so I append the content to the file .ssh/authorized_keys there

$ cat >> ~/.ssh/authorized_keys

Make sure I can login from my local machine as well as on the VPS itself

# from my local machine
$ ssh the-vps -l git

On the VPS, I need to do the same for the login account:

$ ssh-keygen
Generating public/private ed25519 key pair.
Enter file in which to save the key (.../.ssh/id_...): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in .../.ssh/id_...
Your public key has been saved in .../.ssh/id_ed25519.pub

then append the generated public key content to the same authorized_keys file. Then I can log in to the git server via ssh too:

ssh git@localhost

When it is ok, I follow the steps but create the folder /srv/git as root first:

# on the VPS
$ sudo mkdir /srv/git
$ sudo chown git:git /srv/git

Then log in VPS as git and continue the steps:

# on the VPS as git
$ cd /srv/git
$ mkdir pointegrity.git
$ cd pointegrity.git
$ git init --bare -b main
Initialized empty Git repository in /srv/git/pointegrity.git/

To see if I can clone the (empty) repo on the VPS:

# on the VPS, user account (not git)
# suppose ~/ws this the parent folder
$ mkdir ~/ws/pi-www
$ cd ~/ws/pi-www

# use ssh://git@localhost:<port>/... for non 22 port instead
$ git clone git@localhost/srv/git/pointegrity.git
Cloning into 'pointegrity'...
warning: You appear to have cloned an empty repository.

It seems ok, then on my local machine:

$ cd ~/ws/pointegrity
$ git status
On branch main
nothing to commit, working tree clean
$ git remote add origin git@<the-vps>:/srv/git/pointegrity.git
$ git remote -v
origin	.../srv/git/pointegrity.git (fetch)
origin	.../srv/git/pointegrity.git (push)

On VPS, I can pull the repo from the git server now. To make it easy, remove the previous repo and clone again

$ cd ~/ws/pi-www
$ rm -rf pointegrity
$ git clone git@localhost/srv/git/pointegrity.git
Cloning into 'pointegrity'...
remote: Enumerating objects: 708, done.
...
Receiving objects: 100% (708/708), 2.82 MiB | 6.15 MiB/s, done.
Resolving deltas: 100% (145/145), done.

Now the distribution folder should be there at public.

Docker Compose

The docker-compose.yaml file has something similar to:

networks:
  mynet:
    name: mynet
    external: true

services:
  pointegrity:
    restart: unless-stopped
    image: nginx:1-alpine
    expose:
      - 80
    volumes:
    - ./pointegrity/public/:/usr/share/nginx/html
    networks:
      - mynet

The Initial Landing Page

I will have to update the site and change the images later.