このBlogを公開するまでのエトセトラ

注) この記事はもはやただただ日記に近い何かです。

みなさんどうも初めまして、はまーん(@track3jyo)です。

私は関西でクラウド関係の技術職をしています。自己紹介については About ページに少しですが書きました。これからこの Blog で個人的に検証した技術的な話とか、技術に関係ない話とか色々書いていきます。更新頻度は無理な目標立ててもアレなので、Monthly から bi-weekly くらいを目指してアウトプットしていきますー!

さてさて、この投稿ではこのサイトが出来上がるでの変遷をさらーっとですが書いておこうと思います。

Summary

このサイトは α版、β版を経て V1.0 として結局 HugoAWS Amplify Console という組み合わせに落ちつきました。色々やってみて思ったのは、僕はほんの少しですが凝り性なのでこういう風に色々やるのは楽しかったんですが、本来は Blog を書くこと自体(Outputする方)に力を入れた方が正解なんでしょうね。それこそ僕も悩んだんですけど、はてブロのような。僕自身「よし!Blog やるぞ!」からこの初投稿までに半年以上かかっちゃったのでw

もちろんその時間だらだら Blog どうするかー?と悩んで半年かけたわけではないです。しかしBlogを「書く場所がある」という状態と「書く場所がない」状態にはかなり大きな差がありますね。あれば、「書こうかな?」ってなりますしね。無いと「作ってからだなー」ってなるので。当たり前のことですけど。。。

大枠でいうとこんなことしていました。

  • [α版] Wordpress on AWS (ALB + EC2 + RDS)
  • [β版] Hugo + Github + Netlifty + Netlify CMS
  • [V1.0] Hugo + Github + Amplify Console

ちなみにα版で色々やってた期間が一番長くて、β版が一番短かったです。そしてもちろん現在の V1.0 が一番気に入っています。この投稿のメイントピックは V1.0 の話でα版・β版についても簡単にですが書き残しておきます。

[α版] Wordpress on AWS(ALB + EC2 + RDS + S3 + CloudFront)

  • おなじみの Wordpress からスタートしました。僕自身エンジニアとしてのベースが WEB 系の開発者で、新卒入社から5年間 LAMP 環境をメインの戦場としてきました。前職の経験から Drupal にしようかなと悩みましたが、コミュニティの大きさやプラグインの多さからとりあえず Wordpress にしました。あ、でもほんと Drupal 個人的には大好きな CMS なので是非一度お試しください。

  • 個人の AWS アカウント上に構築しました。こういうとき Wordpress がすでにインストール済みな Lightsail は最高な選択肢だと思うんですけど、この段階では「趣味で作るBlogなわけだし、男なら自前でインストールっしょww」くらいのピエロっぷりな私は、ALB + EC2(nginx, php-fpm) + RDS Aurora MySQL + S3 +CloudFront で Wordpress を自前で構築しました。自前でやるならEC2一台で始めてもよかったんですけど、「それも味気ねぇな・・・」とこんな構成にしました。

  • nginx.confphp.iniphp-fpm.conf、Wordpressのプラグインや設定などを簡易にチューニングしたり、セキュリティ設定を施しました。

  • テーマ選びでも悩みますね。夢だけ広がって有料テーマ買うことも考えたけど、結果として Cocoon に落ち着きました。もちろんそのままのテーマのままにしとくのも何か恥ずかしい気がしてテーマのカスタマイズを開始するんですが、デザイナーではないのでここでもまた時間がかかりました。

  • なんとかベースの形にはなりましたが、もともと「コストは勉強費用だぜ!」くらいに思っていましたが、お小遣いから計上されるコストが急に気になってきて「なんか違うなー」と思って結局 Cfn スタックごと Terminated!

[β版] Hugo + Github + Netlifty + Netlify CMS

  • α版からしばらく経って、改めて Blog がんばるモチベーションがでてきました。きっかけはこの後書く自宅のデスク環境を整えたことをアウトプットするためでした。

  • 今度はお財布が苦しくならないように、何か静的サイトジェネレータ的なものを使おうと決意。その上で静的コンテンツのホスティングサービスである Netlify を使って「無料で始めるの最高じゃね?」と思いスタートしました。

  • 静的サイトジェネレータもいくつかあるのですが、その中でも Hugo にしたのは、触ってみた感じ 1番起動が早かったのと、テーマが拡充していたり、カスタマイズ性の高さが気に入りました。

  • ただこの段階では食わず嫌い的な感じで CMS 的に Blog を書きたい気持ちがあって、調べていると Netlify CMS なるものがあることを発見。ファイルアップロードとかもしやすそうなので Netlify CMS を使ってみました。

  • 今回は個人ブログということもあり開発環境やステージ環境設けるほどのものでもなかったのでローカルで作業することが多く、カスタマイズとかしていく中で CMS なくても Hugo のお作法で Blog 書くこと自体に単純に慣れてきて、どんどん CMS いらねぇな・・となってきました。

  • そしてせっかくなので AWS のサービス何か使ってみたいなーという想いもでてきました。

