Posted by James Ward, Developer Advocate
Recently I completed the migration of my blog from Wordpress to Hugo and I wanted to take advantage of it now being a static site by hosting it on a Content Delivery Network (CDN). With Hugo the source content is plain files instead of rows in a database. In the case of my blog those files are in git on GitHub. But when the source files change, the site needs to be regenerated and redeployed to the CDN. Also, sometimes it is nice to have drafts available for review. I setup a continuous delivery pipeline which deploys changes to my prod site on Firebase Hosting and drafts on Cloud Run, using Cloud Build. Read on for instructions for how to set all this up.
If you have an existing Hugo project you'll need to add some files to it:
.firebaserc
{ "projects": { "production": "hello-hugo" } }
cloudbuild-draft.yaml
steps: - name: 'gcr.io/cloud-builders/git' entrypoint: '/bin/sh' args: - '-c' - | # Get the theme git submodule THEME_URL=$(git config -f .gitmodules --get-regexp '^submodule\..*\.url$' | awk '{ print $2 }') THEME_DIR=$(git config -f .gitmodules --get-regexp '^submodule\..*\.path$' | awk '{ print $2 }') rm -rf themes git clone $$THEME_URL $$THEME_DIR - name: 'gcr.io/cloud-builders/docker' entrypoint: '/bin/sh' args: - '-c' - | docker build -t gcr.io/$PROJECT_ID/$REPO_NAME-$BRANCH_NAME:$COMMIT_SHA -f - . << EOF FROM klakegg/hugo:latest WORKDIR /workspace COPY . /workspace ENTRYPOINT hugo -D -p \$$PORT --bind \$$HUGO_BIND --renderToDisk --disableLiveReload --watch=false serve EOF docker push gcr.io/$PROJECT_ID/$REPO_NAME-$BRANCH_NAME:$COMMIT_SHA - name: 'gcr.io/cloud-builders/gcloud' args: - run - deploy - --image=gcr.io/$PROJECT_ID/$REPO_NAME-$BRANCH_NAME:$COMMIT_SHA - --platform=managed - --project=$PROJECT_ID - --region=us-central1 - --memory=512Mi - --allow-unauthenticated - $REPO_NAME-$BRANCH_NAME
cloudbuild.yaml
steps: - name: 'gcr.io/cloud-builders/git' entrypoint: '/bin/sh' args: - '-c' - | # Get the theme git submodule THEME_URL=$(git config -f .gitmodules --get-regexp '^submodule\..*\.url$' | awk '{ print $2 }') THEME_DIR=$(git config -f .gitmodules --get-regexp '^submodule\..*\.path$' | awk '{ print $2 }') rm -rf themes git clone $$THEME_URL $$THEME_DIR - name: 'gcr.io/cloud-builders/curl' entrypoint: '/bin/sh' args: - '-c' - | curl -sL https://github.com/gohugoio/hugo/releases/download/v0.69.2/hugo_0.69.2_Linux-64bit.tar.gz | tar -zxv ./hugo - name: 'gcr.io/cloud-builders/wget' entrypoint: '/bin/sh' args: - '-c' - | # Get firebase CLI wget -O firebase https://firebase.tools/bin/linux/latest chmod +x firebase # Deploy site ./firebase deploy --project=$PROJECT_ID --only=hosting
firebase.json
{ "hosting": { "public": "public" } }
^master$
branch:
drafts-trigger
, specify the branch selector as
.*
(i.e. any branch), and the build configuration file type to "Cloud
Build configuration file" with a value of cloudbuild-draft.yaml
@cloudbuild.gserviceaccount.com
, and select the "pencil" / edit
button:
Now you'll need your project id, which can be found in the URL on the Firebase Project Overview page. The URL for my project is:
console.firebase.google.com/project/jw-demo/overview
Which means my project id is: jw-demo
Now copy your project id go into your GitHub fork, select the
.firebaserc
file and click the "pencil" / edit button:
Replace the hello-hugo
string with your project id and commit the
changes. This commit will trigger two new builds, one for the production site and one for the
drafts site on Cloud Run. You can check the status of those builds on the Cloud Build History
page. Once the default trigger (the one for Firebase hosting) finishes, check out
your Hugo site running on Firebase Hosting by navigating to (replacing YOUR_PROJECT_ID with
the project id you used above): https://YOUR_PROJECT_ID.web.app/
Your prod and drafts sites are now automatically deploying on new commits!
There are many themes for Hugo and they
are easy to change. Typically themes are pulled into Hugo sites using git submodules. To
change the theme, edit your .gitmodules
file and set the
subdirectories and url. As an example, here is the content when using the mainroad theme:
[submodule "themes/mainroad"] path = themes/mainroad url = https://github.com/vimux/mainroad.git
You will also need to change the theme
value in your
config.toml
file to match the directory name in the
themes
directory. For example:
theme = "mainroad"
Note: At the time of writing this, Cloud Build does not clone git submodules so the
cloudbuild.yaml
does the
cloning instead.
To setup local editing you will first need to clone your fork. You can do this with the GitHub desktop app. Or from the command line:
git clone --recurse-submodules https://github.com/USER/REPO.git
Once you have the files locally, install Hugo, and from inside the repo's directory, run:
hugo -D serve
This will serve the drafts in the site. You can check out the site at: localhost:1313
Committing non-draft changes to master and pushing those changes to GitHub will kick off the build which will deploy them on your prod site. Committing draft to any branch will kick off the build which will deploy them on a Cloud Run site.
Hopefully that all helps you with hosting your Hugo sites! Let me know if you run into any problems.