Published: Sep 1, 2021 by Isaac Johnson
In our last blog we worked out Github Pages and blogging with jekyll and Github sites. But what if you have a blog already, such as this one in Ghost. How can we migrate and will it be benificial? What does an Azure DevOps pipeline look like?
Today we’ll explore a few paths to creating a Jekyll based blog then show how we can import from Ghost and update our pipeline.
Setup
We will start by following this guide.
Starting a fresh blog
First, install Ruby
builder@DESKTOP-QADGF36:~/Workspaces/jekyll-blog$ sudo apt install ruby
[sudo] password for builder:
Reading package lists... Done
Building dependency tree
…
Next, we can follow the steps for our OS: https://jekyllrb.com/docs/installation/ubuntu/
sudo apt-get install ruby-full build-essential zlib1g-dev
echo '# Install Ruby Gems to ~/gems' >> ~/.bashrc
echo 'export GEM_HOME="$HOME/gems"' >> ~/.bashrc
echo 'export PATH="$HOME/gems/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
gem install jekyll bundler
At this point we have the neccessary tools to create a fresh blog instance.
Setup a new blog:
jekyll new fbsblog
And now test it:
$ cd fbsblog && bundle exec jekyll server
Configuration file: /home/builder/Workspaces/fbsblog/_config.yml
Source: /home/builder/Workspaces/fbsblog
Destination: /home/builder/Workspaces/fbsblog/_site
Incremental build: disabled. Enable with --incremental
Generating...
Jekyll Feed: Generating feed for posts
done in 0.511 seconds.
Auto-regeneration may not work on some Windows versions.
Please see: https://github.com/Microsoft/BashOnWindows/issues/216
If it does not work, please upgrade Bash on Windows or run Jekyll with --no-watch.
Auto-regeneration: enabled for '/home/builder/Workspaces/fbsblog'
Server address: http://127.0.0.1:4000/
Server running... press ctrl-c to stop.
and check out http://localhost:4000/
Import from Ghost
Our next step is to fire up the Ghost blog which is how, up till this point, I’ve internally developed posts.
builder@DESKTOP-QADGF36:~/Workspaces/ghost-blog$ npm start
> ghost@2.13.1 start /home/builder/Workspaces/ghost-blog
> node index
[2021-09-01 16:09:48] WARN Theme's file locales/en.json not found.
[2021-09-01 16:09:48] INFO Ghost is running in development...
[2021-09-01 16:09:48] INFO Listening on: 127.0.0.1:2368
[2021-09-01 16:09:48] INFO Url configured as: http://localhost:2368/
[2021-09-01 16:09:48] INFO Ctrl+C to shut down
[2021-09-01 16:09:48] INFO Ghost boot 1.474s
If you use a SaaS service, you just need to access your Ghost backend.
Go to the Labs area. From there you can “Export your content”
This downloads a JSON file.
As i’m in WSL, i’ll copy that over and then add the Jekyll Ghost Importer GEM
builder@DESKTOP-QADGF36:~/Workspaces/psfntest2$ cp /mnt/c/Users/isaac/Downloads/fresh-brewed-science.ghost.2021-09-01.json ./ghost-export.json
builder@DESKTOP-QADGF36:~/Workspaces/psfntest2$ sudo gem install jekyll_ghost_importer
[sudo] password for builder:
Fetching jekyll_ghost_importer-1.1.0.gem
Fetching nokogiri-1.12.4-x86_64-linux.gem
Fetching reverse_markdown-1.4.0.gem
Successfully installed nokogiri-1.12.4-x86_64-linux
Successfully installed reverse_markdown-1.4.0
Successfully installed jekyll_ghost_importer-1.1.0
Parsing documentation for nokogiri-1.12.4-x86_64-linux
Installing ri documentation for nokogiri-1.12.4-x86_64-linux
Parsing documentation for reverse_markdown-1.4.0
Installing ri documentation for reverse_markdown-1.4.0
Parsing documentation for jekyll_ghost_importer-1.1.0
Installing ri documentation for jekyll_ghost_importer-1.1.0
Done installing documentation for nokogiri, reverse_markdown, jekyll_ghost_importer after 1 seconds
3 gems installed
Then you could import.. but i found a bit of a nuance. The older Jekyll used “feature_image” and the newer just assumes blog posts have “image”.
You can edit manually.. but my blog is rather hefty (51mb JSON) so i just used sed.
$ sed -i 's/"feature_image":/"image":/g' ghost-export.json
Then just import it.
builder@DESKTOP-QADGF36:~/Workspaces/psfntest2$ jekyll_ghost_importer ghost-export.json
Importing _drafts/themes.markdown
Importing _drafts/the-editor.markdown
Importing _posts/2019-02-02-and-so-it-begins.markdown
Importing _posts/2019-02-04-creating-a-blog.markdown
Importing _posts/2019-02-05-a-vault-tutorial.markdown
Importing _posts/2019-02-06-a-vault-tutorial-part-2.markdown
Importing _posts/2019-02-06-a-vault-tutorial-part-3.markdown
Importing _posts/2019-02-09-a-vault-tutorial-part-4.markdown
Importing _posts/2019-02-09-a-vault-tutorial-part-5.markdown
Importing _posts/2019-02-10-a-vault-tutorial-part-6.markdown
Importing _posts/2019-02-10-automating-updates-with-azure-devops.markdown
Importing _posts/2019-02-12-a-vault-tutorial-part-7.markdown
Importing _posts/2019-02-16-maven-and-nexus-tutorial-part-1.markdown
Importing _posts/2019-02-19-maven-and-nexus.markdown
Importing _posts/2019-02-21-maven-and-nexus-tutorial-part-3.markdown
Importing _posts/2019-02-16-greetings-and-salutations-on-this-fine-and-glorious-day.markdown
Importing _posts/2019-02-28-azure-devops-vsts-security-and-policies-part-1.markdown
Importing _posts/2019-02-28-azure-devops-vsts-security-and-policies-part-2.markdown
Importing _posts/2019-02-28-azure-devops-vsts-security-and-policies-part-3.markdown
Importing _posts/2019-03-02-azure-devops-vsts-security-and-policies-part-4.markdown
Importing _posts/2019-03-03-azure-devops-vsts-security-and-policies-part-5.markdown
Importing _posts/2019-03-10-automating-aks-deployments-like-a-boss-part-1.markdown
Importing _posts/2019-03-17-automating-aks-deployments-like-a-boss-part-2.markdown
Importing _posts/2019-03-25-switching.markdown
Importing _posts/2019-03-31-automating-aks-deployments-like-a-boss-part-3.markdown
Importing _posts/2019-04-07-automating-aks-deployments-like-a-boss-part-4.markdown
Importing _posts/2019-04-07-automating-aks-deployments-like-a-boss-part-5-appd.markdown
Importing _posts/2019-04-14-aks-and-service-mesh-istio-part-1.markdown
Importing _posts/2019-04-23-automating-aks-deployments-like-a-boss-part-6.markdown
Importing _posts/2019-04-30-automating-aks-deployments-like-a-boss.markdown
Importing _posts/2019-05-05-aks-and-stash-k8s-native-backups.markdown
Importing _posts/2019-05-08-the-other-clouds-linode-and-kubernetes.markdown
Importing _posts/2019-05-11-the-other-clouds-digital-ocean-and-kubernetes.markdown
Importing _posts/2019-05-17-the-other-clouds-vultr.markdown
Importing _posts/2019-05-20-rancher.markdown
Importing _posts/2019-05-26-harness.markdown
Importing _posts/2019-06-02-do-k8s-and-azdo-automation.markdown
Importing _posts/2019-06-09-do-k8s-and-azdo-automation-part-2.markdown
Importing _posts/2019-06-23-do-k8s-and-azdo-automation-part-3.markdown
Importing _posts/2019-07-01-do-k8s-and-azdo-automation-part-4.markdown
Importing _posts/2019-07-03-where-it-began-gcp-and-kubernetes.markdown
Importing _posts/2019-07-06-gcp-app-engine-standard.markdown
Importing _posts/2019-07-12-gcp-app-engine-flex.markdown
Importing _posts/2019-07-14-gcp-app-engine-flex-vs-standard-followup.markdown
Importing _posts/2019-07-26-untitled.markdown
Importing _posts/2019-08-08-automating-aks-deployments-like-a-boss-part-9-aks-aad-refinements.markdown
Importing _posts/2019-08-19-kubernetes-aspen-mesh.markdown
Importing _posts/2019-08-27-getting-started-with-k3s.markdown
Importing _posts/2019-09-08-k3s-on-win-10-wsl-2.markdown
Importing _posts/2019-09-08-on-a-personal-note.markdown
Importing _posts/2019-09-20-jfrog-enterprise-cicd-01.markdown
Importing _posts/2019-09-25-devops-stategery-iac-pipelines.markdown
Importing _posts/2019-10-06-ubuntu-multipass-better-than-docker.markdown
Importing _posts/2019-10-22-ubuntu-multipass-part-deux.markdown
Importing _posts/2019-10-28-lenovo-flex-6-14-2-in-1-a-developers-review.markdown
Importing _posts/2019-11-13-getting-started-skaffold.markdown
Importing _posts/2019-11-26-linode-lke-review.markdown
Importing _posts/2019-12-03-distributed-artifactory-and-kubernetes.markdown
Importing _posts/2019-12-22-k3os-almost-good-enough.markdown
Importing _posts/2020-01-12-getting-started-with-containerized-nexus.markdown
Importing _posts/2020-01-26-self-hosted-container-registry-in-kubernetes.markdown
Importing _posts/2020-02-09-civo-k8s-part-1.markdown
Importing _drafts/untitled-2.markdown
Importing _posts/2020-02-16-k3s-pi4-and-azure-devops.markdown
Importing _posts/2020-02-26-github-actions-with-pi4-k3s.markdown
Importing _posts/2020-03-04-k8s-and-redis-a-tale-of-layer-4-ingress.markdown
Importing _posts/2020-03-14-getting-started-with-keda.markdown
Importing _posts/2020-03-28-aks-and-ingress-again.markdown
Importing _posts/2020-04-03-aks-and-ingress-constraining-access.markdown
Importing _posts/2020-04-06-azure-arc-for-servers-preview.markdown
Importing _posts/2020-04-13-aks-and-newrelic.markdown
Importing _posts/2020-04-14-azure-devops-debt-pipelines-and-yaml.markdown
Importing _posts/2020-04-22-datadog-kubernetes-and-azdo.markdown
Importing _posts/2020-05-01-azure-devops-templates-and-integrating-teams-notifications.markdown
Importing _posts/2020-05-04-operationalization-in-day-2-operations.markdown
Importing _posts/2020-05-13-clickup-fb-workplace-and-gitlab-free-cheap-azdo-solutions-part-1.markdown
Importing _posts/2020-05-18-clickup-and-gitabl-part-2.markdown
Importing _posts/2020-05-21-azure-arc-for-kubernetes.markdown
Importing _posts/2020-05-27-whitesource-bolt-for-azdo-and-github.markdown
Importing _posts/2020-06-09-helm-3-creating-and-sharing-charts.markdown
Importing _posts/2020-06-23-codespaces.markdown
Importing _posts/2020-06-29-datadog-for-devops-metrics-dashboards-and-logs.markdown
Importing _posts/2020-07-12-diagrams-as-code-mermaid.markdown
Importing _posts/2020-07-16-notifications-email-with-logic-apps.markdown
Importing _posts/2020-07-29-k8s-and-krew-rbac-utilities.markdown
Importing _posts/2020-08-03-kubernetes-ssl-and-cert-manager.markdown
Importing _posts/2020-08-12-getting-started-with-packer-and-azdo.markdown
Importing _posts/2020-08-19-containerized-fortran-in-kubernetes.markdown
Importing _posts/2020-08-24-containerized-cobol-pascal-and-perl-based-bbs.markdown
Importing _posts/2020-09-03-kubernetes-serverless-knative.markdown
Importing _posts/2020-09-10-kubernetes-serverless-fission-io.markdown
Importing _posts/2020-09-14-kubernetes-serverless-kubeless.markdown
Importing _posts/2020-09-20-kubernetes-serverless-openfaas.markdown
Importing _posts/2020-10-03-vault-on-kubernetes-getting-started.markdown
Importing _posts/2020-10-06-vault-on-kubernetes-part-2-multiple-k8s-templates-and-external-ips.markdown
Importing _posts/2020-10-16-hashi-waypoint.markdown
Importing _posts/2020-10-23-vs-code-bridge-to-kubernetes.markdown
Importing _posts/2020-10-29-chef-habitat-getting-started.markdown
Importing _posts/2020-11-05-azure-devops-vm-deployment-environments.markdown
Importing _posts/2020-11-17-k3s-on-prem-getting-started.markdown
Importing _posts/2020-11-22-container-registries-ibm-cloud.markdown
Importing _posts/2020-11-23-alicloud-container-registry.markdown
Importing _posts/2020-12-01-observability-epsagon.markdown
Importing _posts/2020-12-09-oracle-cloud-vms-k3s-and-container-registry.markdown
Importing _drafts/logic-monitor-who-isnt-interested.markdown
Importing _posts/2020-12-17-rollbar-getting-started.markdown
Importing _posts/2020-12-31-azure-devops-agent-pools.markdown
Importing _posts/2021-01-08-azure-devops.markdown
Importing _posts/2021-01-15-azure-devops-deploying-to-iis-with-windows-vm-environments.markdown
Importing _posts/2021-01-20-terraform-cloud-getting-started.markdown
Importing _posts/2021-01-29-nomad-getting-started.markdown
Importing _posts/2021-02-06-private-ssh-git-with-azure-devops.markdown
Importing _posts/2021-02-10-chef-getting-started.markdown
Importing _posts/2021-02-18-azure-devops-secrets-in-files.markdown
Importing _posts/2021-02-26-revisiting-kubernetes-and-keda.markdown
Importing _posts/2021-03-05-terraform-and-azure-devops-a-bucket-of-yes.markdown
Importing _posts/2021-03-13-logdna-logging-and-alerting.markdown
Importing _posts/2021-03-19-k0s-mirantiss-little-k8s-distro.markdown
Importing _posts/2021-03-26-dapr-getting-started.markdown
Importing _posts/2021-04-03-dapr-part-2.markdown
Importing _posts/2021-04-09-dapr-part-3-digging-into-secrets.markdown
Importing _posts/2021-04-30-azure-dns.markdown
Importing _posts/2021-04-15-dapr-part-4-service-discovery-and-bindings.markdown
Importing _posts/2021-04-16-dapr-part-5-observability-telemetry-and-tracing.markdown
Importing _posts/2021-05-07-harbor-getting-started-with-an-on-prem-container-registry.markdown
Importing _posts/2021-05-13-crypto-mining-intro-not-for-profit.markdown
Importing _posts/2021-05-24-dapr-part-6-workflows.markdown
Importing _posts/2021-05-27-dapr-part-7-secure-our-services.markdown
Importing _posts/2021-06-03-dapr-part-8-middleware-pipelines-for-oauth.markdown
Importing _posts/2021-07-12-wiqautomations.markdown
Importing _posts/2021-06-07-dapr-k8s-events-bindings-kubewatch-and-azdo-webhook-triggers.markdown
Importing _posts/2021-06-11-kubewatch-to-akv-for-dr.markdown
Importing _posts/2021-06-24-feedback-forms-to-azdo-work-items.markdown
Importing _posts/2021-06-24-feedback-forms-to-azdo-work-items-part-2.markdown
Importing _posts/2021-07-08-ingest-email.markdown
Importing _posts/2021-07-22-jenkins-and-azdo.markdown
Importing _posts/2021-07-26-service-mesh-observability-kiali.markdown
Importing _posts/2021-08-05-azure-powershell-functions-getting-started.markdown
Importing _posts/2021-08-12-azure-powershell-functions-extending-automating-and-securing.markdown
Importing _posts/2021-08-18-kuma-mesh.markdown
Importing _posts/2021-08-24-github-blog-jekyll.markdown
141 posts imported ( 4 draft )
we can fire up Jekyll again to see it is working.
We can tweak the main _config.yml file to match our blog
title: Fresh/Brewed Science
email: isaac.johnson@gmail.com
description: >-
Tales from Cloudy McCloudface.
baseurl: ""
url: "https://freshbrewed.science"
twitter_username: nulubez
github_username: idjohnson
# Build settings
markdown: kramdown
theme: minima
plugins:
- jekyll-feed
pro-tip: If you have markdown with lots of braces (e.g. like you might find in helm charts) you can wrap sections that generate liquid errors with “raw” and “endraw”:
{% raw %}
some markdown with lots of unescaped characters
{% endraw %}
and again, fire it up to see the results
$ bundle exec jekyll serve
Configuration file: /home/builder/Workspaces/jekyll-blog/_config.yml
Source: /home/builder/Workspaces/jekyll-blog
Destination: /home/builder/Workspaces/jekyll-blog/_site
Incremental build: disabled. Enable with --incremental
Generating...
Jekyll Feed: Generating feed for posts
done in 5.825 seconds.
/home/builder/gems/gems/pathutil-0.16.2/lib/pathutil.rb:502: warning: Using the last argument as keyword parameters is deprecated
Auto-regeneration may not work on some Windows versions.
Please see: https://github.com/Microsoft/BashOnWindows/issues/216
If it does not work, please upgrade Bash on Windows or run Jekyll with --no-watch.
Auto-regeneration: enabled for '/home/builder/Workspaces/jekyll-blog'
LiveReload address: http://127.0.0.1:35729
Server address: http://127.0.0.1:4000/
Server running... press ctrl-c to stop.
LiveReload: Browser connected
As for the base minima theme, we can actually use a few different colour patterns with it.
Change the Gemfile to pull the latest theme repo:
#gem "minima", "~> 2.0"
gem "minima", git: "https://github.com/jekyll/minima"
Then do a bundle install and update to pull that down
builder@DESKTOP-QADGF36:~/Workspaces/psfntest3$ bundle install
Following files may not be writable, so sudo is needed:
/usr/local/bin
/var/lib/gems/2.7.0
/var/lib/gems/2.7.0/build_info
/var/lib/gems/2.7.0/cache
/var/lib/gems/2.7.0/doc
/var/lib/gems/2.7.0/extensions
/var/lib/gems/2.7.0/gems
/var/lib/gems/2.7.0/specifications
Fetching https://github.com/jekyll/minima
Fetching gem metadata from https://rubygems.org/..........
Fetching gem metadata from https://rubygems.org/.
Resolving dependencies...
Using public_suffix 4.0.6
Using addressable 2.8.0
Using bundler 2.1.4
Using colorator 1.1.0
Using concurrent-ruby 1.1.9
Using eventmachine 1.2.7
Using http_parser.rb 0.6.0
Using em-websocket 0.5.2
Using ffi 1.15.3
Using forwardable-extended 2.6.0
Using i18n 0.9.5
Using sass 3.7.4
Using jekyll-sass-converter 1.5.2
Using rb-fsevent 0.11.0
Using rb-inotify 0.10.1
Using listen 3.7.0
Using jekyll-watch 2.2.1
Using kramdown 1.17.0
Using liquid 4.0.3
Using mercenary 0.3.6
Using pathutil 0.16.2
Using rouge 3.26.0
Using safe_yaml 1.0.5
Using jekyll 3.8.7
Using jekyll-feed 0.15.1
Using jekyll-seo-tag 2.7.1
Using minima 2.5.1 from https://github.com/jekyll/minima (at master@3cdd14d)
Bundle complete! 6 Gemfile dependencies, 27 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
builder@DESKTOP-QADGF36:~/Workspaces/psfntest3$ bundle update
Following files may not be writable, so sudo is needed:
/usr/local/bin
/var/lib/gems/2.7.0
/var/lib/gems/2.7.0/build_info
/var/lib/gems/2.7.0/cache
/var/lib/gems/2.7.0/doc
/var/lib/gems/2.7.0/extensions
/var/lib/gems/2.7.0/gems
/var/lib/gems/2.7.0/specifications
Fetching https://github.com/jekyll/minima
Fetching gem metadata from https://rubygems.org/..........
Fetching gem metadata from https://rubygems.org/.
Resolving dependencies...
Using public_suffix 4.0.6
Using addressable 2.8.0
Using bundler 2.1.4
Using colorator 1.1.0
Using concurrent-ruby 1.1.9
Using eventmachine 1.2.7
Using http_parser.rb 0.6.0
Using em-websocket 0.5.2
Using ffi 1.15.3
Using forwardable-extended 2.6.0
Using i18n 0.9.5
Using sass 3.7.4
Using jekyll-sass-converter 1.5.2
Using rb-fsevent 0.11.0
Using rb-inotify 0.10.1
Using listen 3.7.0
Using jekyll-watch 2.2.1
Using kramdown 1.17.0
Using liquid 4.0.3
Using mercenary 0.3.6
Using pathutil 0.16.2
Using rouge 3.26.0
Using safe_yaml 1.0.5
Using jekyll 3.8.7
Using jekyll-feed 0.15.1
Using jekyll-seo-tag 2.7.1
Using minima 2.5.1 from https://github.com/jekyll/minima (at master@3cdd14d)
Bundle updated!
then lastly, update the _config.yaml to add a skin parameter:
title: Fresh/Brewed Science
email: isaac.johnson@gmail.com
description: >-
Tales from Cloudy McCloudface.
baseurl: ""
url: "https://freshbrewed.science/"
twitter_username: nulubez
github_username: idjohnson
# Build settings
markdown: kramdown
theme: minima
plugins:
- jekyll-feed
minima:
skin: dark
date_format: "%b %-d, %Y"
There are three skins they added
- dark
- solarized
- solarized-dark
- classic (standard)
You can see more on it here.
Themes
This was great but then i wanted more themes.
I checked out the curated lists at
I really tried to make the Bajawa one work.. however i had issues.
In fact, anything outside the normal minima, i would get errors about the theme being fixed at Jekyll 3.* (to line up with Github pages) yet latest Jekyll is 4.*.
When i did manage to install a theme, tweaking the style got worse and worse…
pro-tip: if in dancing between themes (and likely between many conflicting ruby gems), you can ‘scrub’ by clearing out the ruby cache:
root@DESKTOP-QADGF36:~# rm -rf /usr/lib/ruby/vendor_ruby/
Themes, the cheater way
The other way you can do themes is to just copy the theme repo. That is, instead of trying to create a fresh new Jekyll blog then shoehorn in the theme and styles and files. Just clone their repo (from the themes’ github) and then remove all the bits you don’t need.
This was a whole lot easier.
builder@DESKTOP-QADGF36:~/Workspaces$ git clone https://github.com/kulacino/bajawa
Cloning into 'bajawa'...
remote: Enumerating objects: 150, done.
remote: Counting objects: 100% (150/150), done.
remote: Compressing objects: 100% (101/101), done.
remote: Total 150 (delta 48), reused 135 (delta 36), pack-reused 0
Receiving objects: 100% (150/150), 1.90 MiB | 6.69 MiB/s, done.
Resolving deltas: 100% (48/48), done.
builder@DESKTOP-QADGF36:~/Workspaces$ cd bajawa/
if you do a bundle install now, you’ll see the error
builder@DESKTOP-QADGF36:~/Workspaces/bajawa$ bundle install
Fetching gem metadata from https://rubygems.org/..........
Fetching gem metadata from https://rubygems.org/.
Resolving dependencies...
Bundler could not find compatible versions for gem "bundler":
In Gemfile:
bundler (~> 1.16)
Current Bundler version:
bundler (2.1.4)
This Gemfile requires a different version of Bundler.
Perhaps you need to update Bundler by running `gem install bundler`?
Could not find gem 'bundler (~> 1.16)' in any of the relevant sources:
the local ruby installation
Just update the gemspec to match the version referenced or whatever your current version is.
builder@DESKTOP-QADGF36:~/Workspaces/bajawa$ cat bajawa.gemspec | grep bundler
spec.add_development_dependency "bundler", "~> 2.1.2"
Then i did the bundle install
builder@DESKTOP-QADGF36:~/Workspaces/bajawa$ bundle install
Warning: the running version of Bundler (2.1.2) is older than the version that created the lockfile (2.2.26). We suggest you to upgrade to the version that created the lockfile by running `gem install bundler:2.2.26`.
Fetching gem metadata from https://rubygems.org/..........
Fetching gem metadata from https://rubygems.org/.
Resolving dependencies...
Following files may not be writable, so sudo is needed:
/usr/bin
/usr/lib/ruby/gems/2.7.0
/usr/lib/ruby/gems/2.7.0/build_info
/usr/lib/ruby/gems/2.7.0/cache
/usr/lib/ruby/gems/2.7.0/doc
/usr/lib/ruby/gems/2.7.0/extensions
/usr/lib/ruby/gems/2.7.0/gems
/usr/lib/ruby/gems/2.7.0/specifications
Fetching rake 12.3.3
Your user account isn't allowed to install to the system RubyGems.
You can cancel this installation and run:
bundle install --path vendor/bundle
to install the gems into ./vendor/bundle/, or you can enter your password
and install the bundled gems to RubyGems using sudo.
Password:
Installing rake 12.3.3
Fetching public_suffix 4.0.6
Installing public_suffix 4.0.6
Fetching addressable 2.8.0
Installing addressable 2.8.0
Fetching colorator 1.1.0
Installing colorator 1.1.0
Fetching eventmachine 1.2.7
Installing eventmachine 1.2.7 with native extensions
Fetching http_parser.rb 0.6.0
Installing http_parser.rb 0.6.0 with native extensions
Fetching em-websocket 0.5.2
Installing em-websocket 0.5.2
Fetching concurrent-ruby 1.1.9
Installing concurrent-ruby 1.1.9
Fetching i18n 1.8.10
Installing i18n 1.8.10
Fetching ffi 1.15.3
Installing ffi 1.15.3 with native extensions
Fetching sassc 2.4.0
Installing sassc 2.4.0 with native extensions
Fetching jekyll-sass-converter 2.1.0
Installing jekyll-sass-converter 2.1.0
Fetching rb-fsevent 0.11.0
Installing rb-fsevent 0.11.0
Fetching rb-inotify 0.10.1
Installing rb-inotify 0.10.1
Fetching listen 3.7.0
Installing listen 3.7.0
Fetching jekyll-watch 2.2.1
Installing jekyll-watch 2.2.1
Fetching rexml 3.2.5
Installing rexml 3.2.5
Fetching kramdown 2.3.1
Installing kramdown 2.3.1
Fetching kramdown-parser-gfm 1.1.0
Installing kramdown-parser-gfm 1.1.0
Fetching liquid 4.0.3
Installing liquid 4.0.3
Fetching mercenary 0.4.0
Installing mercenary 0.4.0
Fetching forwardable-extended 2.6.0
Installing forwardable-extended 2.6.0
Fetching pathutil 0.16.2
Installing pathutil 0.16.2
Fetching rouge 3.26.0
Installing rouge 3.26.0
Fetching safe_yaml 1.0.5
Installing safe_yaml 1.0.5
Fetching unicode-display_width 1.7.0
Installing unicode-display_width 1.7.0
Fetching terminal-table 2.0.0
Installing terminal-table 2.0.0
Fetching jekyll 4.2.0
Installing jekyll 4.2.0
Fetching jekyll-archives 2.2.1
Installing jekyll-archives 2.2.1
Fetching jekyll-feed 0.15.1
Installing jekyll-feed 0.15.1
Fetching jekyll-paginate 1.1.0
Installing jekyll-paginate 1.1.0
Fetching jekyll-redirect-from 0.16.0
Installing jekyll-redirect-from 0.16.0
Fetching jekyll-seo-tag 2.6.1
Installing jekyll-seo-tag 2.6.1
Fetching jekyll-sitemap 1.4.0
Installing jekyll-sitemap 1.4.0
Fetching jekyll-titles-from-headings 0.5.3
Installing jekyll-titles-from-headings 0.5.3
Using bajawa 0.1.0 from source at `.`
Using bundler 2.1.2
Bundle complete! 3 Gemfile dependencies, 37 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
builder@DESKTOP-QADGF36:~/Workspaces/bajawa$
builder@DESKTOP-QADGF36:~/Workspaces/bajawa$
builder@DESKTOP-QADGF36:~/Workspaces/bajawa$ bundle exec jekyll serve
Configuration file: /home/builder/Workspaces/bajawa/_config.yml
Source: /home/builder/Workspaces/bajawa
Destination: /home/builder/Workspaces/bajawa/_site
Incremental build: disabled. Enable with --incremental
Generating...
done in 0.221 seconds.
Auto-regeneration may not work on some Windows versions.
Please see: https://github.com/Microsoft/BashOnWindows/issues/216
If it does not work, please upgrade Bash on Windows or run Jekyll with --no-watch.
Auto-regeneration: enabled for './'
Server address: http://127.0.0.1:4000/
Server running... press ctrl-c to stop.
Eventually I settled on a theme I liked that had the images and content in a layout that looked good to my eyes (mere-blog-theme).
Setting up the AzDO pipeline.
After tweaking the local version to the point i visually liked it, it was time to add it to AzDO.
First I needed some common templates that i used in the Ghost blog:
templates/aws-release.yml:
jobs:
- job:
pool:
vmImage: 'ubuntu-latest'
steps:
# now uses site artifact
- task: DownloadBuildArtifacts@0
inputs:
buildType: "current"
downloadType: "single"
artifactName: "site"
downloadPath: "_drop"
- bash: |
#!/bin/bash
export
set -x
export DEBIAN_FRONTEND=noninteractive
sudo apt-get -yq install tree
cd ..
pwd
tree .
displayName: 'Bash Script Debug'
- task: AmazonWebServices.aws-vsts-tools.S3Upload.S3Upload@1
displayName: 'S3 Upload: ${{ parameters.awsBucket }} all'
inputs:
awsCredentials: ${{ parameters.awsCreds }}
regionName: 'us-east-1'
bucketName: ${{ parameters.awsBucket }}
sourceFolder: '$(System.DefaultWorkingDirectory)/_drop/site'
filesAcl: 'public-read'
templates/notifications.yml
jobs:
- job:
pool:
vmImage: 'ubuntu-latest'
steps:
- bash: |
#!/bin/bash
set -x
umask 0002
cat > ./post.json <<'endmsg'
{
"@type": "MessageCard",
"@context": "https://schema.org/extensions",
"summary": "1 new build message",
"themeColor": "0078D7",
"sections": [
{
"activityImage": "https://ca.slack-edge.com/T4AQPQN8M-U4AL2JFC3-g45c8854734a-48",
"activityTitle": "$(Build.SourceVersionAuthor)",
"activitySubtitle": "$(Build.SourceVersionMessage) - $(Build.SourceBranchName) - $(Build.SourceVersion)",
"facts": [
{
"name": "Keywords:",
"value": "$(System.DefinitionName)"
},
{
"name": "Group:",
"value": "$(Build.BuildNumber)"
}
],
"text": "Build $(Build.BuildNumber) has completed. Pipeline started at $(System.PipelineStartTime). ${{ parameters.awsBucket }} bucket updated and ${{ parameters.siteUrl }} is live. The world now has just that much more joy in it.\n<br/>\n Peace and love.",
"potentialAction": [
{
"@type": "OpenUri",
"name": "View conversation"
}
]
}
]
}
endmsg
curl -X POST -H "Content-Type: application/json" -d @post.json https://outlook.office.com/webhook/ccef6213-asdf-asdf-asdf-adsfasdfasdf@92a2e5a9-asdf-asdf-asdf-asdfasdfasdf/IncomingWebhook/24casdfasdfasdfasdfasdfasdfd/26a39c32-asdf-asdf-asdf-asdf
displayName: 'Teams Posting'
Lastly, my azure-pipelines.yml was suprisingly short this time. Unlike with Ghost that i had to fire up the server then crawl the site before painfully sedding localhost paths, i just needed to render it out with bundle exec jekyll build
.
azure-pipelines.yml
trigger:
- main
- develop
pool:
vmImage: 'ubuntu-latest'
variables:
- group: AZDOSecrets
stages:
- stage: build
jobs:
- job: start_n_sync
displayName: start_n_sync
continueOnError: false
steps:
- task: UseRubyVersion@0
inputs:
versionSpec: '>= 2.5'
# install Jekyll
- script: |
gem install jekyll bundler
bundle install --retry=3 --jobs=4
displayName: 'bundle install'
#b build the site
- script: |
bundle install
bundle exec jekyll build
displayName: 'jekyll'
# create and publish the "site" archive
- task: CopyFiles@2
displayName: 'Copy Files to: $(Build.ArtifactStagingDirectory)'
inputs:
SourceFolder: '_site'
TargetFolder: '$(Build.ArtifactStagingDirectory)'
- task: PublishBuildArtifacts@1
inputs:
pathtoPublish: '$(Build.ArtifactStagingDirectory)'
artifactName: site
- stage: release_prod
dependsOn: build
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
jobs:
- template: templates/aws-release.yml
parameters:
awsCreds: freshbrewed
awsBucket: freshbrewed.science
awsFinalBucket: freshbrewed.science
- stage: build_notification_prod
dependsOn: release_prod
jobs:
- template: templates/notifications.yml
parameters:
siteUrl: https://freshbrewed.com
awsBucket: freshbrewed.com
awsFinalBucket: freshbrewed.science
- stage: release_test
dependsOn: build
condition: and(succeeded(), ne(variables['Build.SourceBranch'], 'refs/heads/main'))
jobs:
- template: templates/aws-release.yml
parameters:
awsCreds: freshbrewed
awsBucket: freshbrewed-test
awsFinalBucket: freshbrewed.science
- stage: build_notification_test
dependsOn: release_test
jobs:
- template: templates/notifications.yml
parameters:
siteUrl: http://freshbrewed-test.s3-website-us-east-1.amazonaws.com/
awsBucket: freshbrewed-test
awsFinalBucket: freshbrewed.science
After i added the Github repo, the build worked great.
And i could test: http://freshbrewed-test.s3-website-us-east-1.amazonaws.com/index.html
Adding Search
Bing
I have a soft spot for Bing. I have no idea why. I guess i just wish it would do better. But i figured, hey, i’ll give that a try first.
You first need to create a ‘Bing Custom Search’ from the Azure Portal
You can keep it in the Free tier:
But you can see how many transactions per second you can service as well as other options here: https://www.microsoft.com/en-us/bing/apis/pricing
Next we go to the custom portal URL: https://www.customsearch.ai/
After logging in, we can start to create a search instance
Add a URL
and then we can build UI
Back at the portal, we can get that search key from our Keys and Endpoints back in the portal:
Once pasted, I could click Publish in the upper right.
Now i can go to the Hosted UI page to get a Javascript embed or URL to use:
or use the script:
<script type="text/javascript"
id="bcs_js_snippet"
src="https://ui.customsearch.ai/api/ux/rendering-js?customConfig=0ce93d31-8080-497f-91da-e18fa9f33019&market=en-US&version=latest&q=">
</script>
But i saw no results:
Adding to Bing Manually
using Bing Webmaster Tools, I tried adding the site manually
This required me to upload a veification file to my site. I did that quickly via AWS management console
note: make sure to set public (AWS always defaults to private)
Then I went back to the verification tool and clicked verify
…according to Bing, they know it, but have yet to crawl it. so we can request indexing
but as you can search bing presently, other than image search, freshbrewed.science just does not come up.
DuckDuckGo
The documentation on creating a custom search with DuckDuckGo is a little sparse. But i did find success with this this little widget builder.
DuckDuckGo actually works fine and pulls in results.
Google makes it rather easy. I’m sure they will charge you if you want to remove all adverts. But assuming google search is good enough and fast enough, it was just a quick two clicks through their wizard here: https://programmablesearchengine.google.com/cse/create/getcode?cx=85735040fe22c7387
Summary
We took what we started last time and rolled it to production. We did this by both firing a fresh Jekyll blog and also cloning out of a theme to resolve dependency issues.
Next we showed how to convert the JSON export from Ghost to Jekyll markdown (albeit, this markdown could really be used anywhere). Lastly, we walked through adding Search three ways (Bing, Duckduckgo and Google).
Why did we do this? There is no majik in Jekyll. It’s more about using a format more condusive to my workflow. To date I’ve worked out blog posts in google docs. When they are ready i have to copy and paste into Ghost, which has to be fired up locally. Lastly, i’ve had to double enter my images because google docs actually copies a reference to a hosted image, not an image file. It’s really quite jenky and makes it a challenge to work on more than one post at a time.
Additionally, I was spurred by the need to move to a more supportable platform. Ghost was eating posts on the mainpage and short of hosting the actual app in a container or removing all my old content, i didn’t see a path to resolving this. My builds were constantly skirtting the hour limit on the free tier of Azure Pipelines and at least once i had to pay for a month of premium to unblock deployments.
The next steps will be to continue to tweak the format. However, now that my content is in proper markdown, there is a lot more freedom in fixing/changing things.