GitHub Pagesで運営していた写真・IT系の当ブログを、Netlifyと独自ドメインに移行しましたので、その時に行った内容やハマった点を備忘録としてまとめたいと思います。
目次
はじめに
今までは、静的サイトジェネレータのHexoで書き出したページをGitHub Pagesにデプロイしていました。静的ジェネレータは色んな物がありますが、代表例を挙げると以下のようなプログラムがあります。2017年現在ではHugoが流行っているようです。
ホスティングサービスの話題に戻りますが、GitHubからNetlifyへの移行後は、Hexoで書き出したサイトをZipファイルで圧縮して送信し、Netlifyへデプロイしています。実際の処理はhexo-deployer-netlifyというプラグインで自動化されています。
GitHub Pagesは、サーバー維持費が無料でありながら、HTTPSやCDNをサポートしており、ブログを運用するには快適な環境でした。ところが、GitHub Pagesは10万リクエスト/月
という帯域幅制限などの条件があるので、そろそろその制約に引っかかりそうでした。
ブログの運営も順調に推移しているので、更にページビューが増える前にNetlifyに移行しようと考えました。
不明な点はコミュニティやチャットで質問できる
Netlifyに関して不明な点や、分からない所はコミュニティのGITTER - netlify/communityやNetlifyのチャットで聞くことが出来ます。
GITTERでは、Netlify利用者と情報交換ができる ©
Netlifyのページに常設されているチャットからも、直接問い合わせができる ©
Netlifyのチャットは、1日以内に返事が返ってくるので対応の速さに驚きました。質問は全て英語でやりとりする事になりますが、Google先生の力を借りて分からない内容をなんとか質問しています。
Netlifyのフリープランはどうなの?
Netlifyは、GitHub Pagesと似たような使い方ができ、尚且つフリープランの帯域制限もGitHubより遥かに緩めです。更にはHTTP/2やCI(Netlify CI)による静的サイトの生成自動化も行えるのが特徴です。
Netlify
Terms of Service Agreement
Netlifyフリープランの制約等が記載されている。執筆時現在のところ、ネットワーク転送量:100GB/月. 容量:100GB. デプロイ時のAPIリクエスト:200リクエスト/分. 3デプロイ/分 などの制限が設けられている。
冒頭でも触れた通り、Netlifyには、書き出したサイトをZipファイルで圧縮して送信しています。ここで「なぜCIを使わないの?」と不思議に思った方もいらっしゃるかと思います。
Netlifyというと、GitHubやBitbucketやGitLabのリポジトリをCIで自動ビルド&デプロイできるのが目玉の機能です。しかし、Netlifyでは幾つか制約があるため、自身のブログでCIを使う事ができず、結果的に今回は断念することになりました。
下記では、CIを断念した経緯も踏まえて、移行時にハマった内容も振り返ります。
移行時に行った事
Netlifyと独自ドメインに移行する際に行った内容はこちらです。
Netlifyにデプロイ
まずはNetlifyにブログのページデータをデプロイしました。Netlifyでは、以下の方法でページデータをデプロイできます。
- GitリポジトリをNetlifyCIがビルド&デプロイ
- NetlifyにページデータやZipファイルを送る
移行時には上記の項目を順番に試していきましたが、結果的には2番目を採用しました。
GitリポジトリをNetlifyCIがビルド&デプロイ
サイトデータを配置したGitのリポジトリを、Netlifyが自動的にビルドやデプロイを行ってくれます。ビルド&デプロイのタイミングは、リポジトリがPushされた時点を検知してくれます。
また、リポジトリは以下のサービスをサポートしています。
ブログサイトのソースを公開したくないというニーズはよくある話かと思います。そんな時は、上記のようにBitbucketやGitLabに非公開のリポジトリを配置するのがおすすめです。
しかし、Netlify CIのビルドプロセスは15分を超えると強制停止する制約がありますので、注意が必要です。サイトの生成に時間を要する方はCIのビルドに失敗します。
Netlify
How Our Build Bots Build Sites
(引用)You’ll probably see a build timeout in these cases - we’ll run your commands but then after 15 minutes, we stop the build process.
実際に自分のNetlify CIでも、この制約に引っかかってしまい、ビルドが約15分で止まってしまいました。Netlify CIのログでは、下記のようにExecution timed out
とエラーが表示されます。
netlify-deploy-log1 2 3 4 5 6 7
| 00:00:00 AM: Execution timed out 00:00:00 AM: Cleaning up docker container 00:00:00 AM: Build complete: exit code: 137 00:00:00 AM: Error running command: Command did not finish within the time limit 00:00:00 AM: An error occurred while building the site, skipping the deploy and cache refresh. 00:00:00 AM: Command did not finish within the time limit 00:00:00 AM: Finished processing build request in 15m12.213130383s
|
以下に該当するようなケースでは、ビルドの時間が15分を越えてしまう可能性が高いので、この後で説明する方法で対応するしかありません。(もし他に何か良い回避方法がありましたら是非アドバイスをお待ちしております)
- CIにインストールするパッケージが多い
- 記事数が多い
- 静的ページ生成処理に時間が掛かる
NetlifyにページデータやZipファイルを送る
Netlifyでは前述した通り、Gitリポジトリのビルド&デプロイを行う事ができます。
また、前述の方法以外にも、Netlify APIを使ってサイトデータを送信する方法が提供されています。自身のサイトでは、CIが使えないため、仕方なくAPIを使ってサイトデータをデプロイしています。
例えば一例を上げると、Node.jsでjavascript(ES6)を使って、netlifyにデータを送る方法については以下のコードになります。
netlify-dir-send.js1 2 3 4 5 6 7 8 9
| let netlify = require("netlify") netlify.deploy({ access_token : "xxx" , site_id : "xxx" , dir : "/public" }).then( (deploy) => { if(deploy.error_message)console.error(`デプロイ中にエラーが発生しました: '${deploy.error_message}`) else console.log("デプロイに成功しました") })
|
上記ではpublic
ディレクトリ以下の全ファイルをNetlifyに送ります。access_token
とsite_id
はNetlifyのアカウントページから取得及び確認ができます。
Netlify APIの制約
ただし、Netlify APIは200リクエスト/分
という制限が設けられているため、転送するファイル数が多いとAPIエラーになります。
Netlify
Netlify API
(引用)Rate Limiting … The Netlify API is rate limited. You can make up to 200 requests per minute.
ファイル数が多くてエラーが発生する場合は、下記コードのように、サイトのデータをZip圧縮し、一つのファイルにまとめて送信するのがオススメです。
netlify-dir-send.js1 2 3 4 5 6 7 8 9
| let netlify = require("netlify") netlify.deploy({ access_token : "xxx" , site_id : "xxx" , zip : "public.zip" }).then( (deploy) => { if(deploy.error_message)console.error(`デプロイ中にエラーが発生しました: '${deploy.error_message}`) else console.log("デプロイに成功しました") })
|
静的サイトジェネレータのHexoでは、サイトデータのZipファイル圧縮後、Netlify APIで送信できるプラグインhexo-deployer-netlifyがありますので、宜しければそちらも活用ください^^ Zip圧縮の処理は私が改良しました(笑)
お名前.comで独自ドメイン取得
Netlifyにサイトを配置した後、続いて独自ドメインを取得しました。取得先はお名前.comのwww.xxx.com
ドメインにしました。
独自ドメイン取得後はお名前.comの管理ページからドメイン設定 > DNS関連機能の設定 > DNSレコード設定
で以下のように設定しました。
ホスト名 | TYPE | TTL | VALUE |
photo-tea.com | A | 3600 | 104.198.14.52 |
www.photo-tea.com | CNAME | 3600 | photo-tea.netlify.com |
WWWドメイン無しにした
サイトのアドレスは短い方がいいと思ったので、サブドメインのwww
は付けないhttps://photo-tea.com
を使おうと思いました。
こういったケースでは、上記のDNS設定に加えて、Netlifyのカスタムドメインをwww.photo-tea.netlify.com
ではなく、photo-tea.netlify.com
と予め設定しておくのがポイントになります。これでwwwサブドメインにアクセスしても、www無しアドレスにリダイレクトされます。
また、Netlifyの設定でLet’s EncryptによるHTTPS化とForce TLS connections
を有効にしておきます。
Amazonアソシエイトに新しいサイトURL追加の旨を連絡
Amazonアソシエイト・プログラムのお問い合わせフォームで、新しいドメインを追加して貰うように依頼しました。申請後、1時間後にはAmazonから返信が届き、追加が完了しました。
Google Adsenseに新しいサイトURLを追加
アドセンスで新しいドメインを追加して貰います。Google Adsenesのトップ画面から設定 > 自分のサイト > サイトの管理
で新しいドメインを追加します。この手続きで、すぐにAdsenseの広告が新しいドメインでも有効になります。
旧サイトで新しいサイトへリダイレクト・URL正規化する
古いサイトのHTMLにリダイレクトのコードを貼ります。サイトの移転で特に気になったのはページランクの低下でした。そこで参考にしたのが以下の記事です。
海外SEO情報ブログ
301リダイレクトで何%のPageRankが失われるのか?
もっと知りたいリンゴあれこれ
サイト(ブログ)のお引っ越し(移転)は301リダイレクトを。出来ない場合は、メタリフレッシュ(meta refresh)とrel=”canonical”を!
モバイル通信とIT技術をコツコツ勉強する
「ドメイン変更」やURL移転後の「リダイレクト・転送」は,PageRankとSEOに影響する。Google検索順位に若干マイナスなので,Webサイト移転時に要注意
リダイレクトは、.htaccess
などを使って301リダイレクトを行うのが最善の方法であり、Googleでもそのような方法が推奨されています。しかしGitHub Pagesでは.htaccess
が使えません。
そこで、旧サイトに<meta http-equiv="refresh" content="秒数;URL=URL">
というタグを<head>〜</head>
内に記述してリダイレクトする事にしました。
また、新しいサイトと旧サイトでコンテンツの重複が起きてしまうので、URLの正規化も行います。旧サイトの<head>〜</head>
内で<link rel="canonical" href="新しいサイトURL">
を記述しておきます。
sample.html1 2 3 4 5 6
| <head> ... <meta http-equiv="refresh" content="秒数;URL=URL"> <link rel="canonical" href="新しいサイトURL"> ... </head>
|
上記の手順が完了したら、旧サイトをデプロイします。これで古いURLにアクセスされた場合でも新しいURLへリダイレクトされるようになります。
この方法でURLを移転してみて、アクセスを調べてみましたが、2週間ほどで新しいURLへアクセスが切り替わるようになりました。旧サイトのリダイレクトにより、ページビューは以下のように推移しました。
移行後のページビューの変動。赤い箇所はリダイレクトを開始した時期 ©
リダイレクトを行った直後はPV(ページビュー数)が倍になり、徐々に新しいURLへインデックスが進んで行ったようです。一時的にページビューが落ち込みますが、1ヶ月ほどで従来に近いレベルまで戻りました。
Google AnalyticsでURL変更手続き
続いて、Googleアナリティクスでアクセス解析するURLを、新しいURLに変更します。変更手続きは、アナリティクス設定 > プロパティ > プロパティ設定
とアナリティクス設定 > ビュー > ビュー設定
で行います。トラッキングコードの変更は不要です。
Search Consoleでアドレス変更とURLの正規化
Search Consoleの手続きを行います。まずはアドレス変更を行います。
Search Console
アドレス変更ツールの使用
しかし、301リダイレクトができないGitHub Pagesでは上記の手続きができません。今回は見送りました。続いてURLの正規化を行います。
Pascal コンテンツ・SEOツール
wwwありなしをGoogleサーチコンソールで統一する方法
URLの正規化は上記の記事が参考になります。
トレンドマイクロにWebサイトの安全性を評価してもらう
こちらは不要かもしれませんが、セキュリティソフトのウイルスバスターをインストールしていると、検索結果にサイトの安全性がアイコン表示されます。新しいURLが評価されるには遅延が掛かるので、以下のフォームから評価を依頼しておきました。
ウイルスバスター ヘルプとサポート
Trend Micro Site Safety Center について
ソーシャルボタンの各種URL変更手続き
最後にシェアボタンで幾つかのURL変更手続きを行います。
ツイッターで記事がシェアされた時に表示されるカード表示を有効にしてもらいます。
Twitter Developers
Card Validator
URLを入力すると、シェアされた時のカード表示がプレビューされます。またログ表示でINFO: Card loaded successfully
と表示されればOGPの記述も問題無いことが確認されます。この手順で、入力したURLにおけるカード表示が有効になります。
TwitterのOGPの記述方法は下記が参考になります。
Twitter Developers
Card Types
facebookのApp IDの取得
facebookで記事がシェアされる際には、facebook App IDが必要になります。以下から新しいサイトのURLを登録し、IDを取得しておきましょう。
Facebook for Developers
facebook for developers - Login
最後に、NetlifyでサポートされているHTTP/2サーバプッシュの設定をしておきます。サーバープッシュを使うと、CSSファイルやJSファイルを従来よりも高速で配信できるようになります。
サーバプッシュについては、以下の記事が分かりやすかったです。一言で言うと、配信する事が予め分かっているファイルは、サーバプッシュしておくとサイトデータの転送時間(RTT
=ラウンドトリップタイム)や表示時間が短縮できるようです。
GREE Engineers’ Blog
初めてのHTTP/2サーバプッシュ
Developers Summit 2016 - Publickey
リクエストを待たずに送信を開始する「サーバプッシュ」~奥一穂氏による「HTTPとサーバ技術の最新動向」(中編)。Developers Summit 2016
Netlifyでサーバプッシュする方法は、ドキュメントをご覧ください。
Netlify
Headers & Basic Authentication | Netlify
サーバプッシュする方法を詳しく見ていくと、Netlifyでは、デプロイするディレクトリの直下に、_headers
というファイルを作成し、下記のように記述します。
_headers1 2 3
| /* Link: </css/style.css>; rel=preload; as=stylesheet Link: </js/script.js>; rel=preload; as=script
|
上記の記述方法は一例になりますが、/*
で示すように、デプロイするサイトのルートディレクトリ以下、全てのパスで、style.css
とscript.js
をサーバプッシュする設定です。
また、別のケースを考えてみましょう。デプロイするサイトのパスによって、プッシュしたいファイルを使い分けたい場合は以下のように記述します。
_headers1 2 3 4 5 6
| /categories/* Link: </css/style-categories.css>; rel=preload; as=stylesheet Link: </js/script-categories.js>; rel=preload; as=script /tags/* Link: </css/style-tags.css>; rel=preload; as=stylesheet Link: </js/script-tags.js>; rel=preload; as=script
|
Hexoで_(アンダースコア)から始まるファイルをデプロイ
静的ジェネレータのHexoでは通常、_
で始まるファイルをデプロイできません。そこで、以下のようなプラグインを定義しておきます。
themes/your-theme/script.js1 2 3 4 5 6 7 8 9 10
| hexo.extend.generator.register('netlify-headers', function(locals){ var fs = require('hexo-fs'); var pathFn = require('path'); var data = fs.readFileSync( pathFn.join( process.env.PWD || process.cwd() , '_headers')); return { path: "_headers", data: data }; });
|
リダイレクトの設定(404)
Netlifyで404リダイレクトやその他のリダイレクトを行いたい時は_redirects
というファイルをルートディレクトリに配置します。
Netlify
Redirect & Rewrite rules | Netlify
例えばルートのパス以下の全てのURLで、ページが見つからない場合に/404/
というURLのページを開くには上記のように_redirects
を記述します。
_redirects1 2
| # 404 Redirects /* /404/ 404
|
404リダイレクトの他にも、HTTPステータスコードの301・302・200リダイレクトなどを定義する事ができます。
_redirects1 2 3 4 5 6 7 8 9 10 11 12 13
| # 404 Redirects /* /404/ 404
# その他 HTTPステータスコードの301・302・200リダイレクトなども定義できる
Redirect with a 301 /home / 301
Redirect with a 302 /my-redirect / 302
Rewrite a path /pass-through /index.html 200
|
あとは、前述の_headers
と同じようにプラグインを新たに定義しておきます。
themes/your-theme/script.js1 2 3 4 5 6 7 8 9 10
| hexo.extend.generator.register('netlify-redirects', function(locals){ var fs = require('hexo-fs'); var pathFn = require('path'); var data = fs.readFileSync( pathFn.join( process.env.PWD || process.cwd() , '_redirects')); return { path: "_redirects", data: data }; });
|
HTTP/2におけるサイトパフォーマンス向上
また、HTTP/2における配信方法により、HTTP/1.1で行ってきたサイトパフォーマンス向上テクニックが反ってボトルネックになってしまうようです。CSSやJSファイルの結合、画像アセットをスプライト化していた時代は、もはや都市伝説のようです…(汗)
blog.jxck.io
HTTP2 を前提とした HTML+CSS コンポーネントのレンダリングパス最適化について
上記を読みながら、少しづつ改良してみたいと思います。