Skip to content

BOOTSTRAP A PORTFOLIO WEBSITE

Overview

The goal of this lab is to build a website which will be used as professional portfolio.

We just have a few requirements:

  • Easy to update and maintain, nothing fancy -- a static generator will do
  • Free hosting
  • A custom domain name

Gitlab Pages fits our 2 last requirements and we'll use Mkdocs for the first one.

Pre-requisites:

  • A Unix environment (any recent Linux or macOS will do) with Git 2+, GNU Make 3.81+ and Python 3+ installed (required for Mkdocs); we'll use Unix commands and GNU Make which won't work in a Windows environment;
  • A Gitlab account
  • A domain name

Flesh-out Repository

Create a new directory named portfolio and initialize it as a Git repository:

mkdir portfolio
cd portfolio
git init --initial-branch main

As a personal repository layout preference, I like to create the usual src subtree and one subtree per tech used, for easy discoverability and maintenance, in our case here, mkdocs:

mkdir -p src/mkdocs

The files expected by Mkdocs are detailed here but as a quick summary:

  • First a configuration file, named mkdocs.yml
  • And a subtree docs containing the website index file, index.md

Craft the expected files with your favorite code editor:

src/mkdocs/mkdocs.yml:

---
site_name: My Portfolio
nav:
  - index.md
theme:
  name: mkdocs
  color_mode: auto
  user_color_mode_toggle: true
  locale: en

src/mkdocs/docs/index.md, any content will do here for now:

# Portfolio

To be completed.

Build Locally

We can now focus on the build manifest, using GNU Make as build tool.

Craft the Makefile with your favorite code editor:

#
# PUBLIC CONFIGURATION
#

PYTHON3 ?= python3
BUILD_DIR_PATH ?= _build

#
# PRIVATE IMPLEMENTATION
#

MKDOCS_FLAGS := --config-file src/mkdocs/mkdocs.yml --strict
YAMLLINT_FLAGS := --strict

VENV_DIR_PATH := $(BUILD_DIR_PATH)/venv
MKDOCS_SITE_DIR_PATH := $(abspath $(BUILD_DIR_PATH))/site

PIP := $(VENV_DIR_PATH)/bin/pip
MKDOCS := $(VENV_DIR_PATH)/bin/mkdocs
YAMLLINT := $(VENV_DIR_PATH)/bin/yamllint

.PHONY: setup
setup:
    echo "$(BUILD_DIR_PATH)" > .gitignore
    echo "_*" >> .gitignore
    $(PYTHON3) -m venv $(VENV_DIR_PATH)
    PIP_CONFIG_FILE=/dev/null $(PIP) --disable-pip-version-check install --upgrade pip
    $(PIP) install yamllint mkdocs-material

.PHONY: validate
validate: setup
    $(YAMLLINT) $(YAMLLINT_FLAGS) $(shell find src/ -name *.yml)

.PHONY: serve
serve: validate
    $(MKDOCS) serve $(MKDOCS_FLAGS)

.PHONY: build
build: validate
    $(MKDOCS) build $(MKDOCS_FLAGS) --site-dir $(MKDOCS_SITE_DIR_PATH)

.PHONY: clean
clean:
    -rm -rf $(BUILD_DIR_PATH)

Notice both PYTHON3 and BUILD_DIR_PATH can be overriden on invocation.

Now, you can run make serve and open http://127.0.0.1:8000 to browse the website locally.

Press ctrl-c to interrupt and get back your prompt.

Do a build with make build, this generates the site content in BUILD_DIR_PATH.

Setup Gitlab Project

First, create the Gitlab project;

  • Open https://gitlab.com and log in
  • Click on New Project > Create blank project
    • Project name: portfolio
    • Project URL: select a username or an existing group as you see fit
    • Project slug: autocompleted from project name
    • Project deployment target: Gitlab Pages
    • Visibility Level: Private for now
    • Untick "Initialize repository with a README"

Then add this project as remote of your local repository:

# HEADS UP: this prompts you for PROJECT_URL, we use echo+read to support both bash and zsh.
echo "Input your Gitlab project URL"
read PROJECT_URL
git remote add origin "git@gitlab.com:$PROJECT_URL/portfolio.git"
git add .
git commit -m "Initial commit"
git push --set-upstream origin main

Build on Gitlab CI/CD & Publish

Next step, the pipeline definition.

Craft the src/gitlab-ci/gitlab-ci.yml file with your favorite code editor:

---

stages:
  - build

build:
  stage: build
  image: debian:latest
  variables:
    BUILD_DIR_PATH: _build
  script:
    - apt update -y
    - apt install -y make python3-venv
    - make build
  # this generates a "deploy" job
  pages:
    publish: ${BUILD_DIR_PATH}/site

In the Gitlab CI project settings, set src/gitlab-ci/gitlab-ci.yml as CI/CD configuration file.

On committing and pushing this changes, the pipeline is triggered and the site is published at a gitlab endpoint (which you can find in the left hand sidebar Deploy > Pages, or right hand sidebar with the direct link Gitlab Pages.)

Configure Custom Domain name

Final step.

Ref: https://docs.gitlab.com/user/project/pages/custom_domains_ssl_tls_certification/

In Deploy > Pages, click on Domain & Settings > Add Domain;

Fill-in the domain name, then "Create new domain"

You'll land on a new gitlab page indicating details for both an ALIAS and a TXT record, read along.

On your registrar DNS configuration page, create a TXT record with the validation value given on the aforementioned page. On the Gitlab page, click on Validate to verify.

Also create a DNS record:

  • An ALIAS if it's a subdomain (given on the aforementioned gitlab page)
  • Or both a A and AAAA record if you're using a TLD, in which case, use the IPs referenced here

You can test by pointing your browser to your configured domain name.