Current Problem
I have been using various free hosting providers such as x10hosting with self-hosted Wordpress blog in the last few years. I encountered various problems such as,
- poor site performance if you are using free hosting plans.
- creating a self-hosted WordPress site needs to be configured with many sets of credentials including the hosting provider, cPanel, the WordPress admin portal itself and the mysql database for WordPress. All these loops expose security vulnerabilities one way or the other.
- difficult to backup content.
- having a CMS to serve dynamic Wordpress content is an overkill for mostly static blog content. The slower response doesn’t payoff in my use case.
All these add up to unnecessary complexity and wasted time. Time that can be spent on higher ROI work such as creating quality content and picking up new skills.
Project Objective
I want to minimize my effort to just writing, without any add-on time for html/css/javascript development plus maintaining a database.
I’d also prefer the solution to be free with reasonable usage quota.
Employing fewer tools and taking a lightweight approach to simplify my workflow is also important.
My Solution
In the last 2 years, many cloud service providers (e.g., Github Pages, Microsoft Azure Static Web App, Google Firebase Hosting and Cloudflare Pages) start to roll out free plans to host static web apps. Combining with the use of site generators such as Hugo and Jekyll, this seems to be a very simple and attractive value proposition, as
- your sole focus remains in writing the actual content (in markup), whereas the site generator tool will generate the corresponding html/css for you.
- you can apply themes easily to customize your site.
- no database administration is involved.
- you can push your site content to github with automated deployment to your choice of hosting provider.
I decided to take Hugo for a spin as it seems to be a very popular generator based on the volume of tutorials available. The themes available aren’t too shabby either. I will then host the static files generated by Hugo in either Firebase or Azure.
Prerequisites
- Git for source control
- A Github account
- Hugo installation
- A Google account, used to create and configure Firebase projects
- A Microsoft account, used to create an Azure subscription
- basic knowledge of the Markdown language (used to author content)
Generate site content with Hugo
Regardless of where you want to host your site, first you need to generate some content. Let’s get started!
Create a new Github repository called
myblog
Follow Hugo’s simple quick start guide to create your first site called
myblog
.>cd c:\hugo\sites >hugo new site myblog -f yml >cd \myblog >git init >git branch -M main
Apply a theme to your blog. I am using the PaperMod theme.
>git submodule add --depth=1 https://github.com/adityatelange/hugo-PaperMod.git themes/PaperMod
Edit
config.yml
to addtheme: "PaperMod"
at the end so you specify this theme to be used.Create your first post by executing
>hugo new posts/firstpost.md
Examine this first post created under the
content/posts
folder.--- title: "1stpost" date: 2022-05-15T18:19:39-07:00 draft: true ---
Add a line at the end
This is my first blog post!
Now launch the local web server provided by Hugo. By default, draft posts (such as the one we just created, with
draft
set totrue
) are not built. To override it, add the-D
flag to include our draft.>hugo server -D
Navigate to
http://localhost:1313/
to view your site.Now edit
firstpost.md
to changedraft
tofalse
, and save it. Notice that the local web server will immediately rebuild the content to reflect the change!We are now ready to use Hugo to generate our static site content. After it completes, you can examine the newly created public folder that hosts all our assets, ready to be deployed.
>hugo
Commit and push our files to our Github repository.
>git add -A >git commit -m "initial commit" >git remote add origin https://github.com/<YOUR_USER_NAME>/myblog >git push --set-upstream origin main
Deploy to public hosting provider
Github Pages’s free plan requires your content to be stored in a public repository which I don’t like. So I use a private Github repository, and let other hosting providers pull from there.
Next I will try out both Firebase and Azure. They both provide free plans with free SSL, CDN, custom domain support, quick CLI, staging preview, integration with Github workflow.
Deploy to Firebase Hosting
The following steps are adapted from the Hugo docs.
- Using your existing Google account, go to Firebase console to create a new project
- Install the Firebase CLI
- Launch the Firebase CLI and login to your Google account
> firebase login
- Navigate to your myblog folder and initialize Firebase
> cd c:\hugo\sites\myblog
> firebase init hosting
- When prompted,
- to associate this folder with a Firebase project, choose the new project you just created in the Firebase console
- accept
public
as your public directory - say
no
to configure as a single-page app - say
yes
to set up automatic builds and deploys with GitHub.
- It will then prompt you to authenticate with your Github account to upload your service account to a GitHub repository’s secrets store.
- When prompted to setup a workflow, enter the Github repository you created in step 2 of last section and accept default values for all remaining questions. When initialization is completed,
firebase.json
and.firebaserc
will be created to store configuration and project settings respectively. - You can now test your content with the Firebase emulator, which uses a local emulator for you to test your content, similar to the Hugo web server we tried previously.
> firebase emulators:start --only hosting
- After you’ve verified that everything works, deploy to Firebase.
> firebase deploy --only hosting
Verify at https://YOUR-APP-NAME.web.app
or https://YOUR-APP-NAME.firebaseapp.com
that the content is deployed properly.
Bonus
It’s clumsy to call hugo
to rebuild your static files every time you want to redeploy. To get around that, create a pre-deploy script by inserting this line to your firebase.json
file inside the hosting
block
"predeploy": "hugo",
This will be the first step to execute whenever you call firebase to deploy your site.
Deploy to Azure Static Web App
Deploying to Azure is done via the Azure portal, or if you have Visual Studio Code installed, via it’s SWA Extension.
The process is brisk. If you are starting from scratch, you do not need to call hugo
to generate all the static files before deployment, as Azure will take care of that when you choose Hugo as the build preset during the static web app creation.
You can also keep editing your local files and pushing to your Github repo and the Actions workflow created by Azure during app creation will take care of continuous deployment.
Conclusion
I’m quite happy to find out that other than a few config customizations, I can actually spend more time writing. I also enjoy the seamless experience of using Visual Studio Code editor to author in markdown, its terminal pane to build/stage hugo files, the SWA extension to configure Azure Static Web App). The only time I need to branch out from VS Code is to use the Firebase CLI, which itself is quite simple and self-explanatory. Fewer opened windows to toggle, better focus!
This blog is currently hosted in Firebase for the following reasons.
Firebase hosting
Pros
- you can customize the sub-domain as long as it is unique. You are also given two options for your site URL, one long and one short.
- a very lenient 10Gb storage
- easy integration with Google Analytics (just enable it during initial deployment, or via website dashboard). No need to install plug-in or edit html directly
- you can have multiple apps/sites in the same project sharing common assets
Cons
As there is no default continuous deployment from Github, you need to explicitly invoke Hugo to generate the site files (html and supporting assets) before firebase can redeploy. If you don’t like this, you need to manually setup a Github Actions workflow.
Azure Static Web App
Pros
If you specify the site generator you use during static app resource creation, Azure creates a Github Actions workflow to take care of continuous deployment, which automates building HTML assets and deployment whenever there is a push or pull request in your Github repository. Unlike Firebase hosting, you don’t need to run hugo to regenerate the public files and do a push/deploy via its CLI.
Cons
- Azure picks a randomized subdomain which looks very silly, so you need to factor in the cost of buying acustom domain.
- 0.5Gb storage included with the free plan is much more limited that what Firebase offers.
Next step
Implementing CD
As Firebase deployment is manual for me at this stage, I will continue to test out customizing continuous deployment with Github Actions for Firebase.
Staging content
I will also try out the preview channel from Firebase as well as the staging preview from Azure.
Customizing my Hugo site
I’ll try out swapping themes and customization and compare its usability with other generators (Jekyll and Astro come to mind). Will probably add commenting feature for better interaction too.
Integrating Firebase CLI with VS Code
one less jump outside, saying goodbye to distraction!
edited on 6/23/2022: I wrote a new post covered this topic.
Stay tuned!