[V1.0] Hugo + Github + AWS Amplify Console

  • そして、これが現在のBlogの形として落ち着いた形です。ホスティング場所を再び AWS 上に戻し、今度は静的ウェブアプリケーションを構築およびデプロイするためのシンプルな CI/CD ワークフローやホスティング環境を提供してくれる AWS Amplify Console を利用することにしました。

  • コストは0円ではないですが計算したところ、12ヶ月の無料利用枠もありますし、無料枠なしでも以下の条件で月 $1.0 も行きません(Amplify Console のコストはこちらを参考)。また、簡単に環境を持ってこれたのと、エッジロケーションの距離の兼ね合いもあったのかサイトのレスポンスタイムも向上したため満足しています。

    • 月に12回のBuild(週1回投稿+ブログ自体のメンテ)
    • Artifactrの平均サイズが25MB
    • 毎日200MBのデータ配信

V1.0 構築手順

Hugo で環境を作ったり、Amplify との連携については Hugo の公式ドキュメントや、他の方の書いた記事がすでにたくさんあります。参考にしたものを掲載しておきます。

テーマ選定

アウトプット目的の技術 Blog テーマですし、派手さよりシンプルかつ軽量なもので、カスタマイズのしやすいものを探しました。結果としてMainroadをベーステーマに選定しました。

スタイル調整・ロゴフォント調整

ここから色々いじっていきます。さて、Hugo でのテーマのカスタマイズですが、Themes というディレクトリ配下にベーステーマとなるソースを置いておき、config.tomltheme = "mainroad"のように記載することでテーマを指定します。 あとはルートディレクトリ配下はテーマ配下とほぼ同様のディレクトリ構造となっていますので、テーマ自体をいじらずとも基本はテンプレートやスタイル等をオーバライドすることができます。

├── archetypes
│   └── default.md
├── config.toml
├── content
├── data
├── layouts
├── static
└── themes
    └── mainroad
        ├── archetypes
        ├── layouts
        ├── static

私はサイト全体のカラーをモノクロおよび青と決め、ハイライト色の調整を行いました。こちらは config.toml で変更可能です。デフォルト値 #e22d30 から #2189c8 に変更しました。

[Params]
  highlightColor = "#2189c8"

アウトサイドの背景色を何にするのか悩んだんですけど、単色だとなんか味気ない感じに見えたので青のストライプ柄にしました。以下のように css をカスタマイズしています。

