This is part 2 of our JAMstack series. Make sure you've read part 1 so you can follow along!
Now that a Gitpod development environment is in place, let's set up the groundwork for the M part in JAMstack - a markdown oriented static site. This site will host all our user-accessible static content and our dynamic front-end pieces as they are implemented.
Environment Setup
We will be utilizing Hugo for our static site generation. Therefore, a large part of this tutorial will be based on Alejandro's excellent article on deploying a Hugo site, but leveraging the Gitpod environment for development and deployment.
First, ensure your Gitpod environment is set up and has access to Civo:
civo k3s list #Ensure no error is reported back
Let's set that up in our Gitpod environment as we are using Hugo. Your Gitpod environment has access to Homebrew so we will use that. Although there are several ways to install in a Gitpod environment, I prefer to embed software that will be used regularly into a custom Docker image for my environment. Create a .gitpod.Dockerfile
, and add the following:
FROM quay.io/ssmiller25/gitpod-k8s:latest
# Install Hugo
RUN brew install hugo
Edit your .gitpod.yml
configuration, and change the image
link to match below. (the rest of the file was set up in the first article)
image:
file: .gitpod.Dockerfile
tasks:
- name: Login to Cloud Resources
command: |
bash $HOME/scripts/00-cloudinit.sh
vscode:
extensions:
- ms-azuretools.vscode-docker
- ms-kubernetes-tools.vscode-kubernetes-tools
Save and commit all your changes. Then relaunch Gitpod for your repository. The first time you open will take a while (several minutes)! Once the new container is built, the launch time should be drastically reduced. Once up, let's verify we have Hugo installed. Run this from the terminal in your Gitpod instance
hugo version
If that returns a version number, we are good.
Initial Site Development
Let's use Hugo to set up an initial site:
hugo new site jamstacksite -f yml
A new jamstackapp
directory will be created in your repo, with the standard layout for a Hugo site. We will use the PaperMod theme to get started, but most others should work.
git submodule add --depth=1 https://github.com/adityatelange/hugo-PaperMod.git jamstacksite/themes/papermod
Update jamstacksite/config.yml
to match the following:
baseURL: http://example.org/
languageCode: en-us
title: "My JamStack Site"
theme: "papermod"
Now let's make sure we have a functional site. Run the following commands in the Gitpod terminal:
cd jamstacksite/
hugo serve
Once Hugo begins serving, Gitpod will detect the newly open port and give you a chance to preview the site.
Click the "Open Browser", and a new window should appear with the website as it is now:
Press Ctrl + C
to exit the Hugo session when finished.
If everything looks good, let's tell Hugo to build the site:
hugo
Hosting on Civo
Ok, now let's leverage Gitpod to push a docker container to Civo. In production, you would usually embed this into a pipeline as described in Alejandro's article, but we'll leave this as a manual deployment as we are developing our new app. First, let's create a new Civo cluster. From the Gitpod command interface:
cd ${GITPOD_REPO_ROOT}
civo k3s create jamstacksite -n 2 --wait
civo k3s config jamstacksite --save --merge
kubectl config use-context jamstacksite
kubectl get nodes #Ensure we see nodes from the new cluster
Create a Dockerfile
in the root of your repository:
FROM nginx
COPY ./jamstacksite/public /usr/share/nginx/html
Create a k8s.yaml
to deploy the site. Make sure to change the ssmiller25
to your username
apiVersion: apps/v1
kind: Deployment
metadata:
name: jamstackapp
spec:
replicas: 3
selector:
matchLabels:
app: jamstackapp
template:
metadata:
labels:
app: jamstackapp
spec:
containers:
- image: ssmiller25/jamstackapp:latest
name: jamstackapp
imagePullPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
name: jamstackapp
labels:
app: jamstackapp
spec:
ports:
- name: "http"
port: 80
selector:
app: jamstackapp
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: jamstackapp-ingress
labels:
app: jamstackapp
annotations:
kubernetes.io/ingress.class: traefik
spec:
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: jamstackapp
port:
number: 80
# Not required, but useful if serving multiple hostnames through the same ingress
#host: CLUSTER_ID.k8s.civo.com
How? Let's build and push our docker container. Make sure to substitute ssmiller25
with your Dockerhub username:
docker buildx build --push -t ssmiller25/jamstackapp:latest .
Deploy the kubernetes manifests
kubectl apply -f k8s.yaml
Now let's check out the site. First, find out the public IP of your cluster by running civo k3s show jamstacksite
and look for the "DNS A record". Go to that address, and you should see the site you previewed on your Gitpod environment!
Conclusion
We now have a static site hosted on Civo: The M In our JAMStack. With this basis, we can begin exploring implementing more dynamic content leveraging Javascript and APIs - both externally and internally.