Creating a Blog/Website with Docker, Hexo & Github, Free Hosting and HTTPS

Blogging away ...

Updated for 2020. People often like to start a new year or even a new decade with a venture, blogging being particularly popular. I’ve updated this article originally written in 2019.

The supporting container image used in this tutorial has been refactored and improved to handle persistency. Deployment keys are part of the build process and the context has been simplified. I hope you enjoy and find success in your goals :)

TL;DR…

This is a tutorial on creating a blog or website using hexo.io (a static site generator), Docker and Github with your own custom domain and https, for the cost of your domain name only and a little bit of time.

Introduction

I wanted a convenient way of running sites, i.e. blogs and supporting sites for my projects, without a hosting service or server infrastructure like Wordpress, I also, wanted to keep this as cost effective as possible with free being an ideal.

After comparing a multitude of offerings, I settled on the excellent hexo.io platform, ‘A fast, simple & powerful blog framework’. The great thing about hexo, is that your blog/site is generated as a collection of static files. You don’t need anything other than a decent web server to host your page and given that it’s a static site, it reduces security concerns significantly in comparison to other popular blogging platforms.

With the use of hexo, you’ve also got a means that you can work on your blog locally, without internet connectivity. If you’re like me and commute a lot, especially where there is intermittent wifi connectivity (London Underground), then this is particularly useful.

The platform is built with node.js and subsequently, there are for it’s configuration, a variety of modules that need to be installed through npm. Whilst this is not that difficult in itself, it is a process that can result in a lot of installation residual on ones system. For this reason, we’re going to be using Docker to encapsulate the main blogging component that will run our system, keeping our own system shipshape and shiny.

Github, offers a great solution for hosting sites with it’s pages.github.io service, all you need to have is a github account to make use of this. You can even, configure the service to leverage your own domain name, with Github taking care of aspects like https for you for free.

Prerequisites

You will need to have the following -

  • Docker installation. Docker is available for Mac/Windows/Linux and is easily installed
  • Domain Name (optional). I will be using a domain name for my configuration. If you wish to follow along fully, you’ll need a domain name but, you can just as easily stick with the free subdomain provided by Github pages, i.e. name.github.io, and skip the domain name related aspects in this tutorial. If you don’t have a domain name but wish to purchase one, name.com is an excellent provider and fits in well with this tutorial
  • Github account, sign up for free on github.com

Overview

In the subsequent sections, we will be covering the complete setup of https://masteringansible.com, a domain I will be using to support my online course on Mastering Ansible

Docker Pull the spurin/hexo Image

On Docker Hub there is a pre-made image made by myself, containing the steps to install both Hexo and Hexo-Admin. More details about the image can be reviewed here. With docker installed, from a command prompt/terminal, issue the following command to pull the latest version of the image -

$ docker pull spurin/hexo
Using default tag: latest
latest: Pulling from spurin/hexo
804555ee0376: Pull complete
2706bdf80250: Pull complete
3a1861ab5a61: Pull complete
2a2939395b29: Pull complete
738ba111f3fd: Pull complete
c32fd6850012: Pull complete
d4c7abfc1ea7: Pull complete
Digest: sha256:68df85373fa46d314b0fe1b8b278f8dc158342c711163b47fb4be780441b6fc6
Status: Downloaded newer image for spurin/hexo:latest
docker.io/spurin/hexo:latest

Create a container for your site

As we may have multiple sites, I like to give the running container a name that references the site that it relates too, so that I can easily see the container I wish to interact with.

I also like to store the Docker volume that will relate to this, on Dropbox, so that I have a backup of my running configuration as most of my efforts in this space are performed on my personal laptop.

The following example, assumes a domain name of masteringansible.com, with the local hexo server, running on port 4000. The -v ‘/Users/james/Dropbox/James/Application\ Folders/docker/volumes/masteringansible.com’ is the path to where I will store the running configuration for the container.