body {
    ...
	background-image: -moz-linear-gradient(45deg, #CAE9FF 0%, #CAE9FF 25%, #ffffff 25%, #ffffff 50%, #CAE9FF 50%, #CAE9FF 75%, #ffffff 75%);
	background-image: -webkit-linear-gradient(45deg, #CAE9FF 0%,#CAE9FF 25%,#ffffff 25%,#ffffff 50%,#CAE9FF 50%,#CAE9FF 75%,#ffffff 75%);
	background-image: linear-gradient(45deg, #CAE9FF 0%,#CAE9FF 25%,#ffffff 25%,#ffffff 50%,#CAE9FF 50%,#CAE9FF 75%,#ffffff 75%);
	background-position: 0px 0px;
	background-size: 10px 10px;
}

そして基本は日本語記事を書くので日本語用のフォントを指定したいところです。 こちらを参考にし Noto Sans JP フォントを導入しました。こちらの記事 GTM の導入や Twitter ウィジェットの設置など非常に参考になる部分が多くて助かりました。ありがとうございます。

あとはタイトルロゴのフォントですが、これもロゴっぽくしたくてローカルフォントを設定して利用しました。 フォントは851マカポップというフリーフォントをダウンロードして利用しています。

ttfファイルをダウンロードした上で、static/css/font/851MkPOP_002.ttf に保存し @font-face でフォント名とフォントデータを指定した上で、あとは font-family で指定しただけです。

@font-face {
  font-family: '851mkpop';
  src: url('/css/font/851MkPOP_002.ttf') format('truetype');
}

.logo__title {
	font-family: "851mkpop", sans-serif;
}

また細かいですがロゴや記事本文の文字サイズを読みやすいサイズに調整しています。

Twitterウィジェットの設置

TOP ページのサイドメニューに自身のTwitterのアカウントの最新ツイートを表示するように調整しました。またもこちらの記事を参考にしました。

やったこととしては、

  1. 自前の template ファイル(layouts/partials/widgets/twitter.html)を作成します。
  2. テンプレートのソースコードはこちらに自身のTwitterアカウントURLを記入して進めていくと簡単に埋め込み用のコードを作成してくれます。
  3. これでサイドバー用ウィジェット “twitter” として使えるようになるので、config.toml で以下のようにウィジェットとして指定することでサイドバーに表示されます。
[Params.sidebar]
  # Enable widgets in given order
  widgets = ["recent", "categories", "taglist", "twitter"]

SNSシェアボタン作成

ブログを書くからにはどこかでシェアとかされたいものですよね?SNSのシェアボタンを作っちゃいましょう。 とはいっても先人の方がすでに実行済みなのでこちらをベースにしました。 書かれていることをまとめると

  1. Twitterのウィジェット同様に今度は Custom partial として /layouts/partials/share.html を用意しました。中身はTwitterと、facebookと、はてなブックマークに絞りました。
  • また参考リンクの内容を少しカスタマイズして、.RelPermalinkでパスをとってきて、absURL で記事URLを作るようにしています。その際にconfig.tomlで、baseurl = "https://track3jyo.com" を指定しています。もっとスマートにいける気もするのですが、このやり方でないと結局このあとのOGPなどで正しくURLが作られず、今の所はbaseURLでhostname指定をする手法を使っています。
{{ if ne .Params.share false}}
<!-- use font awsome -->
<section class="section sns_parent">
  <div class="container sns_section">
      <div class="sns_button twitter">
        <a href="http://twitter.com/intent/tweet?url={{ .RelPermalink | absURL }}&text={{ .Title }}" target="_blank" title="Tweet"><i class="fab fa-twitter"></i></a>
      </div>
      <div class="sns_button hatena">
        <a href="http://b.hatena.ne.jp/add?mode=confirm&url={{ .RelPermalink | absURL }}&title={{ .Title }}" target="_blank" title="hatena"><i class="fa fa-hatena"></i></i></a>
      </div>
      <div class="sns_button facebook">
        <a href="https://facebook.com/sharer/sharer.php?u={{ .RelPermalink | absURL }}&t={{ .Title }}" target="_blank" title="Facebook"><i class="fab fa-facebook"></i></a>
      </div>
  </div>
</section>
{{ end }}
  1. {{ partial "share" . }} をLayoutの中に埋め込みます。記事本文に埋め込みたいわけなので、mainroad テーマの場合は themes/mainroad/layouts/_default/single.html を編集しました。こちらをルートディレクトリの layouts/_default/single.html にコピーしてオーバーライドさせて編集します。
{{ define "main" }}
<main class="main" role="main">
</main>
{{ partial "share.html" . }}
{{ end }}
  1. CSSを設定(リンク先参照)

Amazonリンク用レイアウト作成

このブログを完成させようと思ったモチベーションは、 Work From Home のデスク環境の紹介をしたかったからでした。基本は Amazon で購入しましたので商品詳細リンクを貼り付けたいです。だが Hugo には Amazon のリッチリンク表示はない!では作りましょう。 Hugoには Shortcode を Markdown の中に記述することで、定義した HTML の内容を埋め込むことができます。例えば Twitter のツイート内容の表示であれば、{{< tweet TweetID >}} のように Shortcode を書くことで指定したツイートを以下のように埋め込むことができます。

そしてこの Shortcode ですが、Custom Shortcode を作成することも可能です。詳細は公式ドキュメントを参照。こちらを使ってAmazonのリッチリンク表示用の Shortcode を作成するのですが、先人の方がすでに実行済みなのでこちらをそのまま利用させていただきました。

ちなみにこの記事を書く際に、ショートコードをエスケープして表示する際にちょっとだけ苦戦しました。こちらに詳細書いていますが、{{</* myshortcode */>}}のように/* */でエスケープする方法が良さそうでした。

外部リンクtarget=blank対応

Hugo ではもともと Markdown のレンダリングエンジンとして Blackfriday を使っており、この時代はaタグにおける target="_blank" つまりリンクの別タブ開きは記事内に HTML タグを直書きするか config.tml に以下のように記載することで別タブ開きを実現することができました。

[blackfriday]
  hrefTargetBlank = true

しかし v0.60 でレンダリングエンジンが Goldmark に変更されたことにより、上記のオプションは効かなくなっています。代わりにv0.6.2では Goldmark と Markdown Render Hooks という仕組みがサポートされたことにより、レンダリング動作にフックして、該当部分の出力を書き換えることができるようになりました。詳細については公式Blogに書かれています。こちらに記載されている Sample を活用しました。

layouts/_default/_markup というディレクトリが Markdown Render Hooks のディレクトリのようなので、こちらに以下の内容のlayouts/_default/_markup/render-link.htmlを配置します。

<a href="{{ .Destination | safeURL }}"{{ with .Title}} title="{{ . }}"{{ end }}{{ if strings.HasPrefix .Destination "http" }} target="_blank"{{ end }}>{{ .Text }}</a>

これで、いつも通り[リンクテキスト](リンクURL)で作成したリンクのうち、外部リンク(httpからはじまるもの)については、target="_blank" が書き加えられて出力され、別タブでリンクが開かれるようになります。内部リンクの場合は通常通り同じタブ内で遷移しますので、ユーザ体験的にもタブが増えすぎるということもありません。

例: 外部リンク 内部リンク

GTM導入

アクセス解析ができるように Google Aanlytics を使います。Hugoでは、config.tomlgoogleAnalytics = "トラッキングID" のように書き込むだけで各ページにトラッキングコードを埋め込むことができます。ただ将来的に複数のタグやスクリプトを設定することになった際も一元管理ができるように、できればGoogle Tag Managerで管理をしておきたい。また調べたところ、Hugo のGoogle Analyticsテンプレートのトラッキングコードは gtag.js ではなく、古いタイプの analytics.js を利用しているみたいです。

Google Tag Manger を Hugo で利用する手順ですが、こちらのBlogに書かれている手順がそのまま利用できますので活用します。

  1. まずは自身のgoogleアカウントでGoogle Analyticsのサイト登録を行います。そうするとトラッキングIDが発番されますのでこれをメモします。
  2. 続いてGoogle Tag Managerのアカウント登録をします。登録が完了すると、 タグと タグに貼り付けるコードが費用時されますのでそれぞれ、layouts/partials/gtm/gtm-head.htmllayouts/partials/gtm/gtm-body.html に保存します。
  3. themes/mainroad/layouts/_default/baseof.html をルートディレクトリの layouts/_default/baseof.html にコピーした上で編集し、以下のように head の最後と body の頭にそれぞれタグを挿入します。
<!DOCTYPE html>
<html class="no-js" lang="ja">
<head>
  <meta charset="UTF-8">
  {{ partial "gtm/gtm-head" . }}
</head>
<body class="body">
  {{ partial "gtm/gtm-body" . }}
  1. Hugo 側はこれで完了で、この状態で Build すると各ページに GTM のコードが入っています。
  2. 今度は GTM 側で GA のページビューイベントを設定します。手順はタグマネージャーのドキュメントに記載されています。
  3. 完了すると、ページビューイベントがGA側に記録されていることが確認できます。
  4. 他にカスタムメトリクスや、クリックイベントなどを集計する際も GTM 経由で設定可能です。

プライバシーポリシー作成

サイトでクッキーを使って GTM 経由で Google Analytics を利用していますので、利用規約に従ってプライバシーポリシーにその利用の旨を記載する必要があります。

このサイトではその他のサイトポリシーや免責事項も含めて/privacy/のパスで公開し、Footer にリンクとして加えました。内容はこちらです。

OGP関係

Hugo ではconfig.toml で以下の設定を施すことでデフォルトで OGP を設定してくれます。

[Params]
  opengraph = true
  images = ["/img/og-image.png"]

images を指定することで、各コンテンツで個別に images が設定されていないページがSNSにシェアされた際もデフォルトで og:image を設定してくれます。

RSS関係

Hugo はデフォルトで RSS 2.0 の仕様に沿った xml ファイルを作成します。全体のRSSであるhttps://example.com/index.xml に加えてセクションごとの RSS も作成されます。このサイトでは blog セクションの RSS /blog/index.xml をダウンロードしやすいようにメインメニューに表示させています。またスマホでは非表示とさせたいので、CSSでスマホサイズの時のみ display:none 対応をしています。メニューが増えても基本は RSS はメニューの最後になるだろうと、last-child を使った書き方をしました。これが正しいのかまではわかりません。詳しい人がいれば教えてください。

@media screen and (max-width: 900px) {
	.menu__item:last-child {
		display: none;
	}
}

SEO関係

その他以下のようなSEO対策用の設定とかをしました。

Sitemap.xml

Hugo がデフォルトで Sitemap.xml を作ってくれるので、それを使っています。

robots.txt

config.toml に以下のように記載すると、robots.txt を作成してくれます。そちらを使っています。

enableRobotsTXT = true

Google Search Console

サイトの Google での SEO 管理のために Google Search Console にサイトを登録の上、sitemap.xml を指定するところまでしています。

おわりに

このブログを公開するにあたって、色々調べながら進めた内容をせっかくなのでまとめるところをブログに書くことからスタートしました。さてさて、宣言通り bi-weekly や Monthly でブログを執筆することができるのか?アウトプットすることを追い込むために作ったこのブログを有効活用して成長していけるようにがんばりますー\(^o^)/