This command, creates a container for us using the customised spurin/hexo image as a base -

$ docker create --name=hexo-masteringansible.com \
-e HEXO_SERVER_PORT=4001 \
-e GIT_USER="James Spurin" \
-e GIT_EMAIL="james@abcdef.com" \
-v /Users/james/Dropbox/James/Application\ Folders/docker/volumes/masteringansible.com:/app \
-p 4001:4001 \
spurin/hexo

We can start the container and follow the logs. When this runs for the first time, if a site does not exist in the target folder, one will be created (can take a while). Subsequently, hexo-admin will be installed inside the site. It will also create SSH keys for deployment, setup both github and gitlab as known_hosts and perform a gitconfig for your username and email -

$ docker start hexo-masteringansible.com && docker logs --follow hexo-masteringansible.com
hexo-masteringansible.com
***** App directory is empty, initialising with hexo and hexo-admin *****
INFO Cloning hexo-starter https://github.com/hexojs/hexo-starter.git
Cloning into '/app'...
Submodule 'themes/landscape' (https://github.com/hexojs/hexo-theme-landscape.git) registered for path 'themes/landscape'
Cloning into '/app/themes/landscape'...
Submodule path 'themes/landscape': checked out '73a23c51f8487cfcd7c6deec96ccc7543960d350'
INFO Install dependencies
yarn install v1.21.1
info No lockfile found.
[1/4] Resolving packages...
[2/4] Fetching packages...
<snip>
***** App directory contains no requirements.txt file, continuing *****
***** App .ssh directory is empty, initialising ssh key and configuring known_hosts for common git repositories (github/gitlab) *****
***** Running git config, user = James Spurin, email = james@abcdef.com *****
***** Copying .ssh from App directory and setting permissions *****
***** Contents of public ssh key (for deploy) - *****
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC2z5BbOk241XaNTALIlcHDF57WHQTvfA+NV8T7Puw5wk0hZExIWNZt0zfqD8m1XYWUYRlQbCx1wUMGRGOCHq5NtXlzQmCiDkBULXgoofC+/8trD0p8pwzCPW8BZ4/agRDIExdnaMD2Wqd8VCg/1/Y09QM3k5roiXPy7ES4ZCp5QHCbBJ1EXWjpgfn50o5pbq64Mgnw05lsAVbFjtSHm6Th+tN0IXbUvXO0znRvDTEJ15cG7uf9pI1rstCzydK0mqYDrOyqWYk/aroJpnoJGnbT0AKnVoo3c5IS4w1SSY33Ju6G82QMjFOrPqqQPM3dNBIQHb2crRN+VxKpLAjMojfr root@b3feb661344f
***** Starting server on port 4001 *****
INFO Start processing
INFO Hexo is running at http://localhost:4001 . Press Ctrl+C to stop.

We can press Ctrl+C at this point without concern as we’re following the logs, the container is running in the background and thus our Ctrl+C stops the following of the logs, not the actual container.

I’m performing this on my laptop so Docker is localhost, adjust the name/ip address accordingly if you’re running Docker elsewhere. If you browse to http://localhost:4001, you’ll be presented with a hexo starting page as follows -

Hexo with the Landscape theme

You can also, access the admin interface for hexo-admin at http://localhost:4001/admin -

Hexo-Admin

Customising the Theme

This theme may suit your needs but personally, I am a big fan of the Hueman theme. The next steps cover the installation of this particular theme.

Each theme will have their own requirements but this give an overall idea of the process.

Execute a bash shell in the running container, giving you a prompt similar to the following -

$ docker exec -it hexo-masteringansible.com bash
root@b3feb661344f:/app#

We will clone the theme from it’s source github repository, and whilst we’re in the shell, we’re going to rename the default configuration file to the expected name. Although we’re doing this in the shell, we’re in the app volume so all changes here are persistent. Technically, we could do this directly in the app volume on our local OS if that is more convenient -

root@b3feb661344f:/app# git clone https://github.com/ppoffice/hexo-theme-hueman.git themes/hueman
Cloning into 'themes/hueman'...
remote: Enumerating objects: 1831, done.
remote: Total 1831 (delta 0), reused 0 (delta 0), pack-reused 1831
Receiving objects: 100% (1831/1831), 5.55 MiB | 1.51 MiB/s, done.
Resolving deltas: 100% (935/935), done.
root@b3feb661344f:/app#

root@b3feb661344f:/app# mv themes/hueman/_config.yml.example themes/hueman/_config.yml
root@b3feb661344f:/app# exit

The next change, is to our blog configuration file which again, is now accessible in two ways

  1. In the container under /app/_config.yml
  2. Outside of the container in the local directory, in my case this would be /Users/james/Dropbox/James/Application\ Folders/docker/volumes/masteringansible.com/_config.yml

To reiterate, when we created the container, we specified the volume location so these files are accessible both inside the container (via an interactive shell) and outside of the container (via your filesystem). If you wish to make changes inside the container using an editor like vim, you will need to install an editor as the container is built from a lightweight image that has no default editors (i.e. apt update && apt -y install vim), n.b. this change is to the running container and won’t persist should the container be destroyed/recreated).

Change the following context in _config.yml to use hueman as the theme -

# Extensions
## Plugins: https://hexo.io/plugins/
## Themes: https://hexo.io/themes/
theme: hueman

It is also worth setting the language to en, if you’re using English, I noticed that without this, my configuration defaulted to Dutch -

# Site
title: Hexo
subtitle:
description:
keywords:
author: John Doe
language: en
timezone:

After making these change, if you’re in the running container, exit and then restart the Docker container -

$ docker restart hexo-masteringansible.com
hexo-masteringansible.com

Wait for the server to start, checking the logs if necessary and then, accessing http://localhost:4001, should now give you the site, with the hueman plugin enabled -

Hueman Theme

Personalising the Page

Where desired you can personalise the page. Pages/Posts can be added using the Admin interface and changes can be made to both _config.yml and themes/hueman/_config.yml for Hexo and the Hueman theme respectively.

We’re not going to cover this aspect in detail but should you wish to do so before continuing, now is a good time to try out the platform.

For my own site, masteringansible.com, I performed the following changes as a starter guide.

Updated _config.yml with the following -

# Site
title: MasteringAnsible.com
subtitle:
description: Official website for the Mastering Ansible online course
keywords: Mastering Ansible
author: James Spurin
language: en
timezone:

Changed the logo in themes/hueman/source/css/images and updated themes/hueman/_config.yml to reflect my social media settings and the new logo size -

# Customize
customize:
logo:
width: 340
height: 154
url: images/logo-header.png
theme_color: '#006bde'
highlight: androidstudio
sidebar: left # sidebar position, options: left, right
thumbnail: true # enable posts thumbnail, options: true, false
favicon: # path to favicon
social_links: # for more icons, please see http://fontawesome.io/icons/#brand
linkedin: https://uk.linkedin.com/in/jamesspurin
facebook: https://www.facebook.com/james.spurin
github: https://github.com/spurin
twitter: https://twitter.com/jamesspurin
medium: https://medium.com/@spurin

If you review further in the themes/hueman/_config.yml file, there is an entry that relates to insight search. I personally like this feature and it’s installation is pretty straight forward, the configuration makes reference to the following -

# Search
search:
insight: true # you need to install `hexo-generator-json-content` before using Insight Search
swiftype: # enter swiftype install key here
baidu: false # you need to disable other search engines to use Baidu search, options: true, false

For this, we’re going to need some additional npm requirements, fortunately, the image has been built to accomodate this. Execute a shell, and then add the requirement to requirements.txt in the app volume.

$ docker exec -it hexo-masteringansible.com bash
root@b3feb661344f:/app#

$ echo hexo-generator-json-content >> requirements.txt
$ exit

Restart the container, it should now, at execution, install any requirements as part of the startup process

$ docker restart hexo-masteringansible.com && docker logs --follow hexo-masteringansible.com
<snip>
***** App directory contains a requirements.txt file, installing npm requirements *****
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@2.1.2 (node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.1.2: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.11 (node_modules/nunjucks/node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.11: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.11 (node_modules/hexo-admin/node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.11: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})

+ hexo-generator-json-content@4.1.6
added 6 packages from 24 contributors, removed 1 package and audited 4834 packages in 88.184s

5 packages are looking for funding
run `npm fund` for details

found 17 vulnerabilities (4 low, 6 moderate, 6 high, 1 critical)
run `npm audit fix` to fix them, or `npm audit` for details
***** App .ssh directory exists and has content, continuing *****
<snip>

Using the admin page, I created initial posts, an about post and a purchase page .

The page, for me, now looks like the following -

Mastering Ansible Homepage

Using the SSH Deploy Key

We’re going to use SSH keys to deploy our site to Github, this is conveniently done as part of the application generation and we can use the SSH key generated, i.e.

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC2z5BbOk241XaNTALIlcHDF57WHQTvfA+NV8T7Puw5wk0hZExIWNZt0zfqD8m1XYWUYRlQbCx1wUMGRGOCHq5NtXlzQmCiDkBULXgoofC+/8trD0p8pwzCPW8BZ4/agRDIExdnaMD2Wqd8VCg/1/Y09QM3k5roiXPy7ES4ZCp5QHCbBJ1EXWjpgfn50o5pbq64Mgnw05lsAVbFjtSHm6Th+tN0IXbUvXO0znRvDTEJ15cG7uf9pI1rstCzydK0mqYDrOyqWYk/aroJpnoJGnbT0AKnVoo3c5IS4w1SSY33Ju6G82QMjFOrPqqQPM3dNBIQHb2crRN+VxKpLAjMojfr root@b3feb661344f

n.b. this is an example only and has not been used, outside of this tutorial, you willneed to use your own SSH key.

On Github, create a repository called something.github.io

In my case, I created masteringansible.github.io -

masteringansible.github.io

Using the Github GUI, I created a simple index.html with the word ‘test’ in it. This will easily allow you to verify that the site is working in its current form, i.e. https://masteringansible.github.io

Configuring a domain name using Github

If you wish to host your site with a custom domain, in the project settings in the github repository, you can enable as follows -

masteringansible.github.io settings

After doing this, you’re repository will consist of 2 files, the index.html previously created and a file called CNAME, this file is important and we need to factor this into our hexo configuration later. For now, the repository will look like the following -

masteringansible.github.io with index.html and CNAME

Adding the Deployment Keys to Github

Whilst in the repository, we can add the deployment keys that we created -

In Settings, choose Deploy Keys -

Deploy Keys on left hand side

Select Add deploy key

upload successful

And paste the key we created earlier

Deploy Key

If successful, you should see something similar to this -

Deployed Keys

Configuring the Domain ANAME

Most modern domain name sites provide the convenience of an ANAME in the DNS configurator.

Should you wish to know more about ANAME’s, see Andre Wallen’s blog entry

I’m using name.com for my domain and the entry is as follows.

name.com ANAME entry for masteringansible.com

Wait for DNS Propagation

DNS can take time to update, when it’s ready, you should be able to see the following using the dig command in Linux/Mac environments -

$ dig masteringansible.com

; <<>> DiG 9.9.7-P3 <<>> masteringansible.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 42137
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;masteringansible.com. IN A

;; ANSWER SECTION:
masteringansible.com. 300 IN A 185.199.109.153
masteringansible.com. 300 IN A 185.199.111.153
masteringansible.com. 300 IN A 185.199.108.153
masteringansible.com. 300 IN A 185.199.110.153

;; Query time: 19 msec
;; SERVER: 194.168.4.100#53(194.168.4.100)
;; WHEN: Sat Mar 09 18:03:42 GMT 2019
;; MSG SIZE rcvd: 113

Or, if you’re on a Windows host, the equivalent via the Google DNS Toolbox

Google DNS Toolbox

If you now browse to your domain with https://domain.com, you should be presented with the word ‘test’, n.b. it can take time for github to generate https certificates so if you encounter an issue here, check settings on your github repository.

Configure CNAME in Hexo and Deploy Settings

Earlier on, when we set a custom CNAME in Github, it created a file called CNAME in the repository, we need to ensure that this file is in our source on Hexo, otherwise, this will be removed during deployment, breaking the cname configuration for our site. Create an equivalent file in the source directory -

$ docker exec -it hexo-masteringansible.com bash
root@b3feb661344f:/app# echo masteringansible.com > source/CNAME
exit

Edit _config.yml and update the deployment section with your own github settings -

# Deployment
## Docs: https://hexo.io/docs/deployment.html
deploy:
type: git
repo: git@github.com:spurin/masteringansible.github.io.git
branch: master
message: "Site updated"

Generating content

In preparation for the launch of the site, we can request that Hexo generates the content for us

$ docker exec hexo-masteringansible.com hexo generate
INFO Start processing
INFO Files loaded in 1.87 s
INFO Generated: content.json
INFO Generated: index.html
INFO Generated: archives/index.html
INFO Generated: archives/2019/03/index.html
INFO Generated: archives/2019/index.html
INFO Generated: purchase/index.html
INFO Generated: categories/Purchase/index.html
INFO Generated: about/index.html
INFO Generated: 2019/03/09/Purchase/index.html
INFO Generated: 2019/03/09/About-Mastering-Ansible/index.html
INFO Generated: css/images/opacity-10.png
INFO Generated: css/images/logo-header.orig.png
INFO Generated: CNAME
INFO Generated: css/images/thumb-default-small.png
INFO Generated: css/images/thumb-default.png
INFO Generated: css/images/logo-header.png
INFO Generated: css/images/s-left.png
INFO Generated: libs/lightgallery/fonts/lg.eot
INFO Generated: libs/source-code-pro/fonts/mrl8jkM18OlOQN8JLgasD9V_2ngZ8dMf8fLgjYEouxg.woff2
INFO Generated: libs/lightgallery/css/lg-fb-comment-box.css.map
INFO Generated: libs/source-code-pro/fonts/mrl8jkM18OlOQN8JLgasDy2Q8seG17bfDXYR_jUsrzg.woff2
INFO Generated: libs/lightgallery/fonts/lg.svg
INFO Generated: libs/lightgallery/fonts/lg.ttf
INFO Generated: libs/lightgallery/img/loading.gif
INFO Generated: libs/lightgallery/img/video-play.png
INFO Generated: libs/lightgallery/css/lightgallery.css.map
INFO Generated: libs/lightgallery/img/vimeo-play.png
INFO Generated: libs/lightgallery/fonts/lg.woff
INFO Generated: libs/lightgallery/css/lg-transitions.css.map
INFO Generated: libs/titillium-web/fonts/anMUvcNT0H1YN4FII8wpr_SNRT0fZ5CX-AqRkMYgJJo.woff2
INFO Generated: libs/titillium-web/fonts/7XUFZ5tgS-tD6QamInJTcSo_WB_cotcEMUw1LsIE8mM.woff2
INFO Generated: libs/lightgallery/img/youtube-play.png
INFO Generated: libs/titillium-web/fonts/anMUvcNT0H1YN4FII8wpr46gJz9aNFrmnwBdd69aqzY.woff2
INFO Generated: libs/titillium-web/fonts/anMUvcNT0H1YN4FII8wpr9INifKjd1RJ3NxxEi9Cy2w.woff2
INFO Generated: libs/titillium-web/fonts/7XUFZ5tgS-tD6QamInJTcZSnX671uNZIV63UdXh3Mg0.woff2
INFO Generated: libs/titillium-web/fonts/anMUvcNT0H1YN4FII8wpr4-67659ICLY8bMrYhtePPA.woff2
INFO Generated: images/pasted-0.png
INFO Generated: js/main.js
INFO Generated: libs/justified-gallery/justifiedGallery.min.css
INFO Generated: libs/source-code-pro/styles.css
INFO Generated: libs/font-awesome/fonts/fontawesome-webfont.eot
INFO Generated: libs/font-awesome/fonts/FontAwesome.otf
INFO Generated: css/style.css
INFO Generated: libs/titillium-web/styles.css
INFO Generated: libs/font-awesome/fonts/fontawesome-webfont.woff2
INFO Generated: libs/font-awesome/fonts/fontawesome-webfont.woff
INFO Generated: libs/lightgallery/css/lg-fb-comment-box.css
INFO Generated: libs/lightgallery/js/lg-hash.min.js
INFO Generated: libs/lightgallery/js/lg-autoplay.min.js
INFO Generated: libs/lightgallery/css/lg-fb-comment-box.min.css
INFO Generated: libs/lightgallery/js/lg-autoplay.js
INFO Generated: libs/lightgallery/js/lg-fullscreen.min.js
INFO Generated: libs/lightgallery/js/lg-pager.js
INFO Generated: libs/lightgallery/js/lg-fullscreen.js
INFO Generated: libs/lightgallery/js/lg-hash.js
INFO Generated: libs/lightgallery/js/lg-share.min.js
INFO Generated: libs/lightgallery/js/lg-share.js
INFO Generated: libs/lightgallery/js/lg-pager.min.js
INFO Generated: libs/lightgallery/js/lg-video.min.js
INFO Generated: js/insight.js
INFO Generated: libs/font-awesome/fonts/fontawesome-webfont.ttf
INFO Generated: libs/lightgallery/js/lg-thumbnail.min.js
INFO Generated: libs/justified-gallery/jquery.justifiedGallery.min.js
INFO Generated: libs/lightgallery/js/lg-video.js
INFO Generated: libs/lightgallery/js/lg-zoom.min.js
INFO Generated: libs/lightgallery/js/lg-thumbnail.js
INFO Generated: libs/lightgallery/js/lg-zoom.js
INFO Generated: images/pasted-3.png
INFO Generated: images/pasted-4.png
INFO Generated: images/pasted-2.png
INFO Generated: libs/lightgallery/css/lightgallery.min.css
INFO Generated: libs/lightgallery/css/lightgallery.css
INFO Generated: libs/lightgallery/js/lightgallery.min.js
INFO Generated: libs/font-awesome/css/font-awesome.min.css
INFO Generated: libs/font-awesome/css/font-awesome.css
INFO Generated: libs/lightgallery/css/lg-transitions.min.css
INFO Generated: libs/lightgallery/css/lg-transitions.css
INFO Generated: libs/lightgallery/js/lightgallery.js
INFO Generated: libs/font-awesome/fonts/fontawesome-webfont.svg
INFO Generated: libs/jquery/3.3.1/jquery.min.js
INFO Generated: images/pasted-1.png
INFO 81 files generated in 3.13 s

Finally, Deploy the site

$ docker exec -it hexo-masteringansible.com hexo deploy
INFO Deploying: git
INFO Clearing .deploy_git folder...
INFO Copying files from public folder...
INFO Copying files from extend dirs...
[master (root-commit) 37b974f] Site updated: 2019-03-09 18:26:05
81 files changed, 15456 insertions(+)
create mode 100644 2019/03/09/About-Mastering-Ansible/index.html
create mode 100644 2019/03/09/Purchase/index.html
create mode 100644 about/index.html
create mode 100644 archives/2019/03/index.html
create mode 100644 archives/2019/index.html
create mode 100644 archives/index.html
create mode 100644 categories/Purchase/index.html
create mode 100644 content.json
create mode 100644 css/images/logo-header.orig.png
create mode 100644 css/images/logo-header.png
create mode 100644 css/images/opacity-10.png
create mode 100644 css/images/s-left.png
create mode 100644 css/images/thumb-default-small.png
create mode 100644 css/images/thumb-default.png
create mode 100644 css/style.css
create mode 100644 CNAME
create mode 100644 images/pasted-0.png
create mode 100644 images/pasted-1.png
create mode 100644 images/pasted-2.png
create mode 100644 images/pasted-3.png
create mode 100644 images/pasted-4.png
create mode 100644 index.html
create mode 100644 js/insight.js
create mode 100644 js/main.js
create mode 100644 libs/font-awesome/css/font-awesome.css
create mode 100644 libs/font-awesome/css/font-awesome.min.css
create mode 100644 libs/font-awesome/fonts/FontAwesome.otf
create mode 100644 libs/font-awesome/fonts/fontawesome-webfont.eot
create mode 100644 libs/font-awesome/fonts/fontawesome-webfont.svg
create mode 100644 libs/font-awesome/fonts/fontawesome-webfont.ttf
create mode 100644 libs/font-awesome/fonts/fontawesome-webfont.woff
create mode 100644 libs/font-awesome/fonts/fontawesome-webfont.woff2
create mode 100644 libs/jquery/3.3.1/jquery.min.js
create mode 100644 libs/justified-gallery/jquery.justifiedGallery.min.js
create mode 100644 libs/justified-gallery/justifiedGallery.min.css
create mode 100644 libs/lightgallery/css/lg-fb-comment-box.css
create mode 100644 libs/lightgallery/css/lg-fb-comment-box.css.map
create mode 100644 libs/lightgallery/css/lg-fb-comment-box.min.css
create mode 100644 libs/lightgallery/css/lg-transitions.css
create mode 100644 libs/lightgallery/css/lg-transitions.css.map
create mode 100644 libs/lightgallery/css/lg-transitions.min.css
create mode 100644 libs/lightgallery/css/lightgallery.css
create mode 100644 libs/lightgallery/css/lightgallery.css.map
create mode 100644 libs/lightgallery/css/lightgallery.min.css
create mode 100644 libs/lightgallery/fonts/lg.eot
create mode 100644 libs/lightgallery/fonts/lg.svg
create mode 100644 libs/lightgallery/fonts/lg.ttf
create mode 100644 libs/lightgallery/fonts/lg.woff
create mode 100644 libs/lightgallery/img/loading.gif
create mode 100644 libs/lightgallery/img/video-play.png
create mode 100644 libs/lightgallery/img/vimeo-play.png
create mode 100644 libs/lightgallery/img/youtube-play.png
create mode 100644 libs/lightgallery/js/lg-autoplay.js
create mode 100644 libs/lightgallery/js/lg-autoplay.min.js
create mode 100644 libs/lightgallery/js/lg-fullscreen.js
create mode 100644 libs/lightgallery/js/lg-fullscreen.min.js
create mode 100644 libs/lightgallery/js/lg-hash.js
create mode 100644 libs/lightgallery/js/lg-hash.min.js
create mode 100644 libs/lightgallery/js/lg-pager.js
create mode 100644 libs/lightgallery/js/lg-pager.min.js
create mode 100644 libs/lightgallery/js/lg-share.js
create mode 100644 libs/lightgallery/js/lg-share.min.js
create mode 100644 libs/lightgallery/js/lg-thumbnail.js
create mode 100644 libs/lightgallery/js/lg-thumbnail.min.js
create mode 100644 libs/lightgallery/js/lg-video.js
create mode 100644 libs/lightgallery/js/lg-video.min.js
create mode 100644 libs/lightgallery/js/lg-zoom.js
create mode 100644 libs/lightgallery/js/lg-zoom.min.js
create mode 100644 libs/lightgallery/js/lightgallery.js
create mode 100644 libs/lightgallery/js/lightgallery.min.js
create mode 100644 libs/source-code-pro/fonts/mrl8jkM18OlOQN8JLgasD9V_2ngZ8dMf8fLgjYEouxg.woff2
create mode 100644 libs/source-code-pro/fonts/mrl8jkM18OlOQN8JLgasDy2Q8seG17bfDXYR_jUsrzg.woff2
create mode 100644 libs/source-code-pro/styles.css
create mode 100644 libs/titillium-web/fonts/7XUFZ5tgS-tD6QamInJTcSo_WB_cotcEMUw1LsIE8mM.woff2
create mode 100644 libs/titillium-web/fonts/7XUFZ5tgS-tD6QamInJTcZSnX671uNZIV63UdXh3Mg0.woff2
create mode 100644 libs/titillium-web/fonts/anMUvcNT0H1YN4FII8wpr4-67659ICLY8bMrYhtePPA.woff2
create mode 100644 libs/titillium-web/fonts/anMUvcNT0H1YN4FII8wpr46gJz9aNFrmnwBdd69aqzY.woff2
create mode 100644 libs/titillium-web/fonts/anMUvcNT0H1YN4FII8wpr9INifKjd1RJ3NxxEi9Cy2w.woff2
create mode 100644 libs/titillium-web/fonts/anMUvcNT0H1YN4FII8wpr_SNRT0fZ5CX-AqRkMYgJJo.woff2
create mode 100644 libs/titillium-web/styles.css
create mode 100644 purchase/index.html
The authenticity of host 'github.com (192.30.253.113)' can't be established.
RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'github.com,192.30.253.113' (RSA) to the list of known hosts.
Counting objects: 114, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (103/103), done.
Writing objects: 100% (114/114), 2.00 MiB | 869.00 KiB/s, done.
Total 114 (delta 11), reused 0 (delta 0)
remote: Resolving deltas: 100% (11/11), done.
To github.com:spurin/masteringansible.github.io.git
+ d3fe1f1...37b974f HEAD -> master (forced update)
Branch master set up to track remote branch master from git@github.com:spurin/masteringansible.github.io.git.
INFO Deploy done: git

At this point, you should be able to successfully navigate to your site with https://domain.com and if so, give yourself a pat on the back :-)

Future Changes

From this point forward, you can quite simply use the local Hexo-Admin interface for updates, and when ready, push changes to your live site with a one liner as follows -

$ docker exec hexo-masteringansible.com bash -c 'hexo generate && hexo deploy'

Saving your current image, and future images

Whilst the docker containers in use here, should be able to be created and recreated as needed alongside the persistent application data, there is a risk that a future version of Hexo, may indeed break the execution process (after all Hexo and the supporting libraries are constantly evolving).

If you have a working container image, I recommend, taking a point in time copy, allowing you if required, to load that precise image at a future date.

All of the changes that you’ve made to the Docker image that involved command execution outside of /app, would have resulted in additional layers to that of the original spurin/hexo(-domain.com) images that you’ve been working on.

Whilst our /app data is safe inside it’s own volume, we may wish to save the current state of our running image.

Commit the current container state as am image, using YYYYMMDD as the reference -

$ docker commit hexo-masteringansible.com spurin/hexo-masteringansible.com:20200103
sha256:4ee249ff19ba1d7e6edcef83705543a458fb1a52ffa7219fc5f2d6b038e6cb1f

And save the new image to a file -

$ docker save spurin/hexo-masteringansible.com:20200103 > spurin_hexo-masteringansible.com_20200103.tar

In a worst case scenario, you can now load this image, and recreate your container to get it back to a known point in time.

Closing remarks

This post, summarises different technologies with a desired outcome of a working site/blog. Hopefully by the end of it, you’ve got a working site and/or have learnt something new. Comments and feedback are very welcome. Thanks - James Spurin

